Linux防火墙(iptables/nftables)通过mangle表打mark标记,再由tc的fw过滤器基于标记实现精准限速。先用MARK目标设置32位标记,再在tc中用fw匹配mark值分流至不同HTB带宽类,结合conntrack和multiport提升协议识别精度,并需验证计数与持久化配置。

Linux 防火墙本身(如 iptables/nftables)不直接“限速”,但可通过与内核流量控制子系统(tc)协同,实现基于标记(mark)的精准流量控制。核心思路是:先用防火墙规则对特定协议、端口或连接打标记,再用 tc 根据标记分流并限速。这种方式比单纯匹配 IP 或端口更灵活、更高效,也避免了重复解析包头。
标记流量:用 iptables/mangle 表打 mark
mangle 表专用于修改数据包,其中 MARK 目标可为数据包设置一个 32 位整数标记(0–0xffffffff),供后续 tc 识别。标记操作通常放在 PREROUTING(入向)或 OUTPUT(本机发出)链。
- 标记所有 HTTP 流量(目标端口 80):
sudo iptables -t mangle -A PREROUTING -p tcp --dport 80 -j MARK --set-mark 1 - 标记 SSH 流量(源端口 22,常用于出站响应):
sudo iptables -t mangle -A OUTPUT -p tcp --sport 22 -j MARK --set-mark 2 - 标记已建立的连接(配合 conntrack,保证双向一致):
sudo iptables -t mangle -A PREROUTING -m conntrack --ctstate ESTABLISHED,RELATED -j CONNMARK --save-mark
sudo iptables -t mangle -A OUTPUT -m conntrack --ctstate ESTABLISHED,RELATED -j CONNMARK --restore-mark
tc 基于 mark 分流:使用 fw 模块
tc 的 u32 或 fw 过滤器能读取数据包的 netfilter 标记。推荐用 fw 过滤器(更简洁、性能更好),它直接匹配 iptables 设置的 mark 值。
Linux 性能分析与调优专家,覆盖 CPU、内存、磁盘 I/O、网络、内核参数、编译优化、容器/K8s。适用场景:系统卡顿/高负载、内存不足/OOM/Swap 高、CPU 异常/iowait 高。
- 先创建 htb 队列:
sudo tc qdisc add dev eth0 root handle 1: htb default 30 - 创建两个带宽类:
sudo tc class add dev eth0 parent 1: classid 1:1 htb rate 10mbit ceil 10mbit
sudo tc class add dev eth0 parent 1:1 classid 1:10 htb rate 2mbit ceil 4mbit
sudo tc class add dev eth0 parent 1:1 classid 1:20 htb rate 512kbit ceil 1mbit - 用 fw 过滤器按 mark 分流:
sudo tc filter add dev eth0 parent 1: protocol ip prio 1 fw classid 1:10(mark=1 → 类 1:10)
sudo tc filter add dev eth0 parent 1: protocol ip prio 2 fw classid 1:20(mark=2 → 类 1:20)
协议级过滤:结合 conntrack 与 multiport 提升精度
仅靠端口匹配(如 --dport 80)可能被伪装绕过。真实场景中应叠加协议特征判断:
- 限制非标准端口上的 DNS 查询(UDP + 端口 53 或非常规端口但含 DNS 头):
sudo iptables -t mangle -A PREROUTING -p udp -m udp --dport 53 -j MARK --set-mark 3
sudo iptables -t mangle -A PREROUTING -p udp -m length --length 52 -j MARK --set-mark 3(典型 DNS 查询长度) - 区分 HTTP/HTTPS:HTTPS 流量无明文 Host,但可用 TLS Client Hello 特征(需 xt_u32 或 nftables + socket 模块);更实用的是结合端口 + 连接状态:
sudo iptables -t mangle -A PREROUTING -p tcp -m multiport --dports 80,8080,3000 -m conntrack --ctstate NEW -j MARK --set-mark 1
sudo iptables -t mangle -A PREROUTING -p tcp -m multiport --dports 443,8443 -m conntrack --ctstate NEW -j MARK --set-mark 4
验证与持久化关键点
标记和分流是否生效,不能只看规则是否存在,要查实际匹配计数:
- 查看 iptables mangle 规则命中次数:
sudo iptables -t mangle -L PREROUTING -v -n - 查看 tc 过滤器统计:
sudo tc -s filter show dev eth0 - 持久化注意:iptables 规则需保存(如 iptables-save > /etc/iptables/rules.v4),tc 命令无内置持久化,建议写成脚本放入 /etc/network/if-up.d/ 或 systemd service。

















