登录日志审计脚本筛查异常爆破账号及时拦截告警
场景与问题
服务器每天收到大量SSH登录尝试,其中不乏暴力破解(异常爆破)。
手动翻/var/log/secure显然不现实。
一个登录日志审计脚本能自动扫描日志、统计失败次数超过阈值的IP,然后执行拦截(如iptables封锁)并推送告警。
本文带你从零开始写出这个脚本,并解决常见坑点。
准备工作
你需要一台Linux服务器(CentOS 7/8或Ubuntu 20.04+),有root权限或sudo权限。
确保以下命令可用:
grep、awk、sort、uniq(系统自带)iptables(防火墙工具,安装命令:yum install -y iptables-services或apt install -y iptables)mail或sendmail(用于告警,可选,不装也不影响拦截功能)
另外确认登录日志路径:CentOS/RHEL为/var/log/secure,Ubuntu/Debian为/var/log/auth.log。
后续脚本中可配置变量。
编写审计脚本
创建一个文件,比如/root/ssh_audit.sh,输入以下内容:
#!/bin/bash
# SSH异常爆破审计与拦截脚本
LOG_FILE="/var/log/secure" # 根据系统修改
THRESHOLD=5 # 失败次数阈值
BLOCK_LIST="/tmp/blocked_ips.txt" # 已封IP记录,避免重复封禁
grep "Failed password" $LOG_FILE | awk '{print $(NF-3)}' | sort | uniq -c | sort -rn | while read count ip; do
if [ $count -ge $THRESHOLD ]; then
# 检查是否已封禁
if ! grep -q $ip $BLOCK_LIST 2>/dev/null; then
iptables -A INPUT -s $ip -j DROP
echo $ip >> $BLOCK_LIST
# 可选:发送邮件告警(需配置mail命令)
# echo "爆破IP: $ip (失败次数: $count)" | mail -s "SSH爆破告警" admin@example.com
echo "[$(date)] 已封锁IP: $ip (失败$count次)" >> /var/log/ssh_audit.log
fi
fi
done
说明:
-$(NF-3)提取失败登录日志中的IP字段(不同系统可能位置不同,建议先手动跑一次grep "Failed password" /var/log/secure确认)。
- 如果日志格式不一致,可改用awk '{for(i=1;i<=NF;i++) if($i ~ /^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+$/) print $i}'提取所有IP再过滤。
设置定时任务与告警推送
脚本写好之后,用crontab让它每分钟跑一次(根据日志量调整频率):
crontab -e
# 添加一行:
* * * * * /bin/bash /root/ssh_audit.sh
如果想同时接收邮件告警,请先在系统上配置mailx或sendmail,并取消脚本中mail -s行的注释。
如果不想发邮件,也可以将日志写入文件,然后用监控工具(如Zabbix)扫描该文件。
避坑指南
- IP字段提取错误:不同发行版或自定义日志格式会导致IP位置不同。建议在脚本开头加一行
grep "Failed password" $LOG_FILE | head -5手动观察。 - 白名单遗漏:封禁前要排除自己公司的出口IP,否则可能把自己关在外面。可以在脚本中加入白名单判断:
WHITE_LIST="192.168.1.0/24 10.0.0.1"
if [[ $WHITE_LIST =~ $ip ]]; then continue; fi
- 日志轮转:如果日志刚被切割,
grep可能读不到最新记录。可以加-r递归扫描或指定/var/log/secure*。但注意避免重复处理旧记录。更稳的做法是用journalctl(systemd系统)替代直接读文件。 - iptables规则持久化:重启后规则会丢失。请执行
iptables-save > /etc/iptables/rules.v4(Ubuntu)或service iptables save(CentOS)。 - 脚本权限与执行:记得
chmod +x /root/ssh_audit.sh,并且crontab中路径写绝对路径。
验证与测试
- 手动模拟爆破:用另一台机器(或本机换端口)尝试5次以上错误密码登录。例如:
ssh wronguser@your-server
# 重复输错密码6次
- 等待1分钟后,检查iptables规则:
iptables -L -n | grep DROP,应看到刚才使用的源IP。 - 查看日志:
cat /var/log/ssh_audit.log,应有封锁记录。 - 如果有邮件配置,检查邮箱是否收到告警。
常见问题解答
Q:脚本不生效,没有封锁任何IP?
A:先手动执行脚本bash -x /root/ssh_audit.sh,观察输出。大概率是日志路径不对或IP提取字段错误。另外检查crontab是否启用。
Q:误封了正常用户怎么办?
A:在脚本中加入白名单,并将常用IP从/tmp/blocked_ips.txt中删除,然后iptables -D INPUT -s 该IP -j DROP恢复。
Q:有没有更完善的替代方案?
A:专业工具fail2ban功能更全(支持多种服务、动态ban时间、自动白名单),但本文的轻量脚本适合不想安装依赖、只想快速实现核心拦截的场景。你可以在此基础上扩展,比如记录到数据库。
总结
通过一个不到20行的shell脚本,配合crontab和iptables,就能完成登录日志审计、异常爆破账号筛查、自动拦截与告警。
整个过程无需第三方软件,适合零基础用户快速落地。
遇到问题先对照避坑部分检查,再根据自己的日志格式微调。
如果觉得手动维护麻烦,可以进一步学习fail2ban。