Linux Policy Routing

Up ../

Linux Policy Routing

An example to make clear, to me at least. what this involves.

Three networks 10.0.0.0/24, 10.0.7.0/24 and 192.168.99.0/24
The External Router (G) routes between the various 10.0. networks but 
doesn't know about the 192.168.99.0/24 network.
The Local Router (L) has interfaces on the three networks routes between the
10.0.0 and 10.0.7 networks and the 192.168.99.0/24 network.

Host A is multihomed. Host B is on 10.0.0.0/24 only while Host C
is on 192.168.99.0/24 and Host D is on 10.0.7.0/24 only.


                            ?
                            |
                  [ External Router (G) ]
                       |         |
                  10.0.0.254  10.0.7.254
[Host B]               |         |           [Host D]
    |                  |         |               |
10.0.0.23              |         |           10.0.7.59
    |                  |         |               |
  --+----------------+-+-       -+-+-------------+--
    |                |             |
    |                |             |
10.0.0.1          10.0.0.190  10.0.7.190
    |                   |          |
[Host A]            [ Local Router (L) ]
    |                       |
192.168.99.1         192.168.99.254
    |                       |
  --+-----------------------+--------------------+--
                                                 |
                                          192.168.99.5
                                                 |
                                             [Host C]

Routes

Destination    Gateway         Genmask         Flags   MSS Window  irtt Iface
--Local Router(L)
192.168.99.0   0.0.0.0         255.255.255.0   U         0 0          0 eth1
10.0.0.0       0.0.0.0         255.255.255.0   U         0 0          0 eth0
0.0.0.0        10.0.0.254      0.0.0.0         UG        0 0          0 eth0

--Host B
10.0.0.0       0.0.0.0         255.255.255.0   U         0 0          0 eth0
192.168.99.0   10.0.0.190      255.255.255.0   UG        0 0          0 eth0
0.0.0.0        10.0.0.254      0.0.0.0         UG        0 0          0 eth0

--Host C
192.168.99.0   0.0.0.0         255.255.255.0   U         0 0          0 eth0
0.0.0.0        192.168.99.254  0.0.0.0         UG        0 0          0 eth0

--Host A
192.168.99.0   0.0.0.0         255.255.255.0   U         0 0          0 eth1
10.0.0.0       0.0.0.0         255.255.255.0   U         0 0          0 eth0
0.0.0.0        10.0.0.254      0.0.0.0         UG        0 0          0 eth0

--Host D
10.0.7.0       0.0.0.0         255.255.255.0   U         0 0          0 eth0
192.168.99.0   10.0.7.190      255.255.255.0   UG        0 0          0 eth0
0.0.0.0        10.0.7.254      0.0.0.0         UG        0 0          0 eth0

Consider
1. Host C(192.168.99.5) connects to A(10.0.0.1)
   The packet is routed via L(192.168.99.254) then to A,
   the reply is sent directly to C(192.168.99.5) vi eth1

2. Host B(10.0.0.23) connects to A(192.168.99.1)
   The packet is routed via L(10.0.0.190) then to A,
   the reply is sent directly to B vi eth0

So far we have asymetric routing only which will work subject to
host firewall rules.

3. Host D(10.0.7.59) connects to A(192.168.99.1)
   The packed is routed via the L(10.0.7.190) then to A,
   the reply is sent via the external router(G) to D(10.0.7.59)

This usually won't work as G doesn't know about the 192.168.99. network
and will normally drop such packets (anti spoof rules.)

To fix (3) linux has routing rules that can select the next hop based on
the source address.
On Host A
ip rule add from 192.168.99.1 table 200
ip route add table 200 to 10.0.0.0/8 via 192.168.99.254 dev eth1

To fix(1,2)
On Host A
ip rule add from 10.0.0.1 table 210
ip route add table 210 to 192.168.99.0/24 via 10.0.0.190 dev eth0

Actually add the rule names to /etc/iproute2/rt_tables
eg
200	Intern_Extern
210	Extern_Intern

Redhat Linux 5+
In /etc/sysconfig/network-scripts/
	rule-eth0 route-eth0
	rule-eth1 route-eth1

    # rule-eth0
	from 10.0.0.1 table Extern_Intern 
    # route-eth0
	to 192.168.99.0/24 via 10.0.0.190 dev eth0

    # rule-eth1
	from 192.168.99.1 table Intern_Extern
    # route-eth1
	to 10.0.0.0/8 via 192.168.99.254 dev eth1

policy_routing.txt