https://mp.weixin.qq.com/s/-TWOTIorgjgaXQMA3XvUvQ
在当前的数字化时代,服务器安全成为了一个不可忽视的重要环节。无论是企业网站还是个人博客,都面临着来自各方的潜在威胁。其中,恶意访问和频繁登录尝试更是让管理员头疼不已。本文将为大家介绍如何通过脚本自动屏蔽频繁访问和尝试SSH登录的IP,从而提升服务器的安全防护能力。
一、背景与需求分析
随着互联网的快速发展,服务器面临的攻击手段也在不断演变。恶意访问和频繁登录尝试是两种常见的攻击方式。恶意访问通常是指通过大量请求来消耗服务器资源,导致服务器无法正常提供服务;而频繁登录尝试则是试图通过暴力破解的方式获取服务器的控制权限。
为了应对这些威胁,管理员需要实时监控服务器的访问日志和登录状态,并采取相应的措施。手动监控和屏蔽IP显然是不现实的,因此我们需要借助脚本自动化这一过程。
二、Nginx访问日志分析与屏蔽脚本
- 脚本介绍
我们的第一个脚本是基于Nginx访问日志来屏蔽频繁访问的IP。Nginx是一款高性能的HTTP服务器和反向代理服务器,其访问日志记录了每个请求的详细信息,包括客户端IP、请求时间、请求URI等。
- 脚本代码
#!/bin/bash
DATE=$(date +%d/%b/%Y:%H:%M)
ABNORMAL_IP=$(tail -n5000 access.log |grep $DATE |awk '{a[$1]++}END{for(i in a)if(a[i]>100)print i}')
#先tail防止文件过大,读取慢,数字可调整每分钟最大的访问量。awk不能直接过滤日志,因为包含特殊字符。
for IP in $ABNORMAL_IP; do
if [ $(iptables -vnL |grep -c "$IP") -eq 0 ];
then
iptables -I INPUT -s $IP -j DROP
fi
done
- 脚本解析
DATE=$(date +%d/%b/%Y:%H:%M):获取当前时间的日期和时间,格式为“日/月/年:时:分”。
tail -n5000 access.log:读取Nginx访问日志的最后5000行,防止文件过大导致读取速度慢。
grep $DATE:过滤出当前时间段的日志记录。
awk '{a[$1]++}END{for(i in a)if(a[i]>100)print i}':使用awk统计每个IP的访问次数,并输出访问次数超过100次的IP。
for IP in $ABNORMAL_IP; do ... done:遍历所有异常IP,并检查是否已经被iptables屏蔽。
iptables -I INPUT -s $IP -j DROP:如果IP未被屏蔽,则将其加入iptables规则,直接丢弃该IP的所有请求。
- 使用建议
将脚本保存为nginx_block.sh,并设置定时任务(如每分钟执行一次)来实时监控和屏蔽频繁访问的IP。
根据服务器的实际情况调整tail -n5000中的数字,以确保既能及时发现问题又不会因读取过多日志而影响性能。
三、通过TCP连接数屏蔽频繁访问IP
- 脚本介绍
除了基于访问日志来屏蔽频繁访问的IP外,我们还可以通过监控TCP连接数来实现这一目标。这种方法不需要依赖特定的日志格式,因此更具通用性。
- 脚本代码
#!/bin/bash
ABNORMAL_IP=$(netstat -an |awk '$4~/:80$/ && $6~/ESTABLISHED/{gsub(/:[0-9]+/,"",$5);{a[$5]++}}END{for(i in a)if(a[i]>100)print i}')
#gsub是将第五列(客户端IP)的冒号和端口去掉
for IP in $ABNORMAL_IP; do
if [ $(iptables -vnL |grep -c "$IP") -eq 0 ]; then
iptables -I INPUT -s $IP -j DROP
fi
done
- 脚本解析
netstat -an:列出所有当前的TCP连接。
awk '$4~/:80$/ && $6~/ESTABLISHED/{gsub(/:[0-9]+/,"",$5);{a[$5]++}}END{for(i in a)if(a[i]>100)print i}':过滤出所有目标端口为80且状态为ESTABLISHED的连接,统计每个客户端IP的连接数,并输出连接数超过100次的IP。
gsub(/:[0-9]+/,"",$5):使用gsub函数去掉第五列(客户端IP)中的冒号和端口号。
其余部分与上一个脚本类似,遍历异常IP并加入iptables规则进行屏蔽。
- 使用建议
将脚本保存为tcp_block.sh,并设置定时任务来定期执行。
根据服务器的实际情况调整连接数的阈值(如100次),以确保既能有效屏蔽恶意访问又不会误伤正常用户。
四、屏蔽频繁SSH登录尝试的IP
- 通过lastb获取登录状态
脚本代码
#!/bin/bash
DATE=$(date +"%a %b %e %H:%M") #星期月天时分 %e单数字时显示7,而%d显示07
ABNORMAL_IP=$(lastb |grep "$DATE" |awk '{a[$3]++}END{for(i in a)if(a[i]>10)print i}')
for IP in $ABNORMAL_IP; do
if [ $(iptables -vnL |grep -c "$IP") -eq 0 ];
then
iptables -I INPUT -s $IP -j DROP
fi
done
脚本解析
lastb:显示失败的登录尝试记录。
DATE=$(date +"%a %b %e %H:%M"):获取当前时间的日期和时间,格式为“星期 月 天 时:分”。
grep "$DATE":过滤出当前时间段的失败登录尝试记录。
awk '{a[$3]++}END{for(i in a)if(a[i]>10)print i}':统计每个IP的失败登录尝试次数,并输出尝试次数超过10次的IP。
其余部分与之前的脚本类似,遍历异常IP并加入iptables规则进行屏蔽。
- 通过日志获取登录状态
脚本代码
#!/bin/bash
DATE=$(date +"%b %d %H")
ABNORMAL_IP="$(tail -n10000 /var/log/auth.log |grep "$DATE" |awk '/Failed/{a[$(NF-3)]++}END{for(i in a)if(a[i]>5)print i}')"
for IP in $ABNORMAL_IP; do
if [ $(iptables -vnL |grep -c "$IP") -eq 0 ]; then
iptables -A INPUT -s $IP -j DROP
echo "$(date +"%F %T") - iptables -A INPUT -s $IP -j DROP" >>~/ssh-login-limit.log
fi
done
脚本解析
/var/log/auth.log:SSH登录尝试的日志文件。
DATE=$(date +"%b %d %H"):获取当前时间的日期和时间,格式为“月 日 时”。
tail -n10000 /var/log/auth.log:读取auth.log文件的最后10000行。
grep "$DATE":过滤出当前时间段的日志记录。
awk '/Failed/{a[$(NF-3)]++}END{for(i in a)if(a[i]>5)print i}':统计每个IP的失败登录尝试次数(失败关键字为“Failed”),并输出尝试次数超过5次的IP。注意这里使用了$(NF-3)来获取IP地址,因为auth.log中的IP地址通常位于倒数第四列。
iptables -A INPUT -s $IP -j DROP:将异常IP加入iptables规则进行屏蔽,并记录到日志文件中以便后续查看。
使用建议
将两个脚本分别保存为ssh_block_lastb.sh和ssh_block_auth.log.sh,并根据实际情况选择使用哪个脚本。
设置定时任务来定期执行脚本,以确保及时屏蔽频繁登录尝试的IP。
根据服务器的实际情况调整失败登录尝试次数的阈值(如10次或5次),以确保既能有效屏蔽恶意尝试又不会误伤正常用户。
五、总结与展望
本文介绍了如何通过脚本自动屏蔽频繁访问和尝试SSH登录的IP,从而提升服务器的安全防护能力。我们分别基于Nginx访问日志、TCP连接数以及SSH登录日志实现了三种不同的屏蔽方法,并提供了详细的脚本代码和解析。
转载请注明:有爱前端 » 自动屏蔽频繁访问IP,提升服务器安全:实战脚本解析