强曰为道

与天地相似,故不违。知周乎万物,而道济天下,故不过。旁行而不流,乐天知命,故不忧.
文档目录

第 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 是一个内核内部的整数值,不会出现在网络上的数据包中。它通常用于:

  1. 策略路由:根据标记选择不同的路由表
  2. tc 流量控制:根据标记进行带宽管理
  3. 规则分类:在 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-extensionsTOS/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 表与连接跟踪优化,将学习如何优化连接跟踪性能。