
面对服务器上频繁出现的SSH暴力破解尝试,手动排查和封禁IP效率低下。本文将介绍一种基于Shell脚本的自动化解决方案,通过分析系统日志,自动识别并封禁恶意IP,有效加固你的Linux服务器安全。
一、 防护原理与日志分析
Linux系统的认证日志 /var/log/secure 记录了所有SSH登录尝试的详细信息。攻击者进行暴力破解时,会在短时间内产生大量失败的登录记录。我们的防护思路是:分析这些失败记录,提取频繁出现的源IP地址,并将其加入系统的黑名单。
查看一段典型的日志,可以清晰看到攻击模式:
May 4 18:36:33 localhost sshd[79355]: Failed password for root from 221.226.43.62 port 38954 ssh2
May 4 18:36:34 localhost sshd[79358]: Failed password for root from 106.37.72.121 port 58297 ssh2
May 4 18:36:35 localhost sshd[79350]: Failed password for invalid user said from 95.78.176.107 port 47976 ssh2
日志行 Failed password for root from 221.226.43.62 port 38954 ssh2 包含了关键信息:失败的用户名(root)、来源IP(221.226.43.62)和端口。攻击者会快速、轮换地使用不同用户名和IP进行尝试。
Linux系统可以通过 /etc/hosts.deny 文件来阻止特定主机的网络连接。我们的目标就是编写一个脚本,自动将恶意IP以 sshd:IP:deny 的格式添加到这个文件中。
二、 防护脚本详解
以下Shell脚本实现了自动分析和封禁功能。你可以根据需要调整 MAX_FAILED 变量,它定义了触发封禁的失败登录次数阈值。
#!/bin/bash
# 设置允许的最大失败次数,支持通过命令行参数传入
if [[ $1 =~ ^[1-9] ]] || [ -z $1 ]; then
MAX_FAILED=3 # 默认失败次数阈值为3
else
MAX_FAILED=$1
fi
# 分析 /var/log/secure,提取失败登录的IP并统计次数
cat /var/log/secure | awk '/Failed/{print $(NF-3)}' | sort | uniq -c | awk '{print $2"="$1;}' > /root/.blacklist
# 遍历统计结果,封禁超过阈值的IP
for i in `cat /root/.blacklist`
do
IP=`echo $i | awk -F= '{print $1}'`
NUM=`echo $i | awk -F= '{print $2}'`
if [ $NUM -gt $MAX_FAILED ]; then
# 检查该IP是否已在黑名单中,避免重复添加
grep $IP /etc/hosts.deny > /dev/null
if [ $? -gt 0 ]; then
echo "sshd:$IP:deny" >> /etc/hosts.deny
fi
fi
done
脚本逻辑解析:
awk ‘/Failed/{print $(NF-3)}’:筛选包含“Failed”关键词的行,并打印倒数第三个字段(即IP地址)。
sort | uniq -c:对IP进行排序和去重,并统计每个IP出现的次数。
awk ‘{print $2”=”$1;}’:将输出格式化为 IP=次数,便于后续读取。
- 循环处理临时黑名单文件,如果某个IP的失败次数超过
MAX_FAILED,且不在 /etc/hosts.deny 中,则将其加入。
![]https://static1.yunpan.plus/attachment/453e934155ad.png)
三、 部署与效果验证
脚本编写完成后,为其添加可执行权限,并通过 crontab 设定定时任务(例如每5分钟执行一次),即可实现持续自动防护。
chmod +x /path/to/your_script.sh
crontab -e
# 添加以下行
*/5 * * * * /bin/bash /path/to/your_script.sh
脚本运行一段时间后,再次检查 /var/log/secure 日志,你会发现原先大量的“Failed password”记录已被“refused connect”取代:
Jun 2 11:54:25 localhost sshd[57490]: refused connect from 139.59.188.207 (139.59.188.207)
Jun 2 11:54:28 localhost sshd[57493]: refused connect from 51.68.212.114 (51.68.212.114)
Jun 2 11:55:13 localhost sshd[57543]: refused connect from 222.175.223.74 (222.175.223.74)
这表明脚本已成功生效,所有被识别出的恶意IP在尝试连接时即被系统拒绝,极大地降低了服务器安全风险,从源头遏制了暴力破解攻击。这种方法简单有效,是运维人员必备的基础安全加固手段之一。
|