Asymmetric routing

I’ve been working on a OpenVPN deployment that is working with asymmetric routing. I think it is working with a sub-optimal solution. First, let me show how it is deployed and what is bothering me.

Big picture

Big picture
So, lets check the path of a packet going from client A to client B.

Order IP Description
1 10.1.0.92 client site A
2 10.1.0.254 default gw site A
3 10.1.0.45 openvpn gw site A
4 172.16.1.1 wan openvpn site A
5 172.16.1.58 wan openvpn site B
6 10.1.8.254 default gateway site B
7 10.1.8.2 client site B

But when the packet comes from client B to client A the path is a bit different.

Order IP Description
1 10.1.8.2 client site B
2 10.1.8.254 default gateway site B
3 172.16.1.2 wan openvpn site B
4 172.16.1.58 wan openvpn site A
5 10.1.0.45 openvpn gw site A
6 10.1.0.92 client site A

Pay attention that the packet is not going through 10.1.0.254 (default gw site A). So the path is asymmetric.

The problem

As the packet does not go through 10.1.0.254 (default gw site A) in both ways, the firewall is unable to track the connection state and it starts to reject packets from that connection. Let’s take one example of client A trying to connect to client B.

client A -> client B – SYN packet
(this packet is forwarded by firewall in default gw site A)

client B -> client A – SYN/ACK packet
(this packet is delivered to client A without going through default gw site A)

client A -> client B – ACK packet
(this packet is reject by default gw site A)

Alternative #1 – ICMP redirect

As soon as the 10.1.0.254 (default gw site A) detects the next hop is in the same network as the sender, 10.1.0.92 (client site A), it should send an ICMP redirect instructing the client to send packets directly to 10.1.0.45 (openvpn gw site A). In this way you get the optimal path in both ways.

If your router is a linux box remember to enable it to send ICMP redirects by changing yours sysctl.conf

1
net.ipv4.conf.all.send_redirects = 1

Unfortunately, routes created by ICMP redirects are short lived in Windows clients, and when this route gets expired a packet is sent to 10.1.0.254 in the middle of a TCP connection, witch wasn’t tracked, so it rejects the packet and the connection is dropped.

Alternative #2 – ICMP redirect + Stateless firewall

To get alternative #1 fixed you just need to make rules stateless in the firewall (aka don’t use switches -m state –state NEW in iptables). So when the ICMP redirect route gets expired the host will send the packet to it’s default gateway and will receive another ICMP redirect instead of an ICMP port unreachable.

Alternative #3 – Use DHCP to push routes

If all your clients are working with DHCP and both client and servers supports RFC3442 it is a very good alternative. It will make clients always use the best route using the right gateway.

You can check how to configure it ISC-DHCP server here.
You can check how to configure it Microsoft DHCP server here.

If you have a mixed network with DHCP clients and static clients this alternative can be a problem since you won’t get the all routes delivered to all hosts, also I had problems with some SIP phones that doesn’t support RFC3442.

Remember that you can still use both this alternative with alternatives #1 and #2 at same time.

Alternative #4 – Source routing

If you decide that you would like to get the packets going through both gateways to get a symmetric routing you can use this alternative.
Check out LARTC how-to to get more info.

Alternative #5 – Transfer network

This last altervative involves using new network to get packets transferred between networks.
To achieve this you should create a new VLAN to connect the hosts:

  • 10.1.0.254 (default gw site A)
  • 10.1.0.45 (openvpn gw site A)

If you like to use just one NIC in 10.1.0.254 (default gw site A) you can make use of IEEE 802.1q, but your switch must support it.
If you have a spare NIC in 10.1.0.254 (default gw site A) you can just configure the new network using this NIC.

After you get the transfer network configured on 10.1.0.254 (default gw site A), you just need to route the packets addressed to VPN to go through this transfer network. Do the same on your VPN box to the packets addressed to your LAN.
Since they are in separated networks no ICMP redirect will occur.

References

#1 icmp-redirects-are-bad
#2 rfc3442