OpenVPN – How to Route Subnet Through a VPN Gateway

openvpnroutingvpn

A small company I work at is getting rid of an office soon and it has fallen onto me to migrate the currently
on-prem-hosted VPN (just a Zyxel Zywall 110 device) into a cloud-based VM. I am not that experienced in networking (backend-dev-turned-ops)
so I would like to validate if the following approach will work.


I have a dedicated VM where I've set up OpenVPN Access Server and the basics are working well, people can connect,
all good.

There is one catch though, the current VPN forwards a certain IP range through a "tunnel" into a partner company's internal network.
It looks like this:

if dest_addr in '172.30.239.0/25':
    route through gw 194.xxx.xxx.xxx
else:
    route through gw 0.0.0.0

As an example, when connected to the VPN, my traffic would be routed as such:

dest 1.2.3.4       => me -> VPN server -> its internet gateway -*-> 1.2.3.4
dest 172.30.239.10 => me -> VPN server -> partner network gateway (194.xxx.xxx.xxx) -(internal network routing)-> 172.30.239.10

Where the connection from our router to the partner company's VPN GW is done via IKEv1 with pre-shared key (judging from the router's web UI, as that's all the "documentation" I have).

Some ascii art depicting the setup below. I am replacing Router with a VM.

            +-----------------+           [     Partner infra, this has to stay the same     ]
            | Router          |           194.xxx.xxx.xxx            e.g. 172.30.239.75
            | --------------- |   IKEv1   +-------------+       +-------------------------+
User -----> | 172.30.239.0/25-| --------> | VPN gateway |-----> | Internal network server |
            |     default     |           +-------------+       +-------------------------+
            |        |        |
            +--------+--------+
                     |
                     |
                 internet

The OpenVPN Access Server does not support anything like this by itself (or I haven't been able to find that config), so I thought I could do it on the VM level.
If I connect the OS to the VPN gateway with something like Strongswan and configure appropriate routing in iptables, could
this work? Would the traffic of users connected to the OpenVPN server going to the 172.30.239.0/25 range get routed
through to the Strongswan's connection, or is this approach fundamentally wrong? What are my options?

Thanks!

Best Answer

Things are a little bit clearer now. Of course OpenVPN has an option for your problem: If you want that the VPN client routes traffic for the network 1.2.3.0/25 through your VPN tunnel, use the option push (source) :

--push option
    Push a config file option back to the client for remote execution. Note that
 option must be enclosed in double quotes (""). The client must specify --pull in
 its config file. The set of options which can be pushed is limited by both
 feasibility and security. Some options such as those which would execute scripts
 are banned, since they would effectively allow a compromised server to execute
 arbitrary code on the client. Other options such as TLS or MTU parameters cannot
 be pushed because the client needs to know them before the connection to the
 server can be initiated. 

So, you have to add in your openvpn server configuration

push "route 1.2.3.0 255.255.255.128"

This tells the openvpn client, that it should route all traffic going to that subnet through the vpn tunnel. And, of course, on the server itself, the correct route must be in place, too - But I guess this route is probably already in place.

[UPDATE]
My answer is missing some basic information about routing. Any network device can act as a gateway - this is what home routers do. Routing is not done with iptables - that is a tool to modify the linux built-in kernel firewall. A routing decision is done with the help of the routing table (I will talk only about IPv4 here for briefity). For every IP packet which is being sent, the routing table is taken into account, starting with host-only routes ( /32 subnet), taking the most "precise" route it can find. So, the default route ( /0 subnet ) is taken only, if no matching route with a more "precise" subnet is being found.

Routing all traffic through the VPN tunnel is easy. OpenVPN uses the redirect-gateway directive for that. So either, you put that directive into all client configurations, or you put a

push "redirect-gateway def1"

into your server config. With the option def1, two routes with 128.0.0.0 subnets is being used instead of one 0.0.0.0 subnet route - which is being done to avoid that the new default route is being overwritten by the DHCP client.

Coming to the routes on your server. As the server is the endpoint of an IPSec tunnel (going to your partner), the software (strongswan?) already installed the necessary routes on that server, such that the traffic for the remote networks is being routed through the IPSec tunnel.

Let me draw a picture with example networks and routes for a better understanding. Think of the following network:

A ---------- B -------- C --------- D
  • A is a OpenVPN client with ip 10.8.0.2
  • B is the OpenVPN server with IP 10.8.0.1 and 172.16.0.1
  • C is the remote IPSec endpoint inside your partner's network with the IP 172.16.0.2 and 192.168.0.1
  • D is a network device inside the partner's network with the IP 192.168.0.10

in this example setup, you have three networks:

  • the OpenVPN network
  • the IPSec network
  • the partner network

Device A has the route: 0.0.0.0/0 gw 10.8.0.1
Server B has two routes: one default gateway going to the ISP, and: 192.168.0.0/24 gw 172.16.0.2
Server C has two routes: one default gateway going to the partner's ISP, and: 10.8.0.0/24 gw 172.16.0.1
For Device D, only the default route 0.0.0.0/0 gw 192.168.0.1 is required.

Related Topic