登录日志审计脚本筛查异常爆破账号及时拦截
服务器登录日志里藏着暴力破解的第一手证据。
当异常 IP 不断尝试 SSH 密码登录,系统会在日志中留下大量 Failed password 记录,而这些记录正是定位攻击来源、筛查异常爆破账号的关键。
本文用一个可复用的 shell 脚本带你把日志里的异常登录行为筛出来,并直接通过防火墙完成紧急拦截,全程无需额外安装软件,适合刚接手服务器运维的新手直接照做。
先把登录日志位置确认清楚
不同 Linux 发行版存放登录日志的路径略有差异,动手前先确认系统类型,避免脚本读不到数据。
- CentOS / RHEL / Rocky Linux:默认读取
/var/log/secure - Ubuntu / Debian:默认读取
/var/log/auth.log
可用下面命令确认日志文件存在,并观察前几行登录审计记录:
ls -lh /var/log/secure 2>/dev/null || ls -lh /var/log/auth.log
确认日志存在后,再查看是否有 SSH 爆破记录:
grep "Failed password" /var/log/secure | tail -20
如果输出里能看到大量来自不同 IP 的失败尝试,说明服务器正被暴力破解扫描,需要立刻进入下一步。
用一行 awk 命令快速筛查异常 IP
暴力破解通常表现为同一 IP 在短时间内反复尝试登录,且失败次数明显偏高。
用 awk 读取登录日志,可以快速统计每个 IP 的失败次数,并列出它尝试过的账号。
awk '/Failed password/ {print $(NF-3)}' /var/log/secure | sort | uniq -c | sort -rn | head -20
这段命令的含义:从日志中提取每次失败登录对应的来源 IP,排序后统计每个 IP 出现的次数,最后按次数从高到低显示前 20 个。
想同时看每个 IP 尝试了哪些账号,可以执行:
awk '/Failed password/ {print $(NF-3), "尝试账号:", $(NF-5)}' /var/log/secure | sort | uniq -c | sort -rn | head -20
输出结果类似:
156 203.0.113.10 尝试账号: root
89 198.51.100.23 尝试账号: admin
45 203.0.113.66 尝试账号: test
看到单个 IP 失败几十上百次,基本可以判定为异常爆破账号或扫描行为。
把审计脚本固化下来,方便随时复查
手动执行命令虽然方便,但服务器被持续爆破时,每次都要敲一遍很麻烦。
建议把统计逻辑写成脚本,下次直接运行文件即可。
创建脚本文件:
vim /usr/local/bin/check_ssh_attack.sh
粘贴以下内容(请根据系统日志路径调整变量):
#!/bin/bash
# 登录日志审计脚本:统计异常爆破 IP 和账号
# 适用系统:CentOS / Ubuntu(请按实际日志路径修改)
LOG_FILE="/var/log/secure"
if [ ! -f "$LOG_FILE" ]; then
LOG_FILE="/var/log/auth.log"
fi
echo "===== 登录日志审计($LOG_FILE)====="
echo ""
echo "[Top 20 失败登录 IP]"
awk '/Failed password/ {print $(NF-3)}' "$LOG_FILE" | sort | uniq -c | sort -rn | head -20
echo ""
echo "[各 IP 尝试的账号]"
awk '/Failed password/ {print $(NF-3), "->", $(NF-5)}' "$LOG_FILE" | sort | uniq -c | sort -rn | head -30
echo ""
echo "[最近 5 条登录日志]"
grep "Failed password" "$LOG_FILE" | tail -5
保存后添加执行权限:
chmod +x /usr/local/bin/check_ssh_attack.sh
之后只要运行 bash /usr/local/bin/check_ssh_attack.sh 就能快速生成审计报告。
对确认恶意的 IP 执行防火墙拦截
筛选出异常爆破 IP 后,需要立即阻断。
以下是两种常见防火墙的配置方式,按自己的系统选择即可。
firewalld 方式(CentOS / Rocky Linux)
firewall-cmd --permanent --add-rich-rule="rule family=ipv4 source address=203.0.113.10 port port=22 protocol=tcp reject"
firewall-cmd --reload
ufw 方式(Ubuntu / Debian)
ufw deny from 203.0.113.10 to any port 22
也可以直接屏蔽整个 IP 的所有端口(更严格):
ufw deny from 203.0.113.10
拦截后确认规则已生效:
# firewalld 查看富规则
firewall-cmd --list-rich-rules
# ufw 查看规则状态
ufw status numbered
如果是云服务器,建议同时到云控制台安全组中把该 IP 加入黑名单,双重保险,避免本机防火墙被绕过。
常见报错和避坑提醒
第一种情况:日志里看不到 Failed password 记录。
可能原因有两个:一是系统的 SSH 登录日志未写到该文件,可先检查 /etc/rsyslog.conf 或 /etc/rsyslog.d/ 下 authpriv 的日志配置;
二是攻击者通过其他服务(如 FTP、数据库)爆破,此时需要调整日志路径和匹配关键词。
第二种情况:误拦截了自己或同事的 IP。
把内网 IP、公司出口 IP 添加到白名单再执行拦截。
建议把正常办公网段加入防火墙白名单,避免把合法登录来源一并封堵。
第三种情况:脚本统计不到 IPv6 地址。
awk 提取字段位置在 IPv6 环境下可能偏移,
如果日志里出现 : 这类地址,
:ffff:
203.0.113.10
说明服务器开启了 IPv4 映射 IPv6,
可在 sshd 配置中只监听 IPv4,
或调整脚本提取逻辑。
关于定期执行的建议。 把审计脚本加入 crontab 每天跑一次,并将结果保存到文件,方便追溯攻击趋势。
同时建议检查系统账号,禁用无密码账号、修改弱密码,从入口堵住爆破空间。
验证最终效果时,可以从被拦截 IP 再次尝试 SSH 连接,如果连接超时或被拒绝,说明拦截已生效。
如果你也正在处理登录日志审计脚本筛查异常爆破账号及时拦截这件事,建议先按上面步骤执行一轮,再根据自己的日志格式微调脚本,遇到异常情况优先回看避坑部分,基本都能解决。