SSH高频连接防护需按序插入三条iptables规则:先DROP已封禁IP,再DROP达阈值者,最后SET新连接;依赖xt_recent模块,参数--seconds 60与--hitcount 5协同判定60秒内5次NEW连接即封300秒。

用 iptables 的 recent 模块实现 SSH 高频连接的动态速率限制与自动封禁,核心是靠内核哈希表实时跟踪源 IP 行为,不依赖日志、不调外部脚本,响应快、资源占用低。关键在规则顺序、匹配条件和参数组合是否精准。
明确防护目标与参数含义
典型目标:同一 IP 在 60 秒内发起 ≥5 次新 SSH 连接(--state NEW),即刻封禁 300 秒。这背后三个参数必须协同:
-
--rcheck --seconds 60 --hitcount 5:从该 IP 第一次触发规则起计时 60 秒,期间累计命中 5 次即满足条件 -
--name ssh_attack:自定义列表名,对应内核中/proc/net/xt_recent/ssh_attack -
--set:每次新连接匹配时,将源 IP 写入列表(为后续统计打基础)
按严格顺序插入 INPUT 链的三条规则
顺序错一条,就会漏判或误封。推荐用 -I 插入链首(确保早于其他 ACCEPT 规则):
- 先查黑名单:已进入 300 秒封禁期?直接丢弃
iptables -I INPUT -p tcp --dport 22 -m state --state NEW -m recent --name ssh_attack --rcheck --seconds 300 -j DROP - 再判阈值:60 秒内达 5 次?封本次并写入黑名单
iptables -I INPUT -p tcp --dport 22 -m state --state NEW -m recent --name ssh_attack --set -m recent --name ssh_attack --rcheck --seconds 60 --hitcount 5 -j DROP - 后记合法连接:未达阈值的新连接,记入列表供后续判断
iptables -I INPUT -p tcp --dport 22 -m state --state NEW -m recent --name ssh_attack --set
确保模块加载与基础环境就绪
recent 模块不是默认启用的,需手动加载并验证:
- 执行
modprobe xt_recent加载模块 - 运行
lsmod | grep xt_recent确认返回非空 - 检查
/proc/net/xt_recent/目录是否存在;若存在,再看cat /proc/net/xt_recent/ssh_attack是否有类似src=192.168.1.100 ttl: 295的输出 - 若无输出,说明规则未生效或匹配条件不匹配(常见原因是漏了
-m state --state NEW)
验证效果与日常维护要点
recent 模块不打日志,状态全在内存中,验证要靠内核接口:
- 模拟攻击可使用简单循环:
for i in {1..6}; do ssh -o ConnectTimeout=2 -o BatchMode=yes user@yourserver exit 2>/dev/null & done,然后立刻查/proc/net/xt_recent/ssh_attack - 封禁时间到期后,对应条目会自动消失,无需手动清理
- 如需临时清空列表,可用
echo : > /proc/net/xt_recent/ssh_attack(注意冒号不能省) - 规则重启后失效,务必保存:Debian/Ubuntu 用
iptables-save > /etc/iptables/rules.v4,CentOS/RHEL 用service iptables save或 systemd 持久化服务


















