iptables的limit模块仅做全局速率限制,不区分IP;真正限制单IP并发连接数需用connlimit模块,限单IP新建连接速率应使用hashlimit模块,并与connlimit组合实现双重防护。

所以准确说:想“平滑限制单 IP 并发连接速率”,本质是两件事的组合—— 一是限新建连接频率(防爆破),二是限已建立连接数量(防占线)。`limit` 单独用在这里容易误配、效果打折,甚至引发服务中断(如资料中提到的 CPU 飙高案例)。
为什么 limit 模块不适合直接限单 IP 速率?
limit 是无状态的全局计数器:
– 它不区分来源 IP,所有匹配包共用一个桶;
– 同一 IP 发 100 个 SYN,和 100 个 IP 各发 1 个 SYN,在 limit 看起来一样;
– 实际场景中攻击者常分散 IP 轮询,limit 完全失效。
因此,仅用 iptables -m limit --limit 5/min 无法达成“每个 IP 每分钟最多 5 次”的目标。
用 hashlimit 实现真正的单 IP 新建连接限速
hashlimit 按源 IP 建立独立哈希桶,支持突发容错,更贴合真实需求:
-
基础命令(每分钟最多 5 个新 SSH 连接):
iptables -A INPUT -p tcp --dport 22 -m state --state NEW -m hashlimit \<br> --hashlimit-above 5/min \<br> --hashlimit-burst 5 \<br> --hashlimit-mode srcip \<br> --hashlimit-name ssh-rate \<br> -j DROP - --hashlimit-burst 5 允许短时重连(如网络抖动后快速重建),避免误伤;
- --hashlimit-mode srcip 确保每个 IP 独立统计,互不影响;
-
先测试再生效:建议初期把
-j DROP换成-j LOG --log-prefix "SSH-LIMIT: ",查dmesg | grep SSH-LIMIT确认拦截逻辑符合预期。
搭配 connlimit 控制单 IP 并发连接上限
新建连接被限速后,还需防止某 IP 维持大量长连接耗尽资源:
-
限制每个 IP 最多 3 个活跃 SSH 会话:
iptables -A INPUT -p tcp --dport 22 -m connlimit \<br> --connlimit-above 3 \<br> --connlimit-mask 32 \<br> -j REJECT --reject-with tcp-reset - --connlimit-mask 32 表示精确到单个 IPv4 地址;
- 用 REJECT + tcp-reset 让客户端立刻断开,不卡在超时等待;
- 注意:connlimit 依赖
nf_conntrack模块,确保lsmod | grep nf_conntrack有输出。
规则顺序与持久化要点
执行顺序决定逻辑是否生效:
- 先放行合规的新建连接(hashlimit 放行);
- 再对已建立连接做并发检查(connlimit);
- 最后兜底拒绝所有未匹配的 SSH 新建请求(-j DROP);
- 保存规则:
iptables-save > /etc/iptables/rules.v4(Debian/Ubuntu)或service iptables save(CentOS 6),systemd 环境建议用iptables-persistent或nftables替代。

















