OpenVPN on Ubuntu Linux

OpenVPN

OpenVPN is a tool to create a Virtual Private Network over a public network connection. With a VPN you create a secure tunnel over the
internet which is fully secured. Device on both sides of the tunnel can talk as if they were connected to the same network. Breaking in on
the secure tunnel is impossible.
With a VPN you can work where ever you are, on a company network or a public wifi hotspot, as if you were at home. Accessing all your local
servers and data.
OpenVPN is opensource and available on many devices including Linux, Windows, IOS and Android. This HOW-TO describes how to setup a OpenVPN
server on Ubuntu Linux Server 12.04 and connect with a Windows 7 client.

Installation

First we need to install the OpenVPN software. OpenVPN is available in the Ubuntu repository.

apt-get install openvpn

OpenVPN will be installed and all required software and libraries will be installed with it.

Certificates

OpenVPN uses SSL certificates to sign and encrypt the connection. It requires a server and client certificate. The easiest way is creating
a CA. This CA will be used to sign all server and client certificates. OpenVPN comes with a tool called easy-rsa that will do most of the
certificate stuff for us. Lets start by activating easy-rsa.

An error could be show saying the openssl.conf must use verion 2.0 or something. This is a known bug in Ubuntu. The work around for
this is creating a link and follow the procudure again.

cd /etc/openvpn/easy-rsa
sudo ln -s openssl-1.0.0.cnf openssl.cnf

The ta.key file is a extra security. The ta.key is used to create an additional HMAC signature. The server first checks this HMAC signature,
any package that doesn't have the right signature is dropped immediately. Coursing the server to be more protected for DoS attacks and port scans.

Now we have a keypair created for the server (named server). The CN in the certificate does not have to be the hostname of the server like
in a HTTPS server certificate.

Clients

Every client should have an own certificate. Again the name of the client certificate is free, as long as it is signed by the CA. Although
using the hostname or username of the client is the easiest way to keep track of you clients. Remember that anyone with a private key signed by
the OpenVPN CA can create a tunnel!

cd /etc/openvpn/easy-rsa/
source vars
./pkitool clienthostname

Now we can copy the required certificates for the client to the client. The client will require the following files:

/etc/openvpn/ca.crt

/etc/openvpn/easy-rsa/keys/clienthostname.crt

/etc/openvpn/easy-rsa/keys/clienthostname.key - Keep this file secret on the client.

/etc/openvpn/ta.key

Make sure to remove any leftovers of copying these files to the clients. These files are your keys to you private network!

Server configuration

Now it is time to configure the OpenVPN server. First we will configure the easy connection. This is a dedicated connection between the client
and the server. Later we will include the server's network and use the internet connection of the servers network.

OpenVPN comes with a couple of sample configuration files. We start off by using one of the sample configuration files.

We setup a server on 10.0.0.2 using udp port 1194 (which is the OpenVPN default).
The server parameter defines the network used by the VPN connection, the server gives all clients an ipaddress in this 10.8.0.0 range.
The ifconfig-pool-persist parameter tells OpenVPN to
remember all the DHCP addresses given to the clients so they key the same address the next time the logon.
Next we push the new route to the client so it can find the server on the 10.8.0.0 network. The last user and group options tell linux to
run the OpenVPN server using this user and group. Just some extra security.

Now we can start the OpenVPN server.

/etc/init.d/openvpn restart

Check your logfile on any errors, a netstat -lpun will show OpenVPN running on port 1194 if everything wend ok.

Client configuration

We will use a Windows 7 client to connect to the VPN server. The client must be connected to another network as the server (10.0.0.0).
The Windows software can be downloaded from the OpenVPN website. The software contains a sample configuration file. Change the configuration
C:\Program Files\OpenVPN\config\client.ovpn as followed:

First we define that we use the tun device on remote address 123.123.123.123 using udp port 1194. The ns-cert-type parameter is an additional
security that tell the client to check the server uses a certificate with the indicated name (server in our case). The certificate files need to
be copied to the config folder.

We can now start the client using the following command (run as administrator!).

"C:\Program Files\OpenVPN\bin\openvpn-gui.exe"

If the connection is successfull the client should have a second network interface with a new ip-address in the 10.8.0.0 range. We should now
be able to ping the server on 10.8.0.1.
The default firewall settings of Windows and Ubuntu should be ok to connect, but when facing connection problems a good look at the both
firewall settings would be advisable.

Access private network

We can connect to the OpenVPN server, but we want to be able to connect to all the other systems in our private network as well.
For this we need some additional setting in the server configuration and push some additional routes to the client. Make the following changes
to the server.conf file and restart the OpenVPN server.

push "route 10.0.0.0 255.255.255.0"
client-to-client

This add's the route to the private network to the clients. Also the option client-to-client enables clients on the OpenVPN network (10.8.0.0)
to see and connect to each other, as if they were connected on the private network.

The clients can now connect through the OpenVPN server to all systems on the network. But the systems on the network don't know the route to
the VPN network. There are 2 options to tell the systems were to find the VPN network address. The first option is to add a route on every individual
system on the private network. This is a lot of work and can easily be forgotten when a new device is added to the private network.
The second option is to add a route to the VPN network in the router (ADSL Internet router). Most modern routers come with the option to manually
add a route to another subnet. Setup a route to network 10.8.0.0 using gateway 10.0.0.2 (our OpenVPN server).

Now we should be able to ping from the client any server on the private network. If we can only ping our OpenVPN server as 10.0.0.2 and not the
other server, the route is misconfigured on not yet activated.

Address Internet over VPN

There could be 2 reasons to use the VPN's internet connection. The first is to disable any other traffic than the VPN traffic to make sure
we do not create a backdoor to our private LAN. The second reason is that the clients Internet connection could be blocked by firewalls to
block us to use specific services or sites.

Again we need to make some changes to the server.conf file on the OpenVPN server, and restart the server.

First we add a new route to route all network address via the VPN server. Next we tell the client to overrule the default gateway and use
the OpenVPN server as default gateway. The last option tells the client to use our private networks router as DNS server. This could be any
DNS server used on the private network.

The client will now try to connect through the OpenVPN server to the internet. But we must also setup our OpenVPN server to forward all
requests from the VPN network to the private network router. For this we need to enable ip forwarding and add some firewall rules on the OpenVPN
linux server.

The change to the sysctl.conf file will enable ip forwarding. The first rule reject all traffic. The second rule accepts all related and established connections. The 3rd rule accepts connections from the
VPN network. So only connection from the VPN network will be allowed. The last rule is the forward rule to masquerade all traffic from the VPN
network (10.8.0.0) as it comes from the local network (10.0.0.0). Now we should be able to connect from the VPN client to the internet using the
private network internet connection.

Hide OpenVPN behind Apache

OpenVPN comes with a very nice option to share the used port with another service. We can use this option to hide OpenVPN behind an Apache
HTTPS website. This can be very usefull when our client's network uses a very restricted firewall. Another advantage is that a portscan will not
reveal an OpenVPN port as it reuses the HTTPS port 443.

To enable this option we need to make some adjustment to both the server and the client configuration files. Lets start with the server config.

port 443
proto tcp
port-share 10.0.0.3 443

In my case the Apache webserver is located on another server in the private network (10.0.0.3) so we can simply forward any HTTPS traffic to
this existing server. The only thing we now need to do is change the portforwarding rule on the router to route HTTPS traffic to 10.0.0.2 (our
OpenVPN server) instead of our Apache server (10.0.0.3). If the Apache server is located on the same server as the OpenVPN server, we need to change
the HTTPS port number of the Apache server to eg. 8081. The OpenVPN configuration needs to forward the port-share to 127.0.0.1 8081.

Next we need to change the client config.

proto tcp
remote 123.123.123.123 443

We should be able to make a VPN connection from the client again. Also check if the HTTPS site still works.

User/Password protection

Our VPN connection can easily be setup by double clicking the shortcut on the client. So if our client gets stolen, someone could easily connect
to our local network. An easy option to protect us from misusing the clients VPN connection is by adding a username and password to the VPN connection.
This is easily done by adding an extra configuration parameter to both the server and the client.

Server config

plugin /usr/lib/openvpn/openvpn-auth-pam.so login

This will tell OpenVPN to check any client against the Linux pam login module. Now we need a valid Linux user to connect to the VPN server.

Client config

auth-user-pass

This option tells the client to ask for a username and password prior to connect to the VPN server.