OpenVPN Road Warrior Setup

02 Mar 2015  Posted under: linux , systems

This is a description of how to setup a Road Warrior VPN for a network hidden behind a NAT or gateway. The road warriors can connect from anywhere and have access to the LAN.

  LAN                Gateway              The          Road Warrior
10.0.0.x  <->  10.0.0.1 | 1.2.3.4  <->  Internet  <->  192.168.0.1

In this case, we will accomplish this by having OpenVPN create a new subnet for the road warriors that forwards packets between itself and the LAN. Note, this is a routed connection (Level 3, using TUN), NOT a network bridge (Level 2, using TAP).

  LAN                Gateway              The          Road Warrior
10.0.0.x  <->  10.0.0.1 | 1.2.3.4  <->  Internet  <->  192.168.0.1
   A                                                        A
   |                                                        |
   V                                                        V
OpenVPN Server                                         OpenVPN Client
172.31.0.1  <--------------------------------------->  172.31.0.6 

This example assumes that the server is running Debain/Ubuntu, and actually located on the lan (as opposed to running on the gateway).

Server Setup

Install the OpenVPN software. EasyRSA can also be downloaded from github.com and saved to the /etc/openvpn/ if it is not available in the repository.

$ sudo apt-get install openvpn bridge-utils easy-rsa

Enable IPv4 forwarding by editing /etc/sysctl.conf

net.ipv4.ip_forward=1

Now we need to generate some SSL certificate stuff using EasyRSA. Start by editing /etc/openvpn/easyrsa/vars. This file is a bash script which we will source before running any of the EasyRSA scripts. In particular you want to edit the following fields…

export KEY_COUNTRY="US"
export KEY_PROVINCE="CA"
export KEY_CITY="SanFrancisco"
export KEY_ORG="Fort-Funston"
export KEY_EMAIL="me@myhost.mydomain"
export KEY_OU="something"

The next several commands all need to be run as root. They will generate the certificates the server needs.

$ sudo su
# ./build-ca
# ./build-key-server myvpnserver
# ./build-dh

Now we need to create a configuration file. An example configuration file can be found in /usr/share/doc/openvpn/examples/sample-config-files/server.conf. The configuration file should have the following inside it.

# IP address of the interface OpenVPN should listen on (optional)
local 10.0.0.3

proto udp
port 1194
dev tun

ca /etc/openvpn/easy-rsa/keys/ca.crt
cert /etc/openvpn/easy-rsa/keys/myserver.crt
key /etc/openvpn/easy-rsa/keys/myserver.key
dh /etc/openvpn/easy-rsa/keys/dh2048.pem

# Specify that we want a routed configuration, and
# that it will use subset 172.31.1.x. Server will 
# take the address 172.31.1.1 for itself.
server 172.31.1.0 255.255.255.0

# Route network traffic to VPN Client addresses
route 172.31.1.0 255.255.255.0

# Push routes to the client to allow it to reach the LAN
push "route 10.0.0.0 255.255.255.0"

# Push DNS settings to clients
push "dhcp-option DNS 10.0.0.1"

# Tell Client to route all traffic through VPN
push "redirect-gateway"

# Allow clients to see each other
client-to-client

# Allow multiple clients to connect with the same cert/key files.
# This is less secure but also easier to manage.
duplicate-cn

# Ping the client every 10s. The client is gone if
# no response after 120s.
keepalive 10 120

persist-key
persist-tun
verb 1
log-append /var/log/openvpn.log

Finally, we need to restart the machine. This will make our ip forwarding take effect, the openvpn daemon to restart, and the tun device to be created. Really, we shouldn’t need to restart the whole machine just to make this happen… but for some reason I could not get a tun device to appear until I did.

Gateway Configuration

The OpenVPN network we just created is not yet fully connected to our LAN. The server knows that it should be forwarding the packets to the network so the packets get to the LAN. However, when another LAN machine receives a packet from 172.31.1.3, it will think it must have come from the gateway since that is not a local address and send its reply packet to the gateway. So unless we want to configure routing rules for every device on the LAN, we need to tell the gateway what to do with packets being sent to 172.31.1.x.

On OpenWRT Routers, this can be done by going to the Network > Static Routes page, and adding the following configuration line.

lan   172.31.1.0     255.255.255.0     10.0.0.3    0     1500

Client Configuration

The first thing we need to get a client connected is to generate the certificates that will be needed to make the connection. On the Server, go to the easy-rsa directory and run build-key

cd /etc/openvpn/easy-rsa/
sudo su
source vars
./build-key roadwarrior

Now we need to create the client.ovpn configuration (profile) file that the client(s) will use to connect. You simply give this file to anyone you want to be able to connect to your LAN.

dev tun
proto udp
remote 1.2.3.4 1194
resolv-retry infinite
nobind
persist-key
persist-tun
ca [inline]
cert [inline]
key [inline]
verb 1
log-append /var/log/openvpn.log
keepalive 10 900
inactive 3600

<ca>
COPY CONTENTS OF CA.CRT HERE. IT SHOULD LOOK LIKE
-----BEGIN CERTIFICATE-----
...
-----END CERTIFICATE-----
</ca>

<cert>
COPY CONTENTS OF ROADWARRIOR.CRT HERE
</cert>

<key>
COPY CONTENTS OF ROADWARRIOR.KEY HERE
</key>

NOTE: you may need to remove the lines that say [inline] in them and replace them with the single line key-direction 1.


These instructions are based off of the guide written by cepa.io and OpenVPN.