The VPN routing problem

March 27, 2007

An end node machine connecting in through a VPN has two IP addresses; one IP address that is inside the VPN (call it I), and its normal IP address outside the VPN (call it O). The outside address is sometimes called the wild side address, because it is accessibly by the wild Internet.

A lot of writing about VPNs assumes that I and O are disjoint from each other, effectively on completely isolated networks; I talks to the corporate network behind the VPN and only the corporate network, and O talks only to the Internet and never to the corporate network (and vice versa; machines inside the corporate network never talk directly to O). This assumption makes routing possible and even simple: routes to the corporate network are established that point to the VPN, and the machine's default route remains going out its usual connection.

The problems with this come in if we violate the isolation assumptions; you wind up with asymmetric routing. If the corporate network tries to talk directly to O, the return packets will try to flow back over the VPN, which may or may not work. If the outside world tries to talk to I, the inside address, the return packets will try to flow back out over the end machine's regular Internet connection, which almost certainly won't work.

The core issue is that the machine really has two identities, the inside one and the outside one, and these identities need different routing. The inside identity should route everything over the VPN; the outside identity should route everything over the regular Internet connection.

Normal routing tables have no concept of separate identities; they pick where to send a packet based purely on what its destination address is. So things only completely work out when the routes for the two identities are completely distinct anyways: when the corporate network behind the VPN is in address space that's not reachable from the Internet.

(It can be publicly assigned and even nominally routed; the important thing is that a machine on the corporate network can't make a direct connection to O and a machine on the Internet can't make a direct connection to I.)

In this case, we can use the local IP address that a packet is coming from as a proxy for which identity of the machine sent it, and thus which connection it should go out over. If it comes from I, send it out over the VPN; if it comes from O, send it out over the regular connection.

This sort of routing goes by the general name of 'policy based routing', and is unfortunately a very complicated field with no standardization between systems. For example, Linux can do a certain amount of it purely with routing magic, while at least some other systems put it in the hands of IP filtering systems.

(This problem doesn't come up with a pure IPSec VPN implementation, because the IPSec specification essentially requires you to have a second routing layer that can match on the source as well as the destination IP address of packets.)

Written on 27 March 2007.
« Some problems with iSCSI on Solaris 10 (on x86)
Dual identity routing with Linux's policy based routing »

Page tools: View Source, Add Comment.
Login: Password:
Atom Syndication: Recent Comments.

Last modified: Tue Mar 27 22:38:36 2007
This dinky wiki is brought to you by the Insane Hackers Guild, Python sub-branch.