之前其实弄过一个自动屏蔽恶意攻击者的IP的脚本{还写了篇文章:自动屏蔽一些恶意IP}(但其实我一直没有实际部署上去,因为看了看日志文件发现本来访问流量就不大,虽然其中也有一些是扫描器的行为,但是对现在的blog访问还没产生什么实际影响,所以就暂时搁置了),但是昨天在浏览别人的blog时发现了篇文章:简单实现自动过滤WEB攻击源IP,解决了之前我一直没有想到该如何处理的几个问题(1.如何避免屏蔽自己的IP,因为现在使用的是PPPoE的拨号式网络,没有一个固定的IP,而自己又会经常上自己的blog看看,有时是以管理员身份,有时就是以访客的身份,当时没有想到该如何避免屏蔽自己的IP所以就没添加这个白名单的功能–其实也和我租的第一台VPS无法执行last命令有关;2.定期清除记录;3.处理关于评论和后台登陆页面的访问),所以,就又关注起了这个事情。因为代码的功能已经基本上满足一般要求(你可以自己在脚本中添加函数实现特定功能,如:记录/屏蔽访问特定URL的IP)了,所以这次以学习为主(而且各人碰到的情况也不一样,需要适当做出修改以符合自己的情况,脚本中的情况就是:根据当前服务器的访问日志来看,如果在10000个请求中,有1000个请求来自于同一个IP的话,那么其攻击特征就非常明显了;另外,针对后台登陆页面和评论页面,单独制定了更加严格的规则,那就是在10000次POST请求中,如果有100次尝试,就Block掉):
将下面的shell脚本保存为/home/rainbow/sbin/block_attack_ips.sh
#!/bin/bash logfiles=( /webserver/blog/logs/rainbow_access.log /webserver/blog/logs/eric_access.log ) whitelist=$(last | grep -Ev '^$|mosh|reboot|wtmp' | awk '{print $3}' | sort | uniq | xargs) function check_root(){ if [ $EUID -ne 0 ]; then echo "This script must be run as root" exit 1 fi } function block_ips(){ blacklist=$@ if [ ! -z "${blacklist}" ]; then for ip in ${blacklist} do if ! $(echo ${whitelist} | grep -wq ${ip}); then if ! $(/sbin/iptables-save | grep -wq ${ip}); then echo "Blocked ${ip}" /sbin/iptables -I INPUT -s ${ip}/32 -p tcp -m tcp --dport 80 -j DROP fi fi done fi } function check_post(){ page=$1 # the URL's path info tailnum=$2 retry=$3 # specify the retry times command="grep -w POST ${logfile} |tail -n ${tailnum} |grep -w ${page} |awk '{print $1}' |sort |uniq -c |awk '($1 > ${retry}){print $2}'" blacklist=$(eval ${command}) block_ips ${blacklist} } function check_all(){ tailnum=$1 retry=$2 command="tail -n ${tailnum} ${logfile} |awk '{print $1}' |sort |uniq -c |awk '($1 > ${retry}){print $2}'" blacklist=$(eval ${command}) block_ips ${blacklist} } check_root for logfile in ${logfiles[@]} do check_post wp-login.php 10000 100 check_post wp-comments-post.php 10000 100 check_all 10000 1000 done
添加可执行权限:
# chmod +x /home/rainbow/sbin/block_attack_ips.sh
配置crontab计划任务,每5分钟执行一次,每天定时重启iptables服务以清除旧的记录:
# sudo crontab -e # */5 * * * * /home/rainbow/sbin/block_attack_ips.sh # 00 01 * * * /etc/init.d/iptables restart # 00 01 * * * /sbin/iptables -F #因为在Ubuntu12.04上面没有"/etc/init.d/iptables"或是"service iptables restart"这样的命令,所以,可以使用命令"/sbin/iptables -F"来达到清除记录的目的
参考文章:
《 “简单实现自动过滤/屏蔽WEB攻击源IP” 》 有 2 条评论
为什么内核社区要用 BPF 替换 iptables?作者分享了一些自己的思考
https://cilium.io/blog/2018/04/17/why-is-the-kernel-community-replacing-iptables/
linux内核将用BPF给iptables”换心”
https://mp.weixin.qq.com/s/u71vsKtz4yaT7uA20Al8wQ
BPFi: Powerful Linux Tracing for Remote targets using eBPF
https://www.socallinuxexpo.org/sites/default/files/presentations/bcc-scale.pdf
eBPF 的教程和例子详细介绍
http://www.brendangregg.com/blog/2019-01-01/learn-ebpf-tracing.html