limit模块限单IP新建连接本质是控SYN包速率,需配合--state NEW,仅对NEW状态TCP包采样,防暴力破解;典型配置为--limit 3/min --limit-burst 3,必须先ACCEPT后DROP且置于INPUT链靠前。

用 limit 模块限制单 IP 新建连接频率,本质是控「每秒/每分钟能发几个 SYN」
它不统计并发连接数,也不管你连上了没,只对匹配到的「新建连接请求包」(即 --state NEW 的 TCP 包)做速率采样。典型用途是防 SSH 暴力破解、HTTP 扫描器高频试探。
常见错误是直接对所有包限速,或漏掉 --state NEW,结果把 ACK、RST 甚至已建立连接的数据包也拦了,导致服务假死。
- 必须配合
-m state --state NEW,否则规则作用于所有 TCP 包,误伤严重 -
--limit是平均速率,--limit-burst是初始允许突发量,默认为 5;比如--limit 3/min --limit-burst 3表示:首分钟最多放行 3 个新连接,之后每分钟最多再放 3 个 - 规则顺序很重要:先
ACCEPT合规请求,再DROP或REJECT剩余,否则会直接截断所有后续包
iptables -m limit 防 SSH 暴力破解的最小可用配置
这是生产环境最常复用的模板,针对端口 22,兼顾可用性与防护强度:
iptables -I INPUT -p tcp --dport 22 -m state --state NEW -m limit --limit 3/min --limit-burst 3 -j ACCEPT iptables -I INPUT -p tcp --dport 22 -m state --state NEW -j DROP
说明:
- 第一条放行每分钟最多 3 个新连接,且允许开局就来 3 个(避免用户第一次连就卡住)
- 第二条兜底拒绝所有未被第一条放行的新建连接请求,注意不能写
REJECT,否则可能触发客户端重试风暴 - 这两条必须插在 INPUT 链靠前位置(用
-I),否则可能被更早的ACCEPT规则绕过
为什么 --limit 10/second 很少真用?
每秒 10 次新建连接听起来很宽松,但实际极易误杀正常用户:
- 浏览器加载一个页面常触发 6–8 个并行 HTTP 连接(尤其带资源域名分片时),加上 DNS+TLS 握手重试,很容易突破 10/s
- 移动端网络不稳定,SYN 丢包后客户端会快速重发,造成短时间内大量
NEW包堆积 -
limit模块无 IP 状态记忆,每次匹配独立计数,无法区分「同一 IP 的连续请求」和「不同 IP 的随机请求」 - 真正需要秒级限速的场景(如 API 网关),应该用
hashlimit或应用层限流,而非limit
和 connlimit、recent 的关键区别在哪?
别混用这三个模块——它们解决的问题完全不同:
-
limit:单位时间内的新建连接请求数(速率),无状态,轻量,适合粗粒度防护 -
connlimit:当前 ESTABLISHED + SYN_RECV 连接数(并发),依赖nf_conntrack,适合防连接耗尽 -
recent:基于 IP 的时间窗口内命中次数(频次+记忆),可实现「60 秒内超 20 次就拉黑 5 分钟」,但规则复杂、易出错
如果你要防 CC 攻击,单靠 limit 不够;如果只是压测前临时挡扫端口脚本,limit 加 --state NEW 就够用。真正容易被忽略的是:limit 规则本身不会记录 IP,也不会自动封禁,它只是「让多余的包静默丢弃」——日志里看不到拒绝记录,排查时容易以为规则没生效。


















