统计ssh非法暴破源ip
在维护linux服务器中,当开启sshd服务时,总会有一些不怀好意的访问者要来试探一下弱口令,假若访问失败的日志文件为/var/log/secure,总是手动来翻日志,也是麻烦,服务器数量较多时,也显得力不从心,基于此,我们可以脚本化来自动分析日志,找出这些访问者,直接拉黑。
首先,统计基于ip的问题访问数量。如下:
grep -E "Failed|Invalid" /var/log/secure|sed -re 's/.*[ ](([0-9]{1,3}\.){3}[0-9]{1,3})[ ].*/\1/g'|sort|uniq -c|sort -n
1 38.75.136.182
1 81.68.154.131
3 81.68.188.196
8 150.158.180.66
14 81.68.166.172
26 101.132.119.42
67 118.178.189.178
将源ip加入防火墙屏蔽
接着,将上述恶意源ip统计数据定向至/var/log/failed_login.log
读取统计数据,筛选恶意访问次数>100(可根据需要自行设置)的ip,如果该ip并未加入黑名单,则将其加入防火墙黑名单
cat /var/log/failed_login.log|awk '$1 > 100{"firewall-cmd --list-all|grep "$2|getline ip;if (ip == "") system("firewall-cmd --add-rich-rule=\"rule family=\"ipv4\" source address=\""$2"\" drop \" --permanent")}END{system("firewall-cmd --reload")}'
或者创建ipset黑名单
firewall-cmd --permanent --new-ipset=black_ips
firewall-cmd --add-rich-rule="rule family="ipv4" source ipset=black_ips log drop" --permanent
tail /var/log/failed_login.log|awk '$1 > 100{"firewall-cmd --ipset=black_ips --get-entries|grep "$2|getline ip;if (ip == "") system("firewall-cmd --permanent --ipset=black_ips --add-entry="$2)}END{system("firewall-cmd --reload")}'
完整shell脚本
最终得到完整功能的shell脚本,如下:
#!/bin/bash
max=100
statistics_ip(){
grep -E "Failed|Invalid" /var/log/secure|sed -re 's/.*[ ](([0-9]{1,3}\.){3}[0-9]{1,3})[ ].*/\1/g'|sort|uniq -c|sort -n
}
add_ips_to_firewalld(){
if ! [[ `firewall-cmd --get-ipsets|grep black_ips` ]];then
firewall-cmd --permanent --new-ipset=black_ips
fi
if ! [[ `firewall-cmd --list-all|grep black_ips` ]];then
firewall-cmd --add-rich-rule="rule family="ipv4" source ipset=black_ips log drop" --permanent
fi
statistics_ip|awk -v max=$max '$1 > max{"firewall-cmd --ipset=black_ips --get-entries|grep "$2|getline ip;if (ip == "") system("firewall-cmd --permanent --ipset=black_ips --add-entry="$2)}END{system("firewall-cmd --reload")}'
}
add_ips_to_firewalld
自动屏蔽
最后,可将上述脚本加入计划任务,设置每隔一段时间(比如5分钟或者根据需要自行定夺)执行一次。
自动解除屏蔽ip
当某个(些)ip被加入防火墙黑名单后,如果之后的日志统计中没有再出现,如果需要从黑名单中移除,也可以使用shell脚本来完成。
比如:自动删除黑名单中屏蔽的,但是不在后续统计日志中出现次数>100的ip,脚本实现如下:
#!/bin/bash
read -d "" -a ips_tmp< <(firewall-cmd --list-all|grep -w rule|cut -d"\"" -f4)
read -d "" -a ips < <(awk '$1>100{print $2}' /var/log/failed_login.log)
ips=echo ${ips[@]}
for ((i=0;i<${#ips_tmp[@]};i++))
do
if ! echo $ips|grep -w $ips_tmp[$i];then
firewall-cmd --remove-rich-rule="rule family="ipv4" source address="${ips_tmp[$i]}" log drop" --permanent
#用ipset
# firewall-cmd --permanent --ipset=black_ips --remove-entry=${ips_tmp[$i]}
fi
done
可将其加入任务计划,周期可以设置稍微长一些,比如一周,一月甚至更长的周期。
注意:
如果用作统计的日志文件/var/log/failed_login.log增长比较快,必要的情况下,要做好日志分割。