iptables hashlimit模块可对特定端口按连接速率动态限流,核心是匹配端口+合理哈希粒度+选择srcip等模式,需配合--state NEW、设置burst与expire参数,并优先配置白名单。

用 iptables 的 hashlimit 模块对特定服务端口限流,核心是“按连接速率或请求频率做动态分流控制”,而不是简单封禁。关键在于匹配目标端口 + 设置合理的哈希桶粒度 + 选择合适的触发模式(如 per-ip 或 per-port),避免误伤正常用户或漏控攻击流量。
明确限流目标和服务端口
先确认你要保护的服务及其监听端口,比如:
- Web 服务:TCP 80 / 443
- SSH 登录:TCP 22
- 数据库访问:TCP 3306(MySQL)、5432(PostgreSQL)
- API 接口:自定义端口如 8080、9000
注意区分 入站(INPUT) 和 转发(FORWARD) 链——大多数服务限流应作用于 INPUT 链;若服务部署在 NAT 后或容器中,可能需调整链位置。
基础 hashlimit 限流规则写法
以限制单个 IP 对 SSH 端口(22)的新连接速率为每分钟 5 次为例:
iptables -A INPUT -p tcp --dport 22 -m state --state NEW -m hashlimit \ --hashlimit-above 5/min \ --hashlimit-burst 10 \ --hashlimit-mode srcip \ --hashlimit-name ssh_limit \ --hashlimit-htable-expire 300000 \ -j DROP
各参数含义:
-
--hashlimit-above 5/min:超过每分钟 5 个新连接即触发限流 -
--hashlimit-burst 10:允许短时突发最多 10 个连接(防误判) -
--hashlimit-mode srcip:按源 IP 建立哈希桶,实现“每个 IP 独立计数” -
--hashlimit-name ssh_limit:为该规则命名,便于调试和清理 -
--hashlimit-htable-expire 300000:哈希表项 5 分钟无活动后自动过期(单位毫秒)
⚠️ 注意:--state NEW 是必须的,否则会把已建立连接的 ACK、FIN 等包也纳入统计,导致误限。
针对不同场景的进阶配置技巧
根据业务特性灵活组合参数:
-
按目标端口分组限流(适合多服务共用一个 IP):
使用--hashlimit-mode srcip,dstport,让同一 IP 访问不同端口互不影响 -
限制 HTTP 请求频率(非连接):
结合string或http模块识别 GET/POST,再套 hashlimit;但更推荐用 Nginx 或应用层限流,iptables 在七层识别效率低且易绕过 -
防止扫描类探测:
对未开放端口加通用限流,例如:-p tcp -m multiport --dports 21,22,23,25,110,143 --syn+ hashlimit,限制 SYN 包速率 -
白名单优先处理:
在限流规则前插入 ACCEPT 规则放行运维 IP:iptables -I INPUT -s 192.168.10.5 -p tcp --dport 22 -j ACCEPT
验证与排错要点
限流生效后务必验证效果:
- 查看当前规则:
iptables -L INPUT -n -v | grep hashlimit - 检查哈希表状态:
cat /proc/net/ip_tables_matches/hashlimit(部分内核需开启 debug) - 模拟测试:用
for i in {1..10}; do nc -zvw1 服务器IP 22; done观察是否从第 6 次开始超时 - 日志辅助定位:
-j LOG --log-prefix "HASHLIMIT_DROP: "插入规则前,配合dmesg查看丢包记录
常见问题:规则不生效多因链顺序错误、未加 --state NEW、或 nf_conntrack 模块未加载;burst 值设太小会导致合法重试被拦,建议初始值设为阈值的 2–3 倍。

















