limit模块不支持单IP独立限流,因其全局共享令牌桶;hashlimit模块通过--hashlimit-mode srcip为每个源IP维护独立令牌桶,配合--hashlimit和--hashlimit-burst参数及后续DROP规则,才能实现平滑精准的单IP限流。

iptables 的 limit 模块适合做简单、低开销的速率控制,但它不按源 IP 独立计数,而是全局共享令牌桶——这意味着它无法真正实现“单 IP 限流”,只适合粗粒度防护(如限制本机发 ICMP 包频率)。若目标是**平滑限制单 IP 的访问峰值**,limit 模块并不适用,必须改用 hashlimit 模块。
为什么 limit 模块不适合单 IP 限流
limit 模块没有维度区分能力:所有匹配的数据包共用一个令牌桶。例如:
iptables -A INPUT -p icmp -m limit --limit 5/sec -j ACCEPT- 这条规则会让整个服务器每秒最多放行 5 个 ICMP 包,不管来自 1 个 IP 还是 100 个 IP
- 恶意 IP 可能只发 3 个包,其余 2 个被正常用户分走;或多个攻击 IP 合计压垮阈值,而单个 IP 却未被有效约束
正确做法:用 hashlimit 实现单 IP 独立限速
hashlimit 按指定维度(如 srcip)为每个客户端维护独立令牌桶,支持突发容忍,才是平滑控峰的核心工具:
- 限制每个 IP 对 SSH 端口每秒最多新建连接 2 次,允许最多 5 次瞬时突发:
iptables -A INPUT -p tcp --dport 22 -m state --state NEW -m hashlimit \--hashlimit-name ssh-new --hashlimit 2/sec --hashlimit-burst 5 \--hashlimit-mode srcip -j ACCEPT - 紧接一条兜底丢弃规则(否则未匹配包仍会继续向下匹配):
iptables -A INPUT -p tcp --dport 22 -m state --state NEW -j DROP - 规则名
--hashlimit-name ssh-new必须唯一,用于查看实时状态:cat /proc/net/ipt_hashlimit/ssh-new可看到各 IP 当前令牌余量
关键参数调优建议
平滑控峰效果取决于两个参数的配合:
-
--hashlimit X/unit:决定长期平均速率,单位支持/sec、/min、/hour;对 Web 接口常用10/sec,对登录页可设更严(如1/sec) -
--hashlimit-burst N:桶容量,应略高于典型合法行为峰值;例如页面加载含 6 个资源请求,burst设为 8~10 较合理 - 过大的
burst会使限流形同虚设;过小则易误伤 AJAX 重试、前端懒加载等正常行为
配套动作不能省略
仅加 ACCEPT 不等于完成限流:
- 必须在
ACCEPT规则后紧跟无条件DROP或REJECT,切断未达标流量路径 - 若只想限制新建连接(避免干扰已有长连接),务必加上
-m state --state NEW - 上线前先用
-j LOG测试,确认日志中出现拦截记录再切到DROP - 规则需持久化:
iptables-save > /etc/sysconfig/iptables(CentOS)或netfilter-persistent save(Debian/Ubuntu)

















