iptables仅负责标记流量,tc执行限速与调度;先用iptables在mangle表中通过--set-mark或--set-dscp-class打标,再用tc基于htb创建队列、分类及filter规则实现qos。

iptables 本身不直接做限速或带宽分配,它只负责“打标签”——把不同类型的流量标记出来;真正执行限速、分级、调度的是 tc(traffic control)。所以实现 QoS 的核心是:用 iptables 标记流量 + 用 tc 按标记执行策略。
第一步:用 iptables 在 mangle 表中标记流量
mangle 表是唯一能修改数据包元信息(如 DSCP 或内核 mark 值)的地方。常用两类标记方式:
-
用 --set-mark 设置内核标记(推荐初学者):适用于所有 Linux 发行版,兼容性好。
例如,给来自 192.168.1.100 的入向流量打标记 1:iptables -t mangle -A PREROUTING -s 192.168.1.100 -j MARK --set-mark 1 -
用 --set-dscp-class 设置 DSCP 值(适合端到端 QoS):需确保网络设备(交换机/路由器)支持并信任该字段。
例如,给 SSH 流量标为 EF( Expedited Forwarding):iptables -t mangle -A OUTPUT -p tcp --sport 22 -j DSCP --set-dscp-class EF
注意:规则链要选对——PREROUTING(进来的转发/本机接收流量)、OUTPUT(本机发出的流量)、POSTROUTING(发出去前最后一步)。INPUT 和 FORWARD 链不适合打 QoS 标签。
第二步:用 tc 创建队列和分类规则
以最常用的 HTB(Hierarchical Token Bucket)为例,在 eth0 上建立分层带宽控制:
- 先清空旧规则(避免冲突):
tc qdisc del dev eth0 root 2>/dev/null || true - 添加根队列,设默认类 ID 30:
tc qdisc add dev eth0 root handle 1: htb default 30 - 创建根类,总出口带宽设为 10Mbit:
tc class add dev eth0 parent 1: classid 1:1 htb rate 10mbit ceil 10mbit - 建两个子类:高优类(5Mbit)和低优类(2Mbit):
tc class add dev eth0 parent 1:1 classid 1:10 htb rate 5mbit ceil 10mbittc class add dev eth0 parent 1:1 classid 1:20 htb rate 2mbit ceil 2mbit
第三步:用 tc filter 把标记流量导入对应类
让 tc 知道“哪个标记对应哪个带宽类”:
- 把标记为 1 的流量导向 1:10 类(高优):
tc filter add dev eth0 protocol ip parent 1:0 prio 1 handle 1 fw flowid 1:10 - 把标记为 2 的流量导向 1:20 类(低优):
tc filter add dev eth0 protocol ip parent 1:0 prio 1 handle 2 fw flowid 1:20
这里 fw 表示按内核 mark 匹配,handle N 必须与 iptables 中 --set-mark N 的数值一致。
验证与调试要点
配置完别急着用,三步快速确认是否生效:
- 查 iptables 规则是否加载成功:
iptables -t mangle -L -v -n—— 看包计数是否增长 - 查 tc 队列结构:
tc qdisc show dev eth0tc class show dev eth0 - 查实时流量匹配情况:
tc -s filter show dev eth0—— 关注 “Sent” 字段是否递增
如果没计数,大概率是链选错、mark 值不匹配,或规则顺序被其他规则拦截。











