新近刚上的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文件轮询特征,如下所示:
[root@centos2 log]# 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 |
基本上,secure文件是以星期为轮询周期的,如果对安全要求严格的朋友还可以本着“一个不放过”的原则来抓取上面的旧secure的恶意IP,下面我们就们就要想办法高效的来抓取这些恶意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 #Denyhosts For vsftpd and sshd #2012-12-28 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" for i in `cat /root/black.txt` do IP=`echo $i |awk '{print $1}'` NUM=`echo $i|awk '{print $2}'` if [ $NUM -gt $DEFINE ]; then grep $IP /etc/hosts.deny > /dev/null if [ $? -gt 0 ]; then echo "sshd:$IP" >> /etc/hosts.deny echo "vsftpd:$IP" >> /etc/hosts.deny fi fi done |