iptables的hashlimit模块仅支持速率限制(如每秒连接数),不支持带宽限制;需结合tc实现按用户(如源IP)的独立带宽整形,其中hashlimit用于防刷限频,tc负责实际带宽控制。

iptables 的 hashlimit 模块本身不支持“带宽”限制(如 Mbps),它只支持“速率”限制(如 每秒连接数、每分钟包数等)。所谓“对每个用户独立带宽的平滑限制”,严格来说无法仅靠 hashlimit 实现。但你可以结合 hashlimit(做连接/请求频次控制) + tc(Traffic Control,真正做带宽整形)来达成近似目标:按用户(如源 IP 或 UID)分类流量,并分别限速。
明确核心分工:hashlimit ≠ 带宽限速
hashlimit 是匹配模块,用于动态跟踪并限制“单位时间内的匹配次数”,典型用途是防刷、限连接频率(如:每个 IP 每秒最多新建 10 个 TCP 连接)。它不感知字节数、不控制发包速率、不调整队列或延迟——这些是 tc 的职责。
所以,正确路径是:
- 用
iptables + hashlimit做粗粒度准入控制(比如拦截异常高频请求) - 用
iptables + owner/physdev/connmark标记不同用户的流量 - 用
tc + htb/cbq/fq_codel对标记流量做独立带宽整形
按源 IP 区分用户并限速(最常用场景)
假设你通过 NAT 或直连知道每个用户对应一个公网/内网 IP(如 192.168.100.0/24 下的终端),可按 IP 分流限速:
步骤 1:用 iptables 标记用户流量
iptables -t mangle -A PREROUTING -s 192.168.100.10 -j MARK --set-mark 10 iptables -t mangle -A PREROUTING -s 192.168.100.11 -j MARK --set-mark 11 # ……为每个用户设唯一 mark
步骤 2:用 tc 创建 HTB 根队列并定义类
# 绑定到 eth0(替换为你实际网卡) tc qdisc add dev eth0 root handle 1: htb default 30 <h1>总带宽上限(例如 100Mbit)</h1><p>tc class add dev eth0 parent 1: classid 1:1 htb rate 100mbit</p><h1>为用户 10 分配 5Mbit,上行 burst 缓冲</h1><p>tc class add dev eth0 parent 1:1 classid 1:10 htb rate 5mbit ceil 6mbit burst 15k tc class add dev eth0 parent 1:1 classid 1:11 htb rate 5mbit ceil 6mbit burst 15k</p><h1>附加 sfq(随机公平队列)避免单流占满</h1><p>tc qdisc add dev eth0 parent 1:10 handle 10: sfq tc qdisc add dev eth0 parent 1:11 handle 11: sfq</p><h1>关联 mark 到 class</h1><p>tc filter add dev eth0 parent 1: protocol ip handle 10 fw flowid 1:10 tc filter add dev eth0 parent 1: protocol ip handle 11 fw flowid 1:11
进阶:结合 hashlimit 做双层防护(防突发+保带宽)
在标记前加一层 hashlimit,防止某个用户短时间内打满连接导致队列拥塞:
# 允许每个 IP 每秒最多 20 个新连接,超限则 DROP(可改为 LOG 或 REJECT) iptables -t mangle -A PREROUTING -s 192.168.100.0/24 \ -m state --state NEW \ -m hashlimit --hashlimit-above 20/sec \ --hashlimit-burst 60 \ --hashlimit-mode srcip \ --hashlimit-name perip_conn \ -j DROP <h1>再执行前面的 MARK 规则(确保未被 drop 的包才进入 tc)
这样既限制了连接建立频率(防扫描/慢速攻击),又保障了正常流量能被 tc 平滑调度带宽。
注意事项与常见坑
-
hashlimit的--hashlimit-mode支持srcip、dstip、srcport、dstport、srcip,srcport等组合,选准维度才能精准区分用户 -
tc只能控制本机发出的流量(e.g.,egress),若要限下行(inbound),需在上游设备做策略,或使用 IFB(Intermediate Functional Block)虚拟设备重定向 - 标记(MARK)必须在
mangle表的PREROUTING(入向)或OUTPUT(本机出向)链中完成,且tc filter需匹配同一协议和 handle - 大量用户时,手动写每条
iptables -j MARK不现实,建议用脚本生成,或改用ipset+setmatch 提升性能


















