OpenVPN Chaining

Solution 1:

I found the solution to this. There is no need to have multiple/redundant VPN connections in the way that Answer #1 describes. Nor do I think it would have done anything to solve my problem, as much as I appreciated the feedback.

The problem is due to the fact that an OpenVPN server will only accept IP traffic through the tunnel of the connected client, if the source IP address matches what the server assigned the client when the tunnel was established. Traffic originating from any other source IP address going through the tunnel will be completely ignored by the server.

Take a look at the following:

10.2.1.15     10.2.0.1/123.123.123.1                                     124.124.124.1/10.1.0.1    10.1.1.20
  (eth0)                   (eth0/eth1)                                                        (eth0/eth1)              (eth0)
----------                   -------------                                                         ------------              ----------
| Host A |-------------| Gateway 1 |------------------------------------------| Gateway 2 |--------| Host B |
----------                   --------------               {INTERNET}                    ----------------          -----------
                              VPN CLIENT                                                     VPN SERVER
                              172.16.1.12                                                        172.16.2.1
                                   (tun0)                                                                (tun0)

So in this example, "Gateway 1" is the VPN client establishing a tunnel to "Gateway 2" as the VPN server. What we want to accomplish is the ability for Host A to communicate with Host B through the VPN. So we set up a standard OpenVPN connection, with Gateway 1 as a client to the Gateway 2 server. Each gateway has a "public" and "private" interface. One for the private network, and one for the public Internet. When the VPN connection is established, each server is using an additional "tun0" interface. Gateway 2, acting as the VPN Server, accecpts the connection from Gateway 1, and assigns it an IP of 172.16.1.12.

The problem, is that Gateway 2 will only accept traffic through that VPN tunnel if the source IP is 172.16.1.12.

That works fine when Gateway 1 wants to connect to Host B, but it is a problem when Host A tries to connect to Host B. When Host A tries to connect, Gateway 1 acts as a router and routes the traffic correctly through the VPN tunnel over to Gateway 2 (assuming you have your routes set up correctly). If you run tcpdump on the tun0 device of Gateway 1, you will even see the traffic from Host A going through the tunnel, destined for the other network. But Gateway 2 sees the source IP address as 10.2.1.15 which does not match the IP address that it assigned for the connection, and completely ignores it.

So the solution is to configure Gateway 2 to accept traffic from the 10.2.0.0/16 network through the VPN tunnel. The VPN Server needs to be configured with an iroute setting. The procedure for setting this up and all of the configuration parameters are explained on the official OpenVPN website here so I will not re-explain it in this post.

I suggest that when you read this documentation, take special note that you need to use client-config dirs (CCD) in your OpenVPN configuration in order to use iroute. Make sure you read that part of the documentation carefully. You will also, of course, need to set up routes on all of your gateways, so they know how to route the traffic through the VPN tunnel. Referencing the diagram above, you would still need to add a route on Gateway 2 like this:

route add -net 10.2.0.0 netmask 255.255.0.0 gw 172.16.1.12 tun0

and on Gateway 1 like this:

route add -net 10.1.0.0 netmask 255.255.0.0 gw 172.16.2.1 tun0

In order for the traffic from the Host B to properly route through the VPN when trying to connect to Host A.

In my particular case, Gateway 1 is acting both as a client to Gateway 2, but also as a server to other clients connecting from the Internet that need access to Host A. So I needed to create two interfaces, tun0 and tun1, so that one could be used for the client connection to the other network, and the other could be used as a server for road-warriors connecting in. I also need to add additional routes, so that I can make a VPN connection to Gateway 1 (server) from the internet, and I'm able to route traffic to Host B on the other network.

I hope this helps others who are confused about this.

Solution 2:

I recently set this up. The magic I needed was to add correct route commands in the openvpn.confs.

My config is even a bit more complex than yours. I have three sites, that happen to be EC2 regions: us-east-1 (VA), us-west-1 (CA), and us-west-2 (OR). Each has its own private IP range as follows:

VA 10.1.0.0/16
CA 10.0.0.0/16
OR 10.10.0.0/16

The configuration is OR <=> CA <=> VA, with CA forming a central "hub."

host vavpn

config va-to-ca.conf

# Sample OpenVPN configuration file using a pre-shared static key
# Port to use: 1194 is the official IANA port number
port 1194

# Use a dynamic tun device.
dev tun

# Remote peer and network
remote 54.241.174.228
route 10.0.0.0 255.255.0.0
route 10.10.0.0 255.255.0.0

# Configure local and remote VPN endpoints
ifconfig 169.254.255.1 169.254.255.2

# The pre-shared static key
secret ovpn.key

# keepalive
keepalive 10 120

host cavpn

config ca-to-va.conf

# Sample OpenVPN configuration file using a pre-shared static key
# Port to use: 1194 is the official IANA port number
port 1195

# Use a dynamic tun device.
dev tun

# Remote peer and network
remote 54.244.21.223
route 10.10.0.0 255.255.0.0

# Configure local and remote VPN endpoints
ifconfig 169.254.255.3 169.254.255.4

# The pre-shared static key
secret ovpn.key

# keepalive
keepalive 10 120

config ca-to-or.conf

# Sample OpenVPN configuration file using a pre-shared static key
# Port to use: 1194 is the official IANA port number
port 1194

# Use a dynamic tun device.
dev tun

# Remote peer and network
remote 54.236.173.50
route 10.1.0.0 255.255.0.0

# Configure local and remote VPN endpoints
ifconfig 169.254.255.2 169.254.255.1

# The pre-shared static key
secret ovpn.key

# keepalive
keepalive 10 120

host orvpn

config or-to-ca.conf

# Sample OpenVPN configuration file using a pre-shared static key
# Port to use: 1194 is the official IANA port number
port 1195

# Use a dynamic tun device.
dev tun

# Remote peer and network
remote 54.241.174.228
route 10.0.0.0 255.255.0.0
route 10.1.0.0 255.255.0.0

# Configure local and remote VPN endpoints
ifconfig 169.254.255.4 169.254.255.3

# The pre-shared static key
secret ovpn.key

# keepalive
keepalive 10 120

Note well the route commands that go to the other endpoint. I think if you layout your network and all the IPs at either endpoint, you'll quickly be able to modify my example to your topology.