真正有效的ssh防护是日志驱动的动态白名单机制:实时解析auth.log或secure中的成功登录ip,自动加入iptables或ipset白名单,并与fail2ban联动实现黑白双控,辅以超时清理和静态兜底规则。

直接用静态IP白名单防SSH攻击,在今天基本失效。团队成员从不同网络接入、云服务出口IP动态漂移、甚至家用宽带每次拨号都换地址——手动维护iptables规则,不是安全,是给自己找麻烦。真正有效的方案,是让防火墙“学会认人”:成功登录一次,就自动信任这个IP一段时间;失败太多次,就立刻拉黑。核心不在堵,而在判别和响应。
用日志驱动的动态白名单机制
关键不是写死IP,而是从/var/log/auth.log(Debian/Ubuntu)或/var/log/secure(RHEL/CentOS)里实时抓取成功的SSH登录记录,提取源IP,再自动加进iptables白名单链。这需要三步闭环:
- 写一个轻量脚本,用
grep "Accepted " | awk '{print $11}'(注意字段位置可能因日志格式微调)持续解析新登录IP - 对每个新IP执行
iptables -I INPUT -s [IP] -p tcp --dport 22 -m conntrack --ctstate NEW -j ACCEPT,并打上注释便于追踪 - 配合
iptables -A INPUT -m set --match-set ssh_whitelist src -p tcp --dport 22 -j ACCEPT这类基于ipset的规则,提升性能和可管理性
与Fail2ban深度联动,形成黑白双控
Fail2ban本身擅长封黑,但默认不支持“成功即加白”。要让它参与白名单闭环,需自定义action:
Linux 性能分析与调优专家,覆盖 CPU、内存、磁盘 I/O、网络、内核参数、编译优化、容器/K8s。适用场景:系统卡顿/高负载、内存不足/OOM/Swap 高、CPU 异常/iowait 高。
- 在
/etc/fail2ban/action.d/下新建whitelist.conf,定义actionstart为清空临时白名单集,actionban为向ipset添加IP - 在
/etc/fail2ban/jail.local中新增一个[sshd-whitelist]段,用filter = sshd-success匹配成功日志,并指向新action - 确保fail2ban的loglevel设为
INFO以上,否则可能漏掉Accept事件
设置合理过期与清理策略
白名单不是永久通行证,否则会越积越多、失去意义:
- 所有自动加入的IP规则,统一加
-m comment --comment "auto-whitelisted-$(date +%s)",方便后续按时间筛选 - 用cron每天执行清理脚本:
iptables -S INPUT | grep "auto-whitelisted" | grep "$(($(date +%s) - 86400))" | awk '{print $4}' | xargs -r -I{} iptables -D INPUT -s {} -p tcp --dport 22 -j ACCEPT(删除24小时前加入的) - 更稳妥的做法是改用
ipset,创建带timeout的hash:ip集:ipset create ssh_temp hash:ip timeout 3600,插入时自动带1小时超时
保留最小化静态兜底,避免自动化失效时失守
完全依赖自动化有风险。务必保留一层人工可控的防御:
- iptables默认策略仍设为
DROP,所有流量必须明确放行 - 在INPUT链最前插入一条“紧急管理IP”规则,比如
iptables -I INPUT -s 203.0.113.5 -p tcp --dport 22 -j ACCEPT,这个IP永不被自动清理 - SSH配置里同步启用
AllowUsers限定账号,双重过滤:即使IP进了白名单,没对应用户名也登不上










