iptables 不支持每秒连接数限制,仅能通过 connlimit 控制并发连接数;真正限速需用 limit、hashlimit 模块或 firewalld rich rule 的 limit 参数。
iptables 本身不直接支持“每秒连接数”限制,它只能做并发连接数控制;真要限速(比如 10 连接/秒),得用 limit 或 hashlimit 模块,或者换到 firewalld 的 rich rule + limit 语法。
iptables 用 connlimit 控制并发连接数(不是每秒)
很多人误以为 connlimit 能限“每秒”,其实它只看当前 ESTABLISHED 连接数。比如防爆破 SSH,限制单 IP 最多 3 个并发连接:
sudo iptables -I INPUT -p tcp --dport 22 -m connlimit --connlimit-above 3 -j DROP
常见错误现象:规则加了但攻击没缓解——因为攻击者用短连接快速建连断连,connlimit 压根不计数;它只管“同时在线”的 TCP 连接。
-
--connlimit-mask 32(默认):按单个 IP 统计 -
--connlimit-mask 24:按 C 类网段(如 192.168.1.0/24)统计总连接数 - 该模块必须加载内核模块:
modprobe ip_conntrack_ftp(某些 FTP 场景需要)
firewalld rich rule 实现真正“每秒连接数”限制
firewalld 的 rich rule 支持 limit 参数,单位可写 1/s、5/m、10/h,这才是你想要的速率控制:
sudo firewall-cmd --permanent --add-rich-rule='rule family="ipv4" port port="80" protocol="tcp" limit value="5/s" accept'
注意:这个 limit 是对 *新建连接*(SYN 包)做令牌桶限速,不是并发数。它和 iptables -m limit 行为一致,但 firewalld 封装得更直观。
- 必须加
--permanent否则重启失效 -
limit value="5/s"表示每秒最多放行 5 个新连接,超限包默认被丢弃(不返回 RST) - 若想记录日志再丢弃,改用:
audit limit value="5/s" reject
iptables 用 hashlimit 做带状态的速率限制(推荐进阶用法)
比 limit 更精准:能按源 IP、目标端口分组限速,且自带自动老化机制,适合防 CC 攻击:
星声AI
可分享的AI播客内容生成器和效率工具
下载
sudo iptables -I INPUT -p tcp --dport 80 -m hashlimit \ --hashlimit-name http_limit \ --hashlimit-mode srcip \ --hashlimit-upto 10/sec \ --hashlimit-burst 30 \ --hashlimit-htable-expire 600000 \ -j ACCEPT
关键参数说明:
-
--hashlimit-upto 10/sec:每个源 IP 每秒最多 10 个新连接 -
--hashlimit-burst 30:允许短时突发 30 个(防误杀合法用户) -
--hashlimit-htable-expire 600000:哈希表项 10 分钟无活动后自动清理 - 务必配合一条兜底 DROP 规则,否则未匹配的流量会继续往下走链
别忘了内核连接跟踪表大小(nf_conntrack_max)
无论用哪种方案,如果 nf_conntrack_count 接近 nf_conntrack_max,新连接就会被丢弃(表现为随机超时或拒绝),这不是防火墙规则的问题,而是内核资源耗尽:
cat /proc/sys/net/netfilter/nf_conntrack_count cat /proc/sys/net/netfilter/nf_conntrack_max
临时调大:
echo 65536 | sudo tee /proc/sys/net/netfilter/nf_conntrack_max
永久生效需写入 /etc/sysctl.conf:
net.netfilter.nf_conntrack_max = 65536
这个值设太高会吃内存(每个连接约 300B),太低又容易触发假限流——实际部署前一定要压测验证。