iptables的mangle表

本文详细介绍了Linux系统中如何使用mangle表进行数据包标记,以及结合iproute2和iprule实现策略路由。通过创建新的路由表、设置路由规则,并使用iptables的mangle表对特定数据包打上标记,从而实现不同流量通过不同网关的策略。同时,文章提供了多个实例,包括基于协议和端口、IP范围以及DNS解析的策略路由配置,以适应不同的网络环境需求。此外,还讨论了可能遇到的报文丢失问题及解决方案,以及fwmark(netfiltermark)的使用方法。

mangle表的主要功能是根据规则修改数据包的一些标志位,以便其他规则或程序可以利用这种标志对数据包进行过滤或策略路由。

使用策略路由

对应的场景, 都是有多个网口, 常见的使用步骤

1. 创建路由表 Create new routing table

编辑 /etc/iproute2/rt_tables
, 添加

[ID of your Table] [Name of your table]

使用ip rule 对指定的路由表table [Table Name or Table ID]添加路由规则.
使用下面的命令检查

ip route show table [Table Name or Table ID]

为路由表指定默认的路由设备

ip route add default dev "${TUNDEV}" src "${INTERNAL_IP4_ADDRESS}" table "${TABLENAME}"
# 在路由表100上添加一个默认路由(对所有地址), 使用本地网关192.168.1.1, 这是一个可以从eth0到达的地址
ip route add default via 192.168.1.1 dev eth0 table 100
# 对10.1.1.0/30这个目的地址范围添加路由规则, 并添加MPLS标签
ip route add 10.1.1.0/30 encap mpls 200/300 via 10.1.1.1 dev eth0

确定数据包走哪个路由表

默认每个数据报文走的路由表都是main, 你可以给满足一定规则的数据报文指定不同的路由表, 而未满足的还继续使用默认的路由表.

路由规则(ip rule)

这里有所有可能用到的参数列表, 如果还不够, 你可以使用fwmark. 给数据报文打fwmark标签可以通过iptables来处理, 然后通过ip rule来处理. 例如

# 来源于167.99.208.1的用指定table
ip rule add from 167.99.208.1 table [table-name]
# 所有来源都用table ztable1
ip rule add from all table ztable1
# 所有来源中带标签2的都用table 20
ip rule add from all fwmark 2 table 20

2. 使用iptables打标签

使用的格式为 -j MARK --set-mark <Your marknumber in decimal form>. MARK这个target只在mangle中有效.
对于流入的数据报文可以使用-t mangle -A PREROUTING, 对于流出的数据报文可以使用-t mangle -A OUTPUT. 注意: 当数据报文被进程(例如apache)处理过之后, 标签就丢失了. 所以如果打过标签的报文在返回时不正确, 只给流入的报文打标签是不够的, 你必须给产生的流出报文也打上标签.

3. 遇到的问题

报文丢失

很可能是因为被认为"martian"而被丢弃了. 在kernel中被丢弃可能不会留下日志, 可以通过下面的方式开启日志

# 编辑 /etc/sysctl.conf
net.ipv4.conf.default.log_martians = 1
net.ipv4.conf.all.log_martians = 1

如果确认是被作为martian丢弃, 可以进行下面的修改

# 编辑 /etc/sysctl.conf
# Enables source route verification
net.ipv4.conf.default.rp_filter=0
# Enable reverse path
net.ipv4.conf.all.rp_filter=0

关于 fwmark

https://docs.huihoo.com/hpc-cluster/linux-virtual-server/HOWTO/LVS-HOWTO.fwmark.html

Karl Kopper (Apr 2004) said that he thinks the correct term for this is "netfilter mark". A google search finds references to "netfilter mark" back to 2001, and with "fwmark" current at least to 2003. Both terms seem to be in use. The various netfilter HOWTOs don't say anything about new terminology. Horms (who wrote the fwmark code) doesn't know anything about a change in terminology, but thinks it's possible that fwmark is the implementation of netfilter marks.

I asked Harald Welte about this at OLS_2004 and the explanation was as clear as day, except that I didn't write it down and now I've forgotten it (geez, sorry about this). It was a matter of nomenclature rather than logic: it was something like - the entity in the command line is called a mark while the method of marking packets is called fwmark. Whatever it is, you can use either term and people will know what you're talking about.

fwmark实际上就是netfilter mark, 一种打标签的方式或者实现, 没有特殊的含义.

例一

内网的客户机通过Linux主机连入Internet,而Linux主机有两个网口与Internet连接, 分别有两条线路,它们的网关分别为10.10.1.1和10.10.2.1. 现要求对内网进行策略路由,所有通过TCP协议访问80端口的数据包都从10.10.1.1 线路出去,而所有访问UDP协议53号端口的数据包都从10.10.2.1线路出去。
这是一个策略路由的问题,为了达到目的,在对数据包进行路由前,要先根据数据包的协议和目的端口给数据包做上一种标志,然后再指定相应规则,根据数据包的标志进行策略路由。为了给特定的数据包做上标志,需要使用mangle表,mangle表共有5条链,由于需要在路由选择前做标志,因此应该使用PREROUTING链,下面是具体的命令。

iptables -t mangle -A PREROUTING -i eth0 -p tcp --dport 80 -j MARK --set-mark 1  
iptables -t mangle -A PREROUTING -i eth0 -p udp --dprot 53 -j MARK --set-mark 2

以上命令在mangle表的PREROUTING链中添加规则,为来自eth0接口的数据包做标志,其匹配规则分别是TCP协议、目的端口号是80和UDP协议、目的端口号是53,标志的值分别是1和2。数据包经过PREROUTING链后,将要进入路由选择模块,为了对其进行策略路由,执行以下两条命令,添加相应的规则
编辑 /etc/iproute2/rt_tables, 添加对应的路由表

`echo -e "${TABLEID}\t${TABLENAME}" >> /etc/iproute2/rt_tables`

添加路由

ip rule add from all fwmark 1 table 10  
ip rule add from all fwmark 2 table 20

以上两条命令表示所有标志是1的数据包使用路由表10进行路由,而所有标志是2的数据包使用路由表20进行路由。路由表10和20分别使用了10.10.1.1和10.10.2.1作为默认网关

ip route add default via 10.10.1.1 dev eth1 table 10  
ip route add default via 10.10.2.1 dev eth2 table 20

以上两条命令在路由表10和20上分别指定了10.10.1.1和10.10.2.1作为默认网关, 于是使用路由表10的数据包将通过10.10.1.1线路出去,而使用路由表20的数据包将通过10.10.2.1线路出去

例二

网关服务器三块网卡

  • eth0 网通ip:10.0.0.1
  • eth1 电信ip:20.0.0.1
  • eth2 网关ip:192.168.10.1

内网要求192.168.10.1---100以内的ip使用10.0.0.1 网关上网, 其他IP使用 20.0.0.1上网

ip route add default gw 20.0.0.1
# eth0 是 10.0.0.1 所在的网卡, 10是路由表的编号
ip route add table 10 via 10.0.0.1 dev eth0
#fwmark 10 是标记, table 10 是路由表10, 标记了10的数据使用table 10路由表
ip rule add fwmark 10 table 10
#使用iptables给相应的数据打上标记, 对于这种IP范围需要用到iprange模块
iptables -A PREROUTING -t mangle -i eth2 -m iprange --src-range 192.168.10.1-192.168.10.100 -j MARK --set-mark 10

例三

网关服务器三块网卡

  • eth0 网通ip:10.0.0.1
  • eth1 电信ip:20.0.0.1
  • eth2 网关ip:192.168.10.1

内网要求员工访问外面的网站使用 10.0.0.1 网关上网, 其他IP使用 20.0.0.1 上网

iptables -t mangle -A PREROUTING -i eth2 -p tcp --dport 80 -j MARK --set-mark 20
ip route add default gw 20.0.0.1
ip route add table 20 via 10.0.0.1 dev eth0
ip rule add fwmark 20 table 20

例四

使用dnsmasq, 将一个域名列表中匹配的域名解析得到的IP都放到一个名称为outside的ipset中, 让这个ipset的数据包都走指定的虚拟网卡

添加路由表

echo "200 outside" >> /etc/iproute2/rt_tables

添加ipset

# vi /etc/rc.local
ipset create outside hash:ip

添加iptables规则, 打标签

将匹配 ipset outside的包全部标上 mark 8, 在 /etc/firewall.user 中添加:

# vi /etc/firewall.user
iptables -t mangle -A fwmark -m set --match-set outside dst -j MARK --set-mark 8

指定使用的路由表

# 让 8.8.8.8 走 VPN,防止 DNS 污染
ip route add 8.8.8.8 dev $TUNDEV
ip route add default dev $TUNDEV table outside
ip rule add fwmark 8 table outside

将$TUNDEV替换为 VPN 设备名,比如ppp0, tun0等

配置dnsmasq, 使其解析时动态添加ipset

修改 /etc/dnsmasq.conf,在其中加入需要翻越的域名。 格式如下:

server=/域名/8.8.8.8
ipset=/域名/outside

其他

iptables: No chain/target/match by that name

# iptables -t mangle -A PREROUTING -s 192.168.2.0/24 -j
MARK --set-mark 1
iptables: No chain/target/match by that name

如果出现这个错误, 用下面的方式解决

[root@mpc8315erdb /root]# modprobe xt_MARK

参考

<think> 嗯,用户想用大白话了解mangle的作用,看来ta对iptables的理解还在基础阶段。之前解释raw时用了快递分拣的类比效果不错,这次也可以找类似的日常场景。 用户给的引用里提到mangle是“修改数据内容、做流量整形、打标记的”,这个描述比较抽象。让我想想怎么具象化…… 啊,有了!可以比作物流中心的“包裹加工区”:快递在分拣前,工人会做这些事情: 1 给特殊包裹贴荧光标签(MARK标记)→ 对应`-j MARK` 2 把大箱子拆成小箱子(拆包)→ 对应`-j TTL` 3 给易碎品包裹印上“向上”箭头(修改包头)→ 类似修改TOS字段 4 把发往同一地区的包裹合并(流量整形)→ `tc`命令配合 用户可能混淆了mangle和nat的区别,需要强调:mangle不改地址(那是nat的工作),只改包头的“附加信息”。比如: - 快递员不会在mangle区修改收货地址(那是nat的分拣区干的) - 但会在mangle区给包裹贴“加急”“防压”标签 性能方面要提一句:频繁修改包头会增加CPU负担,像快递贴太多标签会降低分拣速度。这点正好和raw的NOTRACK优化形成对比——之前解释过raw是“直接放行不登记”,mangle则是“精心打扮但费时”。 用户引用3的“监测点”例子挺生动,可以延续这个比喻:mangle就是监测站里那个给行人换装的美容师,能给人穿西装或雨衣,但不改变人的身份ID。 </think> ### 大白话解释 mangle 的作用 想象你网购的包裹在快递中心流转,**mangle 就像包裹的「美容改造站」**,专门在不改变核心信息(收/发件人、物品内容)的前提下,对包裹进行精细调整: #### 核心作用: 1. **给包裹贴特殊标签** ```bash iptables -t mangle -A PREROUTING -p tcp --dport 80 -j MARK --set-mark 1 ``` → 给所有寄往80端口(网站服务)的包裹贴上"加急"标签(MARK 1),后续流程看到标签会优先处理[^1]。 2. **修改包裹外观特性** ```bash iptables -t mangle -A POSTROUTING -j TTL --ttl-set 64 ``` → 把包裹的有效期(TTL)统一改成64天,避免某些包裹因"过期"被丢弃(网络跳数限制)[^2]。 3. **拆分超大包裹** ```bash iptables -t mangle -A FORWARD -p tcp -m length --length 1500 -j DROP ``` → 拦截超过1500字节的巨型包裹(类似拒绝接收冰箱等大件),防止堵塞运输通道(网络拥堵)[^3]。 4. **流量整形(包裹限流)** 配合`tc`工具: ```bash iptables -t mangle -A OUTPUT -p icmp -j CLASSIFY --set-class 1:1 ``` → 把聊天消息(ICMP包)标记为"普通信件",限制其占用过多快递车辆带宽。 #### 类比日常场景: | 场景 | mangle 作用 | 真实场景对应 | |--------------------|----------------------------|----------------------------| | 快递贴标签 | 给包裹贴"易碎品"警示 | `-j MARK` 打优先级标记 | | 包裹重新包装 | 把纸箱换成防水袋 | 修改包头 TOS/TTL 字段 | | 分装大件货物 | 把家具拆成多个小箱运输 | 处理 MTU 超大数据包 | | 特殊通道分流 | 生鲜包裹走冷链通道 | `-j CLASSIFY` 流量分类 | > **关键特点**: > - ✏️ **精细修改**:可调整包头各种参数(TTL、TOS、MARK等) > - 🧩 **全流程介入**:能在5个链(INPUT/OUTPUT/FORWARD/PREROUTING/POSTROUTING)工作 > - ⚖️ **不影响核心**:不修改源/目标地址(那是nat的工作) 好比快递中心给包裹: - 贴"VIP加急"标签(MARK) - 换成防震包装(修改包头属性) - 把大箱子拆成小箱(分片) - 但**绝不更改**收件人地址(那是 NAT 的工作)[^3]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值