Linux

OpenWRT + OpenVPN + Routed LANs

So I’ve been using OpenVPN for a while now in a “point-to-point” (i.e. road-warrior) fashion. On the server I’m running OpenVPN on CentOS 5.3 using client certificate authentication + TLS-AUTH. I have 2 clients connecting, 1 client (me) connects from either a Windows host (OpenVPN GUI) or a Mac host (Tunnelblick). The other client connects from a Linux host (OpenVPN NetworkManager plugin).

Now whenever I connect, it’s from home – either I’m on my laptop or I’m on my mini. I have a Linksys WRT54GL running OpenWRT as my home router. Now I’ve configured the OpenWRT client in a bridged-fashion before but I wasn’t too fond of it since it doesn’t allow other clients to connect if they’re on a different network than the server without setting up another server instance.

So I set out today to figure out how to configure the routed vpn tunnel to allow the private networks on either side of the tunnel to be able to communicate with each other.

I found this post on the OpenWRT forums describing the same setup but it had no solution. I believe the problem was trying to manipulate the routing tables on the individual hosts directly when you actually need some extra routing configuration in OpenVPN. You have to use the client-config-dir option and the iroute option so OpenVPN can correctly route between the 2 LANs.

On the server we have the following setup:

eth0: 10.0.0.200/24
tun0: 192.168.255.1/24

[root@server openvpn]# cat /etc/openvpn/server.conf
port 1194
proto udp
dev tun
ca /etc/openvpn/ca.crt
cert /etc/openvpn/server.crt
key /etc/openvpn/server.key
dh /etc/openvpn/dh2048.pem
tls-auth /etc/openvpn/ta.key 0
server 192.168.255.0 255.255.255.0
client-config-dir /etc/openvpn/clients
route 192.168.1.0 255.255.255.0
keepalive 10 60
persist-key
persist-tun
comp-lzo

[root@server openvpn]# cat /etc/openvpn/clients/client1
iroute 192.168.1.0 255.255.255.0
push “route 10.0.0.0 255.255.255.0”
ifconfig-push 192.168.255.2 192.168.255.1

An explanation of the /etc/openvpn/clients/client1 config:

The ‘client1’ name comes from the common name of the certificate which the client is connecting with. For example, in my actual setup my common name is my full name so the client config file is /etc/openvpn/clients/FirstName_LastName

  • the ‘iroute’ option tells the server the 192.168.1.0/24 network should be routed through ‘client1’
  • the ‘push’ option tells client1 the 10.0.0.0/24 network is routed through the vpn tunnel
  • the ‘ifconfig-push’ option assigns client1 the vpn ip 192.168.255.2 routed through 192.168.255.1

On the client we have the following setup:

eth0: 192.168.1.1/24
tun0: 192.168.255.2/24

[root@client openvpn]# cat /etc/openvpn/server.conf
client
dev tun
proto udp
remote 1.2.3.4 1194
nobind
ca /etc/openvpn/ca.crt
cert /etc/openvpn/client1.crt
key /etc/openvpn/client1.key
tls-auth /etc/openvpn/ta.key 1
persist-tun
persist-key
comp-lzo

After starting openvpn on the two hosts, there should be additional route entries similar to the following on the client:

[root@client openvpn]# route add -net 192.168.255.1 netmask 255.255.255.255 dev tun0
[root@client openvpn]# route add -net 10.0.0.0 netmask 255.255.255.0 gw 192.168.255.1 dev tun0

And on the server:

[root@server openvpn]# route add -net 192.168.255.2 netmask 255.255.255.255 dev tun0
[root@server openvpn]# route add -net 192.168.1.0 netmask 255.255.255.0 gw 192.168.255.2 dev tun0

Now you may have noticed my OpenVPN server’s internal IP address is 10.0.0.200. It’s not the border router for the 10.0.0/24 network – 10.0.0.1 is (i.e. it’s the default gateway on the 10.0.0/24 network). It’s a FreeBSD router so simply adding a route entry for 192.168.1/24 via 10.0.0.200 allows the server-side LAN to fully communicate with client-side LAN:

[root@bsd-rtr ~]# route add -net 192.168.1/24 10.0.0.200

One last thing is to add a few firewall rules on each vpn end point to allow proper communication over the tunnel:

[root@client openvpn]# iptables -t nat -A POSTROUTING -s 192.168.255.2 -d 10.0.0.0/24 -j SNAT –to-source 192.168.1.1
[root@client openvpn]# iptables -A FORWARD -i eth0 -o tun0 -s 192.168.1.0/24 -d 10.0.0.0/24 -j ACCEPT
[root@client openvpn]# iptables -A FORWARD -i tun0 -o eth0 -s 10.0.0.0/24 -d 192.168.1.0/24 -j ACCEPT

[root@server openvpn]# iptables -t nat -A POSTROUTING -s 192.168.255.1 -d 192.168.1.0/24 -j SNAT –to-source 10.0.0.200
[root@server openvpn]# iptables -A FORWARD -i eth0 -o tun0 -s 10.0.0.0/24 -d 192.168.1.0/24 -j ACCEPT
[root@server openvpn]# iptables -A FORWARD -i tun0 -o eth0 -s 192.168.1.0/24 -d 10.0.0.0/24 -j ACCEPT

If you’ve reached this point and everything has made sense so far, you should be able to successfully ping any host on the 10.0.0.0/24 network from the 192.168.1.0/24 network and vice-versa. If not, leave a comment and I’ll try to help you out.

Cheers,
–The IT Department

Advertisements

2 thoughts on “OpenWRT + OpenVPN + Routed LANs

  1. Hi,

    you write
    >On the client we have the following setup:
    >eth0: 192.168.1.1/24

    This looks like the client-side router (the Linksys one with OpenWrt). So when you use “client openvpn” you are talking about the client-lan-router, right? (Where all requests from the really-cliently-lan-machines come to. And the router then doing his routing work.)

    I notice this is a two year old post. But hey, obviously no entry for this in robots.txt, so you must /expect/ questions! 😉

  2. Hi there,

    I have reproduced same scenario. Differences: My Server is windows 2008 r2 running openvpn as a server and client is openwrt with openvpn.

    From openwrt I can ping everywehre on lan behind openvpn server.

    But I cant ping openvpn’s server internal lan from clients connected on openwrt.

    How can I troubleshoot that ?

    Bruno

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s