新近剛上的FTP備份伺服器,例行檢查/var/log/secure日誌時,發現不少sshd和vsftpd失敗認證資訊,很明顯有人想用暴力破解工具竊取密碼,所以需要編寫一個安全指令碼防止。
指令碼需求如下:此SHELL指令碼放在crontab計劃任務裡,每隔6小時(此時間根據實際情況來定義)就去讀取/var/log/secure指令碼,取出裡面惡意猜測IP,如果單位時間內(一星期)的連線數是高於一個閥值,例如100(此閥值也可以根據實際情況來定義),則將其加進/etc/hosts.deny黑名單裡,如果低於此閥值,則無視此IP。
/var/log/secure裡認證失敗資訊如下: Nov 28 10:18:08 centos2 sshd[7556]: Connection closed by 222.216.30.109 Nov 28 10:18:08 centos2 sshd[7557]: pam_unix(sshd:auth): authentication failure; logname= uid=0 euid=0 tty=ssh ruser= rhost=222.216.30.109 user=root Nov 28 10:18:09 centos2 sshd[7559]: pam_unix(sshd:auth): authentication failure; logname= uid=0 euid=0 tty=ssh ruser= rhost=222.216.30.109 user=root Nov 28 10:18:10 centos2 sshd[7551]: Failed password for root from 222.216.30.109 port 2391 ssh2 Nov 28 10:18:10 centos2 sshd[7552]: Connection closed by 222.216.30.109 Nov 28 10:18:10 centos2 sshd[7553]: Failed password for root from 222.216.30.109 port 2397 ssh2 Nov 28 10:18:10 centos2 sshd[7554]: Connection closed by 222.216.30.109 Nov 28 10:18:11 centos2 sshd[7557]: Failed password for root from 222.216.30.109 port 2401 ssh2 Nov 28 10:18:11 centos2 sshd[7558]: Connection closed by 222.216.30.109 Nov 28 10:18:11 centos2 sshd[7559]: Failed password for root from 222.216.30.109 port 2403 ssh2 Nov 28 10:18:11 centos2 sshd[7560]: Connection closed by 222.216.30.109 Nov 28 10:37:01 centos2 vsftpd: pam_unix(vsftpd:auth): check pass; user unknown Nov 28 10:37:01 centos2 vsftpd: pam_unix(vsftpd:auth): authentication failure; logname= uid=0 euid=0 tty=ftp ruser=hello rhost=centos1.cn7788.com Nov 28 10:37:01 centos2 vsftpd: pam_succeed_if(vsftpd:auth): error retrieving information about user hello Nov 28 10:37:19 centos2 vsftpd: pam_unix(vsftpd:auth): check pass; user unknown Nov 28 10:37:19 centos2 vsftpd: pam_unix(vsftpd:auth): authentication failure; logname= uid=0 euid=0 tty=ftp ruser=yhc rhost=centos1.cn7788.com Nov 28 10:37:19 centos2 vsftpd: pam_succeed_if(vsftpd:auth): error retrieving information about user yhc Nov 28 10:37:36 centos2 vsftpd: pam_unix(vsftpd:auth): check pass; user unknown Nov 28 10:37:36 centos2 vsftpd: pam_unix(vsftpd:auth): authentication failure; logname= uid=0 euid=0 tty=ftp ruser=yuhongchun rhost=centos1.cn7788.com Nov 28 10:37:36 centos2 vsftpd: pam_succeed_if(vsftpd:auth): error retrieving information about user yuhongchun Nov 28 10:42:44 centos2 vsftpd: pam_unix(vsftpd:auth): check pass; user unknown Nov 28 10:42:44 centos2 vsftpd: pam_unix(vsftpd:auth): authentication failure; logname= uid=0 euid=0 tty=ftp ruser=yuhongchun rhost=114.112.169.70 Nov 28 10:42:44 centos2 vsftpd: pam_succeed_if(vsftpd:auth): error retrieving information about user yuhongchun Nov 28 10:42:56 centos2 vsftpd: pam_unix(vsftpd:auth): check pass; user unknown Nov 28 10:42:56 centos2 vsftpd: pam_unix(vsftpd:auth): authentication failure; logname= uid=0 euid=0 tty=ftp ruser=andrewyu rhost=114.112.169.70 Nov 28 10:42:56 centos2 vsftpd: pam_succeed_if(vsftpd:auth): error retrieving information about user andrewyu
我們觀察下/var/log/secure檔案輪詢特徵,如下所示:
ls -lsart secure.* 512 -rw------- 1 root root 516379 11-04 01:31 secure.4 660 -rw------- 1 root root 668192 11-11 00:05 secure.3 304 -rw------- 1 root root 306589 11-17 10:33 secure.2 484 -rw------- 1 root root 488620 11-25 02:33 secure.1
基本上,/var/log/secure檔案是以星期為輪詢週期的,如果對安全要求嚴格的朋友還可以本著“一個不放過”的原則來抓取上面的舊secure的惡意IP,然後扔進/etc/hosts.deny檔案裡。下面我們就們就要想辦法高效的來抓取這些惡意IP,如果參考原始版本的SHELL指令碼寫法,,我們這裡要抓取secure日誌中的偵測vsftpd及sshd
服務的IP地址,我們可以用如下命令,命令如下所示:
cat /var/log/secure | awk `/Failed/{print $(NF-3)}`| sort| uniq -c| awk `{print $2"="$1;}`
很明顯,這樣是取不到vsftpd失敗的IP值的,sshd日誌失敗資訊跟vsftpd日誌失敗信息不一樣,我寫了幾種awk混合sed的方法,測試了效率,感覺用awk指令碼速度是最快的,大家也可以寫幾種,用time命令測試下;最後精簡了下程式碼,完成了整個指令碼,腳
本內容如下所示:
#!/bin/bash awk `{for(i=1;i<=NF;i++){if($i ~ /rhost/)print substr($i,7)}}` /var/log/secure | sort | uniq -c>/root/black.txt DEFINE="100" cat /root/black.txt | while read LINE do NUM=`echo $LINE |awk `{print $1}`` host=`echo $LINE |awk `{print $2}`` if [ $NUM -gt $DEFINE ]; then grep $host /etc/hosts.deny > /dev/null if [ $? -gt 0 ]; then echo "sshd:$host" >> /etc/hosts.deny echo "vsftpd:$host" >> /etc/hosts.deny fi fi done
指令碼執行一段時間後,我們可以觀察此指令碼涉及到的一些檔案,如/root/black.txt,結果如下所示:
cat /root/black.txt 2 113.17.144.156 4 114.112.51.208 4 114.112.69.170 169 118-163-227-50.hinet-ip.hinet.net 8 119.188.7.200 8 122.70.130.11 61 124.248.32.246 12 183.203.14.121 3 189.26.255.11 56 199.204.237.60 3 199.30.53.220 5 201.236.80.4 6 220.172.191.31 30 222.216.30.109 60 222.253.159.111 58 223.4.180.23 166 58.221.42.178 1 61.132.4.85 152 61.142.106.34 22 61.167.33.222 7 85.126.166.83 166 www.b-nets.com
/etc/hosts.deny指令碼內容如下:
sshd:124.248.32.246 vsftpd:124.248.32.246 sshd:199.204.237.60 vsftpd:199.204.237.60 sshd:222.253.159.111 vsftpd:222.253.159.111 sshd:223.4.180.23 vsftpd:223.4.180.23 sshd:58.221.42.178 vsftpd:58.221.42.178 sshd:61.142.106.34 vsftpd:61.142.106.34 sshd:118-163-227-50.hinet-ip.hinet.net vsftpd:118-163-227-50.hinet-ip.hinet.net sshd:www.b-nets.com vsftpd:www.b-nets.com
最後,我們將此shell指令碼放進crontab 裡,每間隔六小時就執行一次,命令如下:
* */6 * * * root /bin/bash /root/hostsdeny.sh >> /dev/null 2>&1
由於/var/log/secure日誌是以星期為輪詢的,此指令碼執行頻率可自行設定,如果感覺伺服器被頻繁偵測,執行頻率間隔可設定短些,反之,可設定長些。附註:如果僅僅只是要防止SSH暴力破解,這個指令碼就沒必要更新了,可以採納我原先的SHELL指令碼(即原始版本),此更新指令碼適合部署在有FTP的公網機器上面,目前測試比較穩定,但感覺還是有不完美的地方,歡迎大家來信交流,撫琴煮酒(yuhognchun027@163.com)。