本文深入探讨 Linux 系统中强大的 `ip rule` 命令,解释其在策略路由中的核心作用。从传统路由的局限性出发,详细讲解 `ip rule` 的参数、如何与多路由表协同工作,并通过多出口链路绑定和基于 `fwmark` 的应用流量分流等实际案例,展示其在复杂网络环境中的巨大潜力,助你掌握 Linux 高级网络配置的核心技能。
引言:告别传统路由的束缚
在复杂的网络环境中,单一的基于目的地的路由策略往往显得力不不心。当我们需要根据源IP、应用程序、服务端口甚至数据包标记来决定流量走向时,Linux 的 ip rule 命令就如同瑞士军刀般闪耀登场。它为我们打开了策略路由(Policy Routing)的大门,让网络管理变得前所未有的灵活与强大。
本文将深入探讨 ip rule 的核心概念、工作原理及其在各种复杂场景下的应用,助你驾驭 Linux 的高级路由功能。
传统路由的局限与策略路由的崛起
在没有 ip rule 的世界里,Linux 路由表主要依赖目的 IP 地址来转发数据包。这意味着所有发往同一目的地的流量都将遵循相同的路径。然而,在以下场景中,这种模式捉襟见肘:
- 一台服务器拥有多个公网 IP,每个 IP 对应不同的出口链路。如何确保从特定源 IP 发出的流量从对应的出口离开?
- 某些特定应用(如 VPN 客户端)的流量需要通过加密隧道,而其他普通流量则直连互联网。
- 根据数据包的 TOS (Type of Service) 或 Firewall Mark (fwmark) 来划分优先级或走向。
策略路由(Policy Routing)正是为了解决这些问题而生。它允许我们定义一套规则,这些规则可以根据数据包的更多属性(如源 IP、接口、FW mark 等)来决定使用哪个路由表进行查找,从而实现更加精细和灵活的流量控制。
ip rule 命令详解:构建你的路由策略
ip rule 命令是管理 Linux 策略路由规则的核心工具。它的基本语法和工作机制如下:
规则的结构与优先级
每条 ip rule 规则都包含一个优先级(priority)和一组匹配条件(selector),以及一个或多个动作(action)。系统会按照优先级从低到高(数字越小优先级越高)的顺序逐条匹配规则,一旦匹配成功,就执行相应的动作并停止查找。
ip rule add [SELECTOR] action [ACTION] [table TABLE_ID] [priority PRIORITY]关键参数解析
priority PRIORITY:规则的优先级。数字越小,优先级越高。默认规则的优先级通常在 0 (local) 和 32766 (main) 之间。你可以为自定义规则选择一个合适的优先级。from SOURCE_IP[/MASK]:匹配源 IP 地址。to DEST_IP[/MASK]:匹配目的 IP 地址。iif INTERFACE:匹配入站接口。oif INTERFACE:匹配出站接口。fwmark MARK[/MASK]:匹配由iptables设置的防火墙标记。这是策略路由中最强大的匹配条件之一,可以将应用层或传输层的特征映射到网络层。uidrange START-END:匹配发起连接的用户 ID 范围。lookup TABLE_ID:当规则匹配成功时,指定使用哪个路由表进行查找。这是最常用的动作。prohibit:拒绝匹配的数据包,并发送 ICMP "Communication administratively prohibited" 错误。blackhole:默默地丢弃匹配的数据包,不发送任何错误信息。unreachable:拒绝匹配的数据包,并发送 ICMP "Destination Host Unreachable" 错误。
要查看当前系统中的所有策略路由规则,只需运行:
ip rule show路由表:策略路由的基石
除了默认的 main 路由表之外,Linux 内核还支持多个路由表。这些路由表在 /etc/iproute2/rt_tables 文件中定义。常见的表包括:
0 (unspec):未指定表。255 (local):存放本地路由,如本地 IP 地址、广播地址等,优先级最高。254 (main):默认路由表,存放所有非本地、非特殊路由。大多数用户配置的路由都在此表。253 (default):保留表,用于特殊的默认路由。- 以及用户自定义的表,通常 ID 大于 1。
ip rule 的核心就是根据匹配条件,将流量导向特定的路由表进行路由查找。
实战场景:ip rule 的魔法
场景一:多出口链路的源 IP 绑定
假设你的服务器有两块网卡 eth0 (IP: 192.168.1.100, 网关: 192.168.1.1) 和 eth1 (IP: 10.0.0.100, 网关: 10.0.0.1)。你希望从 192.168.1.100 发出的流量走 192.168.1.1 网关,从 10.0.0.100 发出的流量走 10.0.0.1 网关。
# 定义新的路由表
echo "100 isp1" >> /etc/iproute2/rt_tables
echo "101 isp2" >> /etc/iproute2/rt_tables
# 为 isp1 表添加路由
ip route add default via 192.168.1.1 dev eth0 table isp1
# 为 isp2 表添加路由
ip route add default via 10.0.0.1 dev eth1 table isp2
# 添加策略路由规则:源 IP 192.168.1.100 的流量查找 isp1 表
ip rule add from 192.168.1.100 table isp1 priority 10
# 添加策略路由规则:源 IP 10.0.0.100 的流量查找 isp2 表
ip rule add from 10.0.0.100 table isp2 priority 20场景二:基于应用的流量分流(通过 fwmark)
假设你有一个 VPN 客户端,你希望它的流量通过 VPN 隧道,而其他所有流量直连。你可以通过 iptables 为 VPN 客户端的流量打上标记,然后 ip rule 根据这个标记进行路由。
# 定义 VPN 路由表
echo "200 vpn_table" >> /etc/iproute2/rt_tables
# 假设 VPN 隧道接口为 tun0,VPN 网关为 10.8.0.1
# 为 vpn_table 添加路由
ip route add default via 10.8.0.1 dev tun0 table vpn_table
# 使用 iptables 为特定用户(或进程)的流量打上 fwmark 10
# 这里以 UID 为例,实际中可以根据端口、目标IP等更复杂条件
iptables -t mangle -A OUTPUT -m owner --uid-owner 1000 -j MARK --set-mark 10
# 添加策略路由规则:fwmark 10 的流量查找 vpn_table
ip rule add fwmark 10 table vpn_table priority 50这样,用户 ID 为 1000 的所有出站流量都会被标记为 10,然后根据 ip rule 规则,查找 vpn_table 并通过 VPN 隧道转发。
高级考量与持久化
- 持久化配置:
ip rule和ip route table命令在重启后会失效。- 在基于 Debian/Ubuntu 的系统上,可以使用
/etc/network/interfaces或/etc/netplan/*.yaml配置。 - 在基于 RHEL/CentOS 的系统上,可以编辑
/etc/sysconfig/network-scripts/route-<interface>和rule-<interface>文件,或使用 NetworkManager。 - 最通用的方法是编写启动脚本(例如放入
/etc/rc.local或 systemd service unit)。
- 在基于 Debian/Ubuntu 的系统上,可以使用
- 调试技巧: 使用
ip rule show和ip route show table <TABLE_ID>来检查规则和路由表。使用tcpdump结合iptables LOG规则可以帮助你追踪数据包的转发路径和标记。 - 规则顺序: 仔细规划规则的优先级。一个宽松的规则放在高优先级可能会意外匹配并覆盖更具体的规则。
总结
ip rule 是 Linux 网络管理中一个极其强大且灵活的工具。通过理解策略路由的原理,并结合 ip route 和 iptables 的使用,你可以实现对网络流量的精细化控制,满足几乎所有复杂的路由需求,从简单的多出口负载均衡到高级的基于应用的安全隔离。掌握它,你就掌握了 Linux 高级网络配置的核心秘密。