Routing it Your Way Part 3: Socat for OpenVPN Forwarding

O.k., I’m going deeper and deeper down the layer 7 routing rabbit hole. As I like to have a plan B when it comes to my infrastructure at home, I have backup Internet connectivity over a separate Internet connection and a separate router. When main connectivity fails, a script detects that my services are no longer reachable. It then changes the DynDNS entries of all domains I use at home to point to the IP address of the backup connectivity. So far, so good.

But here is the catch: Backup connectivity is routed through a VM on the Internet that terminates ssh reverse port mapping tunnels from my VMs at home. These tunnels do not use the main Internet link so they don’t break when connectivity is lost. Instead, the VMs at home have an entry in the routing table for the IP address of the cloud VM that points to the backup connectivity router. This works great but has one major shortcoming: ssh can only tunnel TCP ports. Unfortunately, OpenVPN and similar products use UDP as transport protocol, and hence, ssh tunneling doesn’t work. But there’s another way!

The solution to the problem is not to use ssh tunnels from the inside of the network to the cloud VM, but to make the cloud VM forward UDP packets to the public IP address assigned to the router of my secondary Internet connectivity. As described in previous posts in this series, ‘socat’ is the tool to do this, and the command for UDP forwarding on the cloud VM looks as follows:

sudo nohup socat UDP-LISTEN:1194,fork,reuseaddr UDP:IP-ADDRESS-OF-HOME-ROUTER:1194 &

On the OpenVPN router, an entry in the routing table is required, so response packets will not be routed via the default gateway but via the backup connectivity router. In my case is the default gateway, while is the backup router. Adding the special route for just that IP address looks as follows:

route add CLOUD-VM-IP gw

This begs of course the question why I don’t set the DNS entry for my OpenVPN server to the IP address of the secondary Internet router? In my case, I use a cellular Internet connection for backup connectivity. And while I can get a public rather than a private IP via a special APN, it is not reachable from other devices in the same mobile network. That’s kind of a showstopper. Other people might sit behind a dual-stack lite IPv4v6 connection and only get a public IPv6 address. If their home router allows IPv6 forwarding, then they can probably use this method to make their OpenVPN server available with a public IP address (of the cloud VM) available as well, despite only having an IPv6 address.

And that’s it, two commands are all it takes to get UDP port forwarding over a backup link!