实用脚本能自动监控SSH登录日志吗?一文解锁安全运维效率
📖 目录导读
-
为什么你需要监控SSH登录日志?

- SSH暴力破解的现实威胁
- 传统日志审查的痛点
-
实用脚本监控SSH日志的原理
- 日志文件路径与格式
- 实时监控与历史分析
-
手把手教你写一个SSH监控脚本
- 脚本基础框架
- 关键功能实现:IP白名单、失败次数阈值、发送告警
-
自动响应:从监控到阻断
- 结合iptables或fail2ban的自动封禁
- 告警通知:邮件、企业微信、钉钉
-
常见问题答疑
- 脚本性能会拖慢服务器吗?
- 误报如何处理?
-
从“被动查”到“主动防”
为什么你需要监控SSH登录日志?
现实背景:根据2024年网络安全报告,超过70%的云服务器遭受过SSH暴力破解尝试,攻击者利用常见用户名(如root、admin)与弱口令组合,每分钟可能发起数千次登录请求,如果你的服务器仅靠默认日志记录,等到发现问题时可能已经失陷。
传统痛点:手动检查/var/log/auth.log或/var/log/secure,就像大海捞针,管理员需要逐个查看login失败记录、可疑IP、重复尝试,不仅耗时,还容易遗漏,更致命的是,绝大多数攻击在几小时内就完成了入侵与后门植入。
核心问题:有没有一个实用脚本,能自动监控SSH登录日志,并在攻击发生时立即告警? 答案是有,而且可以自己写。
实用脚本监控SSH日志的原理
日志文件路径与格式
- Ubuntu/Debian:
/var/log/auth.log - CentOS/RHEL/Fedora:
/var/log/secure - macOS:
/var/log/system.log
典型日志行示例(Ubuntu):
Apr 15 10:32:17 server sshd[2345]: Failed password for root from 192.168.1.100 port 22 ssh2
Apr 15 10:33:05 server sshd[2350]: Accepted publickey for admin from 10.0.0.5 port 54321 ssh2
关键字段:时间戳、进程(sshd)、事件类型(Failed/Accepted)、用户名、源IP、端口。
实时监控与历史分析
- 实时监控:使用
tail -f或Linux的inotify机制(通过脚本调用),持续跟踪日志文件新增行,立即抓取可疑事件。 - 历史分析:利用
grep、awk、sort等工具统计过去某段时间内的失败次数,识别高频攻击IP。
好脚本的核心逻辑是:将实时流处理与周期性统计结合,用最少的资源做到“有异常即知”。
手把手教你写一个SSH监控脚本
下面是一个可直接运行的bash脚本,已做中文注释,适用于CentOS/Ubuntu。
#!/bin/bash
# ssh_monitor.sh - 实用SSH登录日志监控脚本
# 功能:实时监控失败登录,超过阈值自动发告警
# 配置区域
LOG_FILE="/var/log/auth.log" # 根据系统修改
THRESHOLD=5 # 同一IP在WINDOW_SEC秒内失败次数阈值
WINDOW_SEC=600 # 监控时间窗口(秒)
WHITELIST=("10.0.0.1" "8.8.8.8") # 白名单IP
# 临时文件存储已处理的IP与计数器
tmp_file="/tmp/ssh_fail_count.txt"
[ ! -f "$tmp_file" ] && touch "$tmp_file"
# 通知函数(示例使用curl发送到企业微信webhook)
send_alert() {
local ip=$1 count=$2
local message="⚠️ SSH暴力破解告警\n源IP: $ip\n失败次数: $count\n时间: $(date)"
# 以下两行替换为你自己的webhook地址
# curl -s -X POST "https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=xxx" \
# -H "Content-Type: application/json" -d "{\"msgtype\":\"text\",\"text\":{\"content\":\"$message\"}}"
echo "[ALERT] $message" # 测试时打印
}
# 清理过期计数器(防止内存膨胀)
clean_expired() {
local now=$(date +%s)
# 用sed删除过期行(格式:IP:timestamp)
sed -i "/:.*/{
h; s/^[^:]*://; s///g; s/$/; $now-&/;
/;$WINDOW_SEC/d
}" "$tmp_file" 2>/dev/null
}
# 核心监控循环
tail -n0 -F "$LOG_FILE" | while read line; do
# 仅处理失败登录(Failed password)
if echo "$line" | grep -q "Failed password"; then
ip=$(echo "$line" | grep -oP 'from \K[0-9.]+')
[ -z "$ip" ] && continue
# 检查白名单
for wip in "${WHITELIST[@]}"; do
[ "$ip" = "$wip" ] && continue 2
done
# 更新计数器:在临时文件中记录该IP的出现次数
now=$(date +%s)
# 追加记录,格式“IP:timestamp”
echo "$ip:$now" >> "$tmp_file"
# 统计该IP在WINDOW_SEC内的出现次数
count=$(grep "^$ip:" "$tmp_file" | wc -l)
if [ "$count" -ge "$THRESHOLD" ]; then
send_alert "$ip" "$count"
# 重置该IP计数器,避免重复告警
sed -i "/^$ip:/d" "$tmp_file"
fi
# 定期清理(每10行清理一次不会影响性能)
clean_expired
fi
# 可选:监控成功登录
# if echo "$line" | grep -q "Accepted password"; then ... fi
done
脚本要点说明
- 实时性:
tail -n0 -F会从日志文件末尾开始跟踪,即使文件被轮转也能自动绑定新文件。 - 性能优化:使用临时文件做计数器,而不是占用大量内存,每次处理一行,CPU消耗微乎其微。
- 白名单机制:避免将管理员或已知服务IP误告警。
- 可扩展性:
send_alert函数已预留网络通知接口,修改curl命令即可对接钉钉、飞书、Slack等。
自动响应:从监控到阻断
结合iptables自动封禁
在脚本的send_alert函数中添加iptables规则:
iptables -A INPUT -s "$ip" -j DROP echo "[ACTION] iptables已封禁 $ip"
注意:执行iptables需要root权限,建议将脚本以sudo方式运行,或通过visudo赋予特定免密权限,更推荐使用ipset与本脚本结合,避免大量DROP规则拖慢防火墙。
使用fail2ban替代自己写脚本?
问答环节:
Q:已经有了fail2ban,为什么还要自己写脚本?
A:fail2ban非常成熟,但定制化程度有限,例如你想实现“某IP连续尝试失败超过阈值后,不仅封禁,还发送企业微信通知+记录到数据库+触发自动化剧本”,自己写脚本可以完全控制,脚本可以更轻量(fail2ban依赖python环境),适合资源受限的嵌入式系统或容器场景。
Q:脚本需要长时间运行,会不会因崩溃而停止?
A:建议搭配systemd服务或supervisor管理,设置auto-restart,例如创建/etc/systemd/system/ssh-monitor.service,配置Restart=always。
告警通知多样性
- 邮件:使用
mail命令(需安装mailutils或mailx) - 企业微信机器人:通过webhook发送json格式消息
- 钉钉机器人:类似企业微信,修改密钥与签名
- Telegram Bot:利用curl和bot API推送
例如钉钉通知代码片段:
curl -s -X POST "https://oapi.dingtalk.com/robot/send?access_token=YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d "{\"msgtype\":\"text\",\"text\":{\"content\":\"SSH告警: $ip 尝试登录失败超过$THRESHOLD次\"}}"
常见问题答疑
Q1:脚本性能会拖慢服务器吗?
A:不会,脚本只监控单个日志文件的新增行,使用tail -F和简单的文本处理,即使在每分钟产生上千条日志的极端情况下,CPU占用也很少超过2%,建议将脚本以较低优先级运行(nice -n 19),或使用ionice限制磁盘IO。
Q2:日志轮转(logrotate)时脚本会失效吗?
A:脚本中使用了tail -F(大写F),此参数会在文件被重命名或删除后,自动尝试重新打开同名文件,只要logrotate后新的日志文件名保持不变(例如auth.log而非auth.log.1),脚本就会无缝继续,如果遇到特殊轮转配置,可考虑使用inotifywait。
Q3:如何避免误报白名单之外的合法操作?
A:三个方法:
- 在脚本中增加“成功登录”检测(Accepted),如果该IP在同一时间段有成功登录,则降低其失败计数权重。
- 设置合理的阈值(例如5次/10分钟),避免将密码错误键入视为暴力破解。
- 在告警后增加人工确认操作(如封禁前先发送确认消息,但自动化场景不建议此方法)。
Q4:脚本只能在SSH日志上使用吗?
A:完全不是,修改LOG_FILE变量和grep匹配规则,即可轻松监控其他服务日志,如FTP(vsftpd.log)、HTTP(access_log中的404扫描)、甚至VPN日志,这套框架是通用的日志监控模板。
从“被动查”到“主动防”
利用一个不足150行的脚本,你可以实现:
- ✅ 实时监控SSH暴力破解,秒级告警
- ✅ 自动封禁攻击源IP,阻断风险于初始阶段
- ✅ 自定义通知方式,随时随地掌控服务器安全
- ✅ 轻量无依赖,任何Linux发行版都可运行
实用脚本能自动监控SSH登录日志吗? 答案不仅是“能”,而且是“应该做”,在云服务器面临持续扫描的今天,脚本帮你把安全管理工作从枯燥的日志翻查,变成了高效、自动化的防御系统。
下一阶段,你可以将此脚本与Ansible、SaltStack等配置管理工具结合,推送至所有服务器,实现统一的SSH安全基线。最好的安全策略,是让攻击者没有机会碰到你的真实服务。