linux中用iptables -t mangle修改dscp字段是qos打标关键步骤:需在prerouting或output链匹配流量(如ssh端口22),用dscp模块设标准值(如46),再配合tc基于dscp分流调度。

在 Linux 中用 iptables -t mangle 修改 DSCP 字段,是实现网络层 QoS 的关键一步。核心在于:选对表(mangle)、选对链(通常是 PREROUTING 或 OUTPUT)、匹配业务流量特征(如端口、协议),再用 DSCP 模块设置标准值(如 EF=46、AF21=18)。这步本身不调度带宽,只打标,后续需配合 tc 做类映射与调度。
明确 mangle 表和 DSCP 模块的作用
mangle 表专用于修改数据包头字段,DSCP 是 IP 头中 ToS 字节的高 6 位,直接决定交换机/路由器如何排队转发。iptables 本身不处理队列,它只是给包“贴标签”。要让标签生效,必须在出接口上用 tc 建立类(class)和过滤器(filter),把不同 DSCP 值导向对应队列。
- DSCP 值必须用十进制(如 --set-dscp 46),不是十六进制或名称(EF/AF21 需查 RFC 标准换算)
- 规则应加在 PREROUTING(入站后路由前)或 OUTPUT(本机发出前),避免在 FORWARD 中误标转发流(除非你确实要干预中间设备行为)
- 务必确认内核已加载 xt_dscp 模块:modprobe xt_dscp
标记典型业务流量的实操命令
按常见业务类型分别打标,便于后续 tc 策略区分处理:
-
SSH 远程管理(高可靠低延迟):
iptables -t mangle -A PREROUTING -p tcp --dport 22 -j DSCP --set-dscp 46 -
Web 服务(中等优先级):
iptables -t mangle -A PREROUTING -p tcp --dport 80 -j DSCP --set-dscp 18(AF21) -
VoIP 信令(如 SIP):
iptables -t mangle -A PREROUTING -p udp --dport 5060 -j DSCP --set-dscp 26(AF31) -
视频会议媒体流(RTP):
iptables -t mangle -A PREROUTING -p udp --sport 16384:32767 -j DSCP --set-dscp 46(EF,注意用 --sport 匹配返回流)
验证标记是否生效
打标后不能只看规则是否存在,得抓包确认 DSCP 字段真被改写:
- 用 tcpdump 抓包并显示 DSCP:
tcpdump -i eth0 -n "tcp port 22" -vvv | grep -i dscp - 若看到类似 tos 0x90 (DSCP 46, ECN 0),说明标记成功
- 注意:若从本机发起 SSH,需检查 OUTPUT 链是否也打了标(PREROUTING 不处理本机发出包)
与 tc 配合完成完整 QoS 隔离
仅打标没有调度等于白做。以 eth0 为例,典型配合流程:
- 先建 HTB 根类:
tc qdisc add dev eth0 root handle 1: htb default 30 - 建三个子类(EF/AF21/BE),分配带宽权重
- 加过滤器,按 DSCP 值分流:
tc filter add dev eth0 parent 1: protocol ip u32 match ip dsfield 0xb8 0xfc flowid 1:10(0xb8 是 46 的十六进制,0xfc 是掩码) - EF 类建议搭配 fq_codel:
tc qdisc add dev eth0 parent 1:10 fq_codel,保障低延迟











