“人人平等”的并发限速指每个源ip独立受限(如每分钟最多5个new连接),互不影响,核心靠--hashlimit-mode srcip实现per-ip计数,配合-m state --state new精准匹配新建连接,而非全局或带宽限制。

用 iptables 的 hashlimit 模块做“人人平等”的并发限速,核心是:**对每个源 IP 单独限制连接数(如 NEW 状态),不偏向任何用户,也不依赖全局阈值**。它不是限带宽,而是限“同时能建多少新连接”,天然适合防扫描、控登录、抑刷接口等场景。
明确目标:什么是“人人平等”的并发限速
“人人平等”指:每个客户端(源 IP)被施加相同的连接新建速率约束,互不影响。A 用户建满限额,不影响 B 用户建自己的限额;没有 VIP 通道,也没有排队等待机制。这和基于总体带宽的 QoS(如 tc + HTB)逻辑不同,hashlimit 是 per-IP 的状态化限速。
典型适用场景:
- SSH 登录:每 IP 每分钟最多 5 次新连接(防暴力破解)
- Web 登录接口:每 IP 每 30 秒最多 3 个 POST /login(防爆破)
- API 网关前置:每 IP 每分钟新建 TCP 连接 ≤ 20(防连接耗尽)
关键参数与规则写法(以 SSH 为例)
以下命令限制每个源 IP 每分钟最多发起 5 个新的 SSH 连接(即匹配 tcp dpt:22 且 state NEW 的包):
iptables -A INPUT -p tcp --dport 22 -m state --state NEW \ -m hashlimit \ --hashlimit-above 5/minute \ --hashlimit-burst 2 \ --hashlimit-mode srcip \ --hashlimit-name ssh_per_ip \ -j DROP
逐项说明:
-
--hashlimit-above 5/minute:超出门限即触发动作(这里是 DROP)。注意单位支持/second、/minute、/hour、/day -
--hashlimit-burst 2:允许突发 2 个额外连接(即首分钟最多 7 个),平滑体验,避免严格均分导致误拦 -
--hashlimit-mode srcip:按源 IP 哈希计数 —— 这是“人人平等”的技术基础。也可加srcport实现更细粒度(如每 IP+端口对),但通常只需srcip -
--hashlimit-name ssh_per_ip:为该规则命名,用于内核哈希表隔离(不同名字=不同计数器)。勿重复使用同一 name 给不同规则 - 务必搭配
-m state --state NEW:只统计新建连接,避免把 ESTABLISHED 或 ACK 包误计入
避坑要点:为什么你的规则可能没生效
常见实效原因及对策:
-
位置错误:规则必须放在
state NEW判定之后、目标链(如 ACCEPT)之前。推荐插入在默认策略前,例如:iptables -I INPUT 1 ... -
未加载模块:运行
lsmod | grep ip_tables_hashlimit,若无输出则执行modprobe ipt_hashlimit -
IPv6 忽略:上述规则仅作用于 IPv4。如需 IPv6,改用
ip6tables并确保加载ip6t_hashlimit -
连接跟踪失效:若系统关闭了 conntrack(如某些容器环境),
state NEW不可用,可改用--syn(仅 SYN 包)替代,但精度略降 -
哈希表满:默认哈希桶数有限(一般 1024),海量 IP 时可能碰撞。可通过
sysctl -w net.netfilter.nf_conntrack_hashsize=4096调大(需 root),或改用connlimit模块替代(后者基于连接跟踪表,非哈希)
进阶:结合 recent 或 LOG 做可观测限速
单纯 DROP 不利于排查。可先记录再限速:
iptables -A INPUT -p tcp --dport 22 -m state --state NEW \ -m hashlimit \ --hashlimit-above 5/minute \ --hashlimit-burst 2 \ --hashlimit-mode srcip \ --hashlimit-name ssh_per_ip \ -j LOG --log-prefix "SSH_HASHLIMIT_DROP: " iptables -A INPUT -p tcp --dport 22 -m state --state NEW \ -m hashlimit \ --hashlimit-above 5/minute \ --hashlimit-burst 2 \ --hashlimit-mode srcip \ --hashlimit-name ssh_per_ip \ -j DROP
或用 recent 模块标记高频 IP 后统一处理:
iptables -A INPUT -p tcp --dport 22 -m state --state NEW \ -m hashlimit \ --hashlimit-above 5/minute \ --hashlimit-mode srcip \ --hashlimit-name ssh_limit \ -m recent --name ssh_abuser --set \ -j DROP
后续可配合脚本读取 /proc/net/nf_conntrack 或 iptables -L -n -v 输出分析攻击源。










