Linux Policy Routing with ip rule: Multiple Routing Tables - 夜莺博客

Linux Policy Routing with ip rule: Multiple Routing Tables

Standard Linux routing consults one table and sends every packet the same way, but multi-homed hosts and VPN gateways need policy routing: different source addresses, marks or applications take different paths. Linux implements this with ip rule — an ordered list of rules that tells the kernel which routing table to consult for a packet. This guide sets up classic source-based policy routing: a custom table, a rule that selects it, and the routes that fill it.

The Pieces: Tables, Rules, Routes

Linux ships three default tables — local (untouchable), main and default. Routes added without a table name go to main. To use policy routing you need three things: a custom table, rules that point traffic at it, and routes inside it.

Step 1: Create a Custom Routing Table

Tables are numbered 1–255 and can be named in /etc/iproute2/rt_tables (persistent across reboots):

echo 200 custom >> /etc/iproute2/rt_tables

Step 2: Add a Policy Rule

The classic use is source routing — selecting the table by the packet's source address. Route all traffic originating from 192.168.30.200 through the custom table:

ip rule add from 192.168.30.200 lookup custom
ip rule show

Rules are evaluated top-down; ip rule show prints the priority, match criteria and target table. Lower priority numbers run first — the built-in local rule (priority 0) always wins for directly connected addresses, so source-address rules usually sit around priority 32765.

Step 3: Populate the Table with Routes

ip route add default via 192.168.40.1 dev eth1 table custom

Now traffic from 192.168.30.200 follows the custom table (default via eth1), while everything else keeps using the main table. Without the table keyword the route would land in main and the rule would find nothing.

Practical Pattern: Symmetric Replies on a Multi-Homed Host

A common requirement is that replies to packets received on interface A leave through interface A. Create one table per uplink and add rules keyed on the incoming interface's source ranges:

echo 100 isp1 >> /etc/iproute2/rt_tables
echo 200 isp2 >> /etc/iproute2/rt_tables
ip route add default via 203.0.113.1 dev eth0 table isp1
ip route add default via 198.51.100.1 dev eth1 table isp2
ip rule add from 203.0.113.0/24 lookup isp1
ip rule add from 198.51.100.0/24 lookup isp2

For persistent configuration on modern distributions, NetworkManager or systemd-networkd can express the same rules; the raw ip commands above are the ground truth that any tool eventually programs.

Verifying Policy Routing

ip rule show
ip route show table custom
ip route get 8.8.8.8 from 192.168.30.200

ip route get ... from ... is the killer diagnostic — it replays the full rule+table lookup and shows exactly which interface and next hop the kernel would pick. See ss, netstat and tcpdump troubleshooting when reply traffic still goes the wrong way, and compare with Junos behavior in Junos static routes and qualified next hops.

原文链接:https://blog.scottlowe.org/2013/05/29/a-quick-introduction-to-linux-policy-routing/