linux策略路由核心是iptables打mark标记,结合ip rule与自定义路由表实现精细控制;需用connmark保障连接双向一致性,禁用rp_filter避免回包丢弃,并通过计数、规则、路由表及抓包四步验证。

Linux 防火墙本身不直接做路由决策,但通过 iptables(或 nftables)在 mangle 表中打标记(MARK),再配合 ip rule + 自定义路由表,就能实现基于应用、协议、连接状态等维度的精细路由控制——这才是真正灵活的策略路由核心路径。
为什么非要用 MARK?
单纯靠源/目的 IP 做策略路由,在现代网络中很快会失效:容器 IP 动态分配、服务端口复用、连接复用(如 HTTP/2)、跨网段回包路径不一致等问题,都要求路由决策能“记住”流量的上下文。MARK 就是这个上下文的轻量载体,它被内核全程携带(从 PREROUTING 到 OUTPUT),且可被 conntrack 关联,让整条连接(包括 ICMP 错误、ACK、FIN 等)走同一路径。
关键配置四步走
以双出口服务器为例(eth0 接电信,eth1 接联通),目标:所有访问 80/443 的流量走 eth0;数据库 3306 流量走 eth1;并确保响应包原路返回:
- 用 iptables 在 PREROUTING 和 OUTPUT 链统一打标:
iptables -t mangle -A PREROUTING -p tcp --dport 80 -j MARK --set-mark 1iptables -t mangle -A PREROUTING -p tcp --dport 443 -j MARK --set-mark 1iptables -t mangle -A PREROUTING -p tcp --dport 3306 -j MARK --set-mark 2 - 为已建立连接自动继承标记(避免响应包丢失):
iptables -t mangle -A PREROUTING -m conntrack --ctstate ESTABLISHED,RELATED -j CONNMARK --restore-markiptables -t mangle -A OUTPUT -m conntrack --ctstate ESTABLISHED,RELATED -j CONNMARK --restore-mark - 创建两个路由表并填入对应默认网关:
编辑/etc/iproute2/rt_tables,添加:100 tab_telcom200 tab_unicom
然后执行:ip route add default via 192.168.1.1 dev eth0 table tab_telcomip route add default via 10.0.2.1 dev eth1 table tab_unicom - 绑定标记与路由表:
ip rule add fwmark 1 table tab_telcomip rule add fwmark 2 table tab_unicom
必须关闭反向路径过滤
Linux 默认开启 rp_filter(反向路径检查),它会丢弃“入接口与路由表查出的出接口不一致”的包——这恰恰是策略路由的常态。需对每个相关网卡禁用:
echo 0 > /proc/sys/net/ipv4/conf/eth0/rp_filterecho 0 > /proc/sys/net/ipv4/conf/eth1/rp_filter- 写入
/etc/sysctl.conf持久化:net.ipv4.conf.eth0.rp_filter = 0net.ipv4.conf.eth1.rp_filter = 0
验证与排障要点
MARK 路由容易“看似生效实则静默失败”,验证不能只看规则是否存在:
- 确认标记是否真实打上:
iptables -t mangle -L -v | grep MARK查看匹配计数 - 确认规则是否命中:
ip rule show看优先级和 fwmark 是否正确 - 确认路由表内容:
ip route show table tab_telcom - 抓包验证路径:
tcpdump -i eth0 port 80 & tcpdump -i eth1 port 3306对比实际出口











