iptables 完全指南 / 第 06 章:mangle 表详解
第 06 章:mangle 表详解
本章目标:掌握 mangle 表的五大链、修改 TOS/TTL/MARK 的方法,以及在 QoS 和策略路由中的实际应用。
6.1 mangle 表概述
mangle 表用于修改数据包的元数据,而非做过滤或地址转换。它是四表中唯一在所有五个链中都可以使用的表。
| 特性 | 说明 |
|---|---|
| 支持的链 | 所有五条链(PREROUTING、INPUT、FORWARD、OUTPUT、POSTROUTING) |
| 核心功能 | 修改数据包头部字段 |
| 执行时机 | 在 raw 表之后、nat/filter 表之前 |
| 典型用途 | QoS 标记、策略路由、TTL 隐藏 |
6.2 可修改的字段
6.2.1 字段一览
| 字段 | 说明 | 用途 |
|---|---|---|
TOS | 服务类型(Type of Service) | QoS 流量分类 |
TTL | 生存时间(Time to Live) | 隐藏网络拓扑 |
MARK | 标记值(内核内部使用) | 策略路由、tc 流量控制 |
SECMARK | 安全上下文标记 | SELinux 网络策略 |
CONNSECMARK | 连接安全标记 | SELinux 连接跟踪 |
NFQUEUE | 传递到用户态队列 | 深度包检查 |
DSCP | 差分服务代码点 | QoS 精细控制 |
6.3 MARK 标记
6.3.1 MARK 的作用
MARK 是一个内核内部的整数值,不会出现在网络上的数据包中。它通常用于:
- 策略路由:根据标记选择不同的路由表
- tc 流量控制:根据标记进行带宽管理
- 规则分类:在 iptables 中后续规则根据标记做匹配
6.3.2 设置 MARK
# 为来自 10.0.0.100 的数据包设置 MARK=1
iptables -t mangle -A PREROUTING -s 10.0.0.100 -j MARK --set-mark 1
# 为 HTTP 流量设置 MARK=2
iptables -t mangle -A PREROUTING -p tcp --dport 80 -j MARK --set-mark 2
# 在 PREROUTING 链标记(入站数据包)
iptables -t mangle -A PREROUTING -i eth0 -p tcp --dport 22 -j MARK --set-mark 100
# 在 OUTPUT 链标记(本机产生的数据包)
iptables -t mangle -A OUTPUT -p tcp --dport 80 -j MARK --set-mark 200
6.3.3 匹配 MARK
# 使用 mark 模块匹配已标记的数据包
iptables -A INPUT -m mark --mark 1 -j ACCEPT
iptables -A INPUT -m mark --mark 2 -j ACCEPT
# 策略路由:根据 MARK 选择路由表
ip rule add fwmark 1 table 100
ip rule add fwmark 2 table 200
6.3.4 MARK 值的操作
# 设置 MARK
iptables -t mangle -A PREROUTING -s 10.0.0.100 -j MARK --set-mark 5
# 与 MARK 进行 AND 操作(保留特定位)
iptables -t mangle -A PREROUTING -s 10.0.0.100 -j MARK --and-mark 0x0f
# 与 MARK 进行 OR 操作
iptables -t mangle -A PREROUTING -s 10.0.0.100 -j MARK --or-mark 0x10
# XOR 操作
iptables -t mangle -A PREROUTING -s 10.0.0.100 -j MARK --xor-mark 0x01
6.3.5 业务场景:双线接入策略路由
#!/bin/bash
# ═══════════════════════════════════════════════════
# 双线接入策略路由
# 线路1:电信 eth0 (203.0.113.0/24) 默认路由
# 线路2:联通 eth1 (198.51.100.0/24) 备用路由
# ═══════════════════════════════════════════════════
# 定义路由表(需要在 /etc/iproute2/rt_tables 中添加)
# 100 telecom
# 101 unicom
# 配置路由表
ip route add default via 203.0.113.1 dev eth0 table telecom
ip route add default via 198.51.100.1 dev eth1 table unicom
# 标记来自内网的特定流量走联通线路
iptables -t mangle -A PREROUTING -s 10.0.0.100 -j MARK --set-mark 101
iptables -t mangle -A PREROUTING -s 10.0.0.200 -j MARK --set-mark 101
# 根据标记选择路由表
ip rule add fwmark 101 table unicom
# 刷新路由缓存
ip route flush cache
6.4 TOS 修改
6.4.1 TOS 字段说明
TOS(Type of Service)字段用于标记数据包的服务类型,路由器可以根据 TOS 值进行优先级转发。
| TOS 值 | 含义 | 典型应用 |
|---|---|---|
| 0x00 | 正常服务 | 默认值 |
| 0x02 | 最小延迟 | SSH、Telnet |
| 0x04 | 最大吞吐量 | FTP 数据传输 |
| 0x08 | 最高可靠性 | SNMP、DNS |
| 0x10 | 最小费用 | 非关键数据 |
6.4.2 设置 TOS
# 为 SSH 流量设置最小延迟
iptables -t mangle -A PREROUTING -p tcp --dport 22 \
-j TOS --set-tos 0x10
# 为 FTP 数据流量设置最大吞吐量
iptables -t mangle -A PREROUTING -p tcp --dport 20 \
-j TOS --set-tos 0x08
# 匹配特定 TOS 值
iptables -A INPUT -m tos --tos 0x10 -j ACCEPT
6.4.3 DSCP 替代 TOS
DSCP(Differentiated Services Code Point)是 TOS 的现代替代方案,提供更精细的 QoS 分类:
# 设置 DSCP 值(EF = 加速转发,适用于语音)
iptables -t mangle -A PREROUTING -p udp --dport 5060 \
-j DSCP --set-dscp-class EF
# 设置 DSCP 值(AF21 = 保证转发,中优先级)
iptables -t mangle -A PREROUTING -p tcp --dport 80 \
-j DSCP --set-dscp-class AF21
# 用数值设置 DSCP
iptables -t mangle -A PREROUTING -p tcp --dport 80 \
-j DSCP --set-dscp 18
6.5 TTL 修改
6.5.1 TTL 的作用
TTL(Time to Live)是 IP 头部的一个字段,每经过一个路由器减 1,到 0 时数据包被丢弃。修改 TTL 可以:
- 隐藏网络拓扑:让外界无法通过 TTL 推断中间路由器数量
- 防止路由环路:确保数据包不会无限循环
6.5.2 设置 TTL
# 将出站数据包的 TTL 设置为 64(隐藏真实 TTL)
iptables -t mangle -A POSTROUTING -o eth0 -j TTL --ttl-set 64
# 将 TTL 增加 1(用于双 NAT 场景)
iptables -t mangle -A PREROUTING -j TTL --ttl-inc 1
# 将 TTL 减少 1
iptables -t mangle -A PREROUTING -j TTL --ttl-dec 1
# 匹配特定 TTL 值(用于检测 traceroute)
iptables -A INPUT -m ttl --ttl-lt 5 -j LOG --log-prefix "LOW-TTL: "
6.5.3 业务场景:防止 traceroute 探测
# 将所有出站数据包的 TTL 统一设置为 128
# 这样攻击者无法通过 TTL 推断中间跳数
iptables -t mangle -A POSTROUTING -o eth0 -j TTL --ttl-set 128
注意:修改 TTL 可能影响某些依赖 TTL 的协议(如某些 DNS 实现)。在生产环境使用前请充分测试。
6.6 实战:综合 mangle 配置
6.6.1 QoS 标记方案
#!/bin/bash
# ═══════════════════════════════════════════════════
# QoS 流量分类与标记
# 配合 tc(traffic control)使用
# ═══════════════════════════════════════════════════
# 清空 mangle 表
iptables -t mangle -F
# ─── 高优先级流量(语音、视频会议)───
iptables -t mangle -A FORWARD -p udp --dport 5060 -j MARK --set-mark 1
iptables -t mangle -A FORWARD -p udp --dport 10000:20000 -j MARK --set-mark 1
iptables -t mangle -A FORWARD -p tcp --dport 3478 -j MARK --set-mark 1
# ─── 中优先级流量(Web、SSH)───
iptables -t mangle -A FORWARD -p tcp -m multiport --dports 80,443 -j MARK --set-mark 2
iptables -t mangle -A FORWARD -p tcp --dport 22 -j MARK --set-mark 2
# ─── 低优先级流量(文件下载、更新)───
iptables -t mangle -A FORWARD -p tcp --dport 21 -j MARK --set-mark 3
iptables -t mangle -A FORWARD -p tcp -m multiport --dports 8080,8443 -j MARK --set-mark 3
# ─── 最低优先级(P2P、未知流量)───
iptables -t mangle -A FORWARD -j MARK --set-mark 4
# 配合 tc 使用:
# tc filter add dev eth0 parent 1:0 protocol ip handle 1 fw flowid 1:10
# tc filter add dev eth0 parent 1:0 protocol ip handle 2 fw flowid 1:20
# tc filter add dev eth0 parent 1:0 protocol ip handle 3 fw flowid 1:30
# tc filter add dev eth0 parent 1:0 protocol ip handle 4 fw flowid 1:40
6.6.2 隐藏网络拓扑
#!/bin/bash
# 隐藏网络拓扑配置
# 统一出站 TTL
iptables -t mangle -A POSTROUTING -o eth0 -j TTL --ttl-set 64
# 统一出站 TOS
iptables -t mangle -A POSTROUTING -o eth0 -j TOS --set-tos 0x00
# 记录低 TTL 的入站包(可能是 traceroute)
iptables -t mangle -A PREROUTING -m ttl --ttl-lt 10 \
-j LOG --log-prefix "LOW-TTL-DETECTED: "
6.7 mangle 表与其他表的协作
数据包处理流程中 mangle 表的位置:
入站数据包:
┌──────┐ ┌────────────┐ ┌────────────────┐ ┌──────────┐
│ 网卡 │───→│ raw 表 │───→│ mangle 表 │───→│ nat 表 │
└──────┘ │ PREROUTING │ │ PREROUTING │ │ PREROUTING│
│ (NOTRACK) │ │ (MARK/TOS/TTL) │ │ (DNAT) │
└────────────┘ └────────────────┘ └──────────┘
│
▼
┌────────────────┐ ┌──────────┐
│ mangle 表 │───→│ filter 表 │
│ INPUT │ │ INPUT │
│ (MARK) │ │ (ACCEPT/ │
└────────────────┘ │ DROP) │
└──────────┘
6.8 注意事项
⚠️ mangle 表的执行顺序:mangle 表在 nat 表之前执行。如果在 mangle 表中修改了 TTL 或 TOS,后续的 nat 表和 filter 表看到的是修改后的值。
⚠️ MARK 不跨主机:MARK 值只在本机内核中有效,不会随数据包发送到网络上。如果需要在下游设备识别流量,应使用 DSCP/TOS 字段。
⚠️ 性能影响:mangle 表中的规则对每个数据包都执行,包括已建立连接的后续包。如果规则过多,可能影响转发性能。建议只对关键流量做标记。
6.9 扩展阅读
| 资源 | 说明 |
|---|---|
man iptables-extensions | TOS/TTL/MARK 扩展的手册 |
| Linux Advanced Routing & Traffic Control | 策略路由与 tc 完整指南 |
| RFC 2474 - DSCP | 差分服务标准 |
本章小结
| 操作 | 目标 | 用途 |
|---|---|---|
MARK --set-mark | 设置标记值 | 策略路由、tc |
TOS --set-tos | 设置服务类型 | QoS 分类 |
TTL --ttl-set/inc/dec | 修改生存时间 | 隐藏拓扑 |
DSCP --set-dscp | 设置差分服务 | 精细 QoS |
下一章:第 07 章:raw 表与连接跟踪优化,将学习如何优化连接跟踪性能。