Posted in Networking Security VPN
Routed OpenVPN between two subnets behind NAT gateways
Edit : between two or MORE subnets. Check out the exchange between Michael Antal and me in the comments. He’s been able to interconnect 3 subnets using this method and some slight tweaks in routes.
The following is the configuration needed to create a routed OpenVPN network between two remote subnets, both behind NAT gateways. On each side, the gateways will act as the VPN gateways.
Network subnets on both side must be different. In this example, we connect 192.168.1.0/24 to 192.168.200.0/24.
With this setup, we don’t even need to open ports at the NAT level on either side of the VPN.
Network configuration
Network A :
Subnet : 192.168.1.0/24
Gateway for Network A
VPN interface (tun0) : 10.0.0.1
Eth0 : 192.168.1.254
Eth1 / Public IP : 212.x.x.x (machineA.example.org)
Network B :
Subnet : 192.168.200.0/24
Gateway for Network B
VPN interface (tun0) : 10.0.0.2
Eth0 / Public IP : 66.x.x.x (machineB.example.org)
Eth1 : 192.168.200.254
If we imagine forwarding is rejected at the firewall level on machine B, we would need to allow traffic between the tun device created by OpenVPN and the LAN interface, as root you would then type :
iptables -I FORWARD -i tun0 -o eth1 -j ACCEPT
iptables -I FORWARD -i eth1 -o tun0 -j ACCEPT
Make sure the rules remain applied across reboots (using iptables-save or storing the rules in /etc/rc.local or else)
Enabling IP routing :
We need to enable routing on both VPN gateways..
echo “1″ > /proc/sys/net/ipv4/ip_forward
Using this method, routing is not persistent across reboots, check the following link :
http://www.wains.be/index.php/2006/06/06/enable-ip-forward-under-rhelcentos/ (which works for Debian as well)
Static key generation :
We will use simple static key for our example…
openvpn --genkey --secret /etc/openvpn/vpn.key
Share the key between the VPN gateways over a secure channel (scp, etc.).
If you want to use certificates instead (which I recommend), check out : http://www.wains.be/index.php/2008/07/15/a-vpn-for-remote-users-with-openvpn/
OpenVPN configuration :
machine A : /etc/openvpn/vpn.conf
remote machineB.example.org
float
port 8000
dev tun
ifconfig 10.0.0.1 10.0.0.2
persist-tun
persist-local-ip
persist-remote-ip
comp-lzo
ping 15
secret /etc/openvpn/vpn.key
route 192.168.200.0 255.255.255.0
chroot /var/empty
user nobody
group nogroup
# If using RedHat replace with
# group nobody
log vpn.log
verb 1
machine B : /etc/openvpn/vpn.conf
remote machineA.example.org
float
port 8000
dev tun
ifconfig 10.0.0.2 10.0.0.1
persist-tun
persist-local-ip
persist-remote-ip
comp-lzo
ping 15
secret /etc/openvpn/vpn.key
route 192.168.1.0 255.255.255.0
chroot /var/empty
user nobody
group nogroup
# If using RedHat replace with
# group nobody
log vpn.log
verb 1
Establishing the connection :
On machine A type :
openvpn --config /etc/openvpn/vpn.conf
Machine A will try to establish the connection. Type the same command on machine B to initialize the connection.
As soon as the connection is up, hosts on network A should be able to ping hosts on network B and vice-versa. If you can’t ping from one side to the other, it’s probably a routing issue.
We can use traceroute from a machine on network A to see the path taken to reach a host on network B :
$ traceroute 192.168.200.30
traceroute to 192.168.200.30 (192.168.200.30), 30 hops max, 40 byte packets
1 192.168.1.254 (192.168.1.254) 2.128 ms 2.378 ms 2.781 ms
2 10.0.0.2 (10.0.0.2) 132.761 ms 137.342 ms 141.130 ms
3 192.168.200.30 (192.168.200.30) 136.752 ms 133.869 ms 135.960 ms
We can see the traffic is going through the 10.0.0.2 interface.
We also can check the routing table on the VPN gateway on network A :
# route -n
Kernel IP routing table
Destination Gateway Genmask Flags Metric Ref Use Iface
10.0.0.2 0.0.0.0 255.255.255.255 UH 0 0 0 tun0
192.168.1.0 0.0.0.0 255.255.255.0 U 0 0 0 eth0
192.168.200.0 10.0.0.2 255.255.255.0 UG 0 0 0 tun0
0.0.0.0 212.x.x.x 0.0.0.0 UG 0 0 0 eth1
We see any traffic directed to 192.168.200.0/255.255.255.0 must go through interface 10.0.0.2 on device tun0.
Making sure the VPN connection is established at boot (Debian way) :
Edit /etc/defaults/openvpn and specify which VPN network must be started.
Make OpenVPN starts at boot with this command :
update-rc.d openvpn defaults
OpenVPN will start any VPN configuration named *.conf found in /etc/openvpn/
So don’t store copies of config like test.conf test-backup.conf as OpenVPN will try to start them at boot.
Comments
Sébastien Wains » OpenVPN : routing all traffic through the VPN tunnel
[...] Setting up a VPN between two sites : http://www.wains.be/index.php/2008/06/07/routed-openvpn-between-two-subnets-behind-nat-gateways/ [...]
Sébastien Wains » Tunneling UDP through SSH
[...] Say you need to forward UDP packets between two remote networks securely. E.g : dns queries from your home machine to your dns servers at work. You should use a VPN between the networks in order to do so (see : http://www.wains.be/index.php/2008/06/07/routed-openvpn-between-two-subnets-behind-nat-gateways/ [...]
Michael Antal
Hi there Sébastien!
Any thoughts on how this method could be extrapolated to three or even more subnets? Btw: I connected two subnets with this method flawlessly! Thank you for the great howto!
Best of luck,
Michael
Sébastien Wains
Hey Michael,
Thanks
If you want to interconnect 3 or more remote sites.. just make one site the central “hub” that would store the routes to every remote sites. Let’s call that hub site “A”.
Site A : 192.168.0.0/24
Site B : 192.168.1.0/24
Site C : 192.168.2.0/24
VPN 1 : A (on tun0) to B (on tun0) with 10.0.0.0/24
VPN 2 : A (on tun1) to C (on tun0) with 10.0.1.0/24
If B wants to connect to C, just set the route on the gateway at site B to point to the tunnel to site A. Like this :
192.168.2.0 10.0.0.2 255.255.255.0 UG 0 0 0 tun0
Gateway A would receive the packets and redirect them through the VPN tunnel to site C, since it has the following route :
192.168.2.0 10.0.1.2 255.255.255.0 UG 0 0 0 tun1
Of course, gateway C must know how to send packets back to site B with the following route :
192.168.1.0 10.0.1.5 255.255.255.0 UG 0 0 0 tun0
Michael Antal
Thanks for the quick answer Sébastien!
I’ve set up the way you said:
There is two communication between (A central hub with 2 vpn interfaces)
A B
A C
But I cannot get B -> C nor C -> B connections going.
The routing tables look fine I guess :
A(192.168.0.1):
192.168.4.0 10.0.1.2 255.255.255.0 UG 0 0 0 tun0
192.168.1.0 10.0.0.2 255.255.255.0 UG 0 0 0 tun1
B(192.168.4.1):
192.168.1.0 10.0.1.1 255.255.255.0 UG 0 0 0 tun0
192.168.0.0 10.0.1.1 255.255.255.0 UG 0 0 0 tun0
C(192.168.1.1):
192.168.4.0 10.0.0.1 255.255.255.0 UG 0 0 0 tun0
192.168.0.0 10.0.0.1 255.255.255.0 UG 0 0 0 tun0
Thank you again for your time,
Michael
Michael Antal
Correction for the last comment:
There is two-WAY communication between (A central hub with 2 vpn interfaces):
A B
A C
Sébastien Wains
Have you tried running tcpdump on the “hub” while trying to ping from B to C or reverse ?
Please try and see what happens.
Michael Antal
Yes I’ve tried it. And thank you for the tip because that solved the problem. It turns out that I had to include another route in B and C’s routing table that is: I had to route the OTHER VPN subnet through the local VPN interface as well:
On B (192.168.4.1, VPN tun0 inet addr:10.0.1.2 P-t-P:10.0.1.1)
The extra routing is:
10.0.0.0 10.0.1.1 255.255.255.0 UG 0 0 0 tun1
Where 10.0.0.0/24 is the VPN subnet of the A – C channel,
Did the opposite on C and now I have perfect connection between
any given subnet!
Thanks again!
Michael
Sébastien Wains
Great, thanks for the feedback. I made up all the config without actually trying it. Of course source addresses appear to come from 10.0.x.0/24 and not 192.168… it makes sense
David Piedra
Hello, this works great for me, i did ti and it’s working great. There’s just one thing that is not working at all. There’s an internal email that’s not working between sites, the server is in site A but none of the site B computers can neither receive nor send emails to the server. With the iptables rules you put, all the traffic from one network to the other, suppose to be passed through the tunnel, but all packages from the email seems to be lost and never get to the tunnel. I configure the email clients to use the IP of the server not the name, but still not working.
Any ideas, thanks!!
Sébastien Wains
I don’t want to talk you down but have you configured your SMTP server to accept send/receive emails from the range at site B ?
David Piedra
Yes, I did. I think is a firewall problem, because I can’t even connect from a computer on site B to the mail server on site A, using telnet to port 110 or 25; I get conection refused and put a sniffer to get all packages from tun interface on site B and there isn’t packages going through the tunnel when telnet is trying.
Thanks for your quick answer.
Sébastien Wains
Please sniff on each end. Try to telnet into SMTP and send me the output. Also provide me with your range info (LAN + VPN).
David Piedra
thanks for all your help!!!
The firewall on both sides are allowing everything pass though!!
Lan config
Site A 130.0.0.0/24
Site B 130.0.1.0/24
VPN
Site A 10.0.0.0
Site B 10.0.1.0
Mail Server 130.0.0.252
Telnet from 130.0.1.17
$ telnet 130.0.0.252 25
Trying 130.0.0.252…
telnet: Unable to connect to remote host: Connection refused
Sniff Site A
home/computo# tshark -i tun0
Running as user “root” and group “root”. This could be dangerous.
Capturing on tun0
tshark: arptype 65534 not supported by libpcap – falling back to cooked socket.
Sniff Site B
:~# tshark -i tun0
Running as user “root” and group “root”. This could be dangerous.
Capturing on tun0
tshark: arptype 65534 not supported by libpcap – falling back to cooked socket.
Leave Comment
Please consider visiting the partners below if you enjoyed this article :If this post saved you time and money, please consider checking my Amazon wishlist.







Serge van Ginderachter
Another fine howto. Thanks!