Tuesday, January 17, 2012

OpenVPN revisited

I already touch on the basics on setting up openvpn. In that setup, a remote client(or clients) will only be able to connect to the server and access it's services. This time i want to share a little bit of knowledge on setting things up where remote clients can communicate with other devices on the server network.

Network setup:

[client1:] [client2:]

[internal:] - [vpn:]

VPN clients:
[vpn:remote user:]

The server is connected to an internal network, When the VPN link is establiished, the vpn network of will be established and the server will get the ip address of, while connecting clients will get different addresses from the vpn's address pool. Now if you've followed my previous openvpn setup, the remote client would only be able to communicate with that server. However many businesses require that remote vpn users have access to the entire subnet's resources. As you will see, upgrading to this setup is quite simple.

Here are the client and server configs:

dev tun
port 1194
proto udp
ca ca.crt
cert server.crt
key server.key
dh dh1024.pem
push "route"
ifconfig-pool-persist ipp.txt
keepalive 10 120
max-clients 100
user nobody
group nogroup

dev tun
proto udp
remote 1194
resolve-retry infinite
ca ca.crt
cert client.crt
key client.key
user nobody
group nogroup
verb 3
Things to note:

The "daemon" directive tells openvpn to run in the background and send all output and error messages to a syslog file such as /var/log/syslog or /var/log/messages.

Including the "server" setting defines the vpn address pool. The first address,, will be assigned to the vpn server's tun interface.

The push "route" setting allows the server to advertise this subnet to connecting clients. When a remote client connects to the vpn server, a route will be added for the subnet, in that client's routing table.

The ifconfig-pool-persist ipp.txt
is very interesting. According to the openvpn's manpage in linux, The goal of this option is to provide a long-term association between clients (denoted by their common name) and the virtual IP address assigned to them from the ifconfig-pool.

The "nobind" directive in the client config simply tells the client to not bind to any address and port. This directive is only suitable for clients.

Very Important things to note:

If you were to use the sample configuration files above as is, you will only have proper communication to the server, but not the subnet behind the server. This is what happens if vpn client tried to ping; Since the clients will now have a route added for the network, the ping packet will get sent over the vpn tunnel. The server already has a route to the internal network so the packet will be routed, ONLY if after setting up forwarding :). In linux you do this by typing the following in a terminal: "echo "1" > /proc/sys/net/ipv4/ip_forward". This turns your machine into a basic router. Without this, your machine will drop all packets that aern't ment for itself. So assuming we have forwarding in place, our inital ping packet will get forwarded to the internal host. Now we run into more problems.

The internal host will recieve the packet but since it doesn't have a route for the vpn client's network (, it will send its response to its default gateway ( routers in most cases), then the router will consult its internal routing table and learn that it has no route for that network then forward the packet to its default gateway, and so on until the packet is dropped. Note that addresses such as and are dropped by routers on the internet as they are flagged as non-route-able addresses.

The solution to this is to add a route to the default gateway. For me, this would be the router, so i would log onto the routers web interface and goto the routing settings and add a maunal route for the network to forward packets to the vpn server,

Now, instead of our router forwarding the packets on the internet (where they will eventually be dropped), since we have an entry for the network in the gateways routing table, the packets will be forwarded to the vpn server. Again, we run into another problem, NAT. I suggest that you read up on NAT (network address translation), as it can be quite a challenge to define its purpose and what it is. Therefore i will leave that up to you and your googling skills.

However, the solution to the NAT problem takes only one command on the linux terminal:
"iptables -t nat -A POSTROUTING -s -o eth0 -j MASQUERADE"

Now everything should be up and working. Remote vpn clients should now be able to communicate successfully with the other hosts on the servers internal network. Try pinging the other hosts to verify connectivity and if all is well, tap yourself on the shoulder.

No comments:

Post a Comment