Open VPN

Installation

With point to point tunneling protocol VPN’s depreciated because of security issues we are now not even bothering to install pptp at all and are instead opting for openvpn.

For the installation you are going to want 2 applications, openvpn and easy-rsa.

#apt-get install openvpn easy-rsa

 

Build and configure the certificate authority

OpenVPN supports bidirectional authentication based on certificates, meaning that the client must authenticate the server certificate and the server must authenticate the client certificate before mutual trust is established. We will use Easy RSA’s scripts to do this.

First copy over the Easy-RSA generation scripts.

#cp -r /usr/share/easy-rsa/ /etc/openvpn

Then create a directory to store the keys in.

#mkdir /etc/openvpn/easy-rsa/keys

Next we need to set the parameters for our certificate

#vi /etc/openvpn/easy-rsa/vars

You need to set the following according to your configuration.

export KEY_COUNTRY=
export KEY_PROVINCE=
export KEY_CITY=
export KEY_ORG=
export KEY_EMAIL=
export KEY_OU=

The country code for England is GB; the province is the county (I guess this is a yank thing but I just put LA for Lancashire; KEY_ORG is the company; and KEY_OU is the top level domain.

Further down you will find the X509 Subject field. This is what your ca certificate will be called. I am going to call it “OpenvpnServer

export KEY_NAME="OpenvpnServer"

That is it for vars, now we can move on to the initialization process.

 

Initialise the Certificate Authority

First we generate the Diffie-Helman parameters using a built-in OpenSSL tool called dhparam.

#openssl dhparam -out /etc/openvpn/dh4096.pem 4096

The -out flag specifies where to save the new parameters file

Now it is time to generate the first key. First we need to switch to the easy-rsa directory.

#cd /etc/openvpn/easy-rsa

Next, we can begin setting up the Certificate Authority itself. First, initialize the Public Key Infrastructure (PKI). The first thing to so is source the vars file (I guess this tells build-ca where to look for the configuration file)

#source ./vars

Then run clean-all to we’ll clear any other keys that may interfere with our installation.

#./clean-all

Finally, we will build the CA using an OpenSSL command. This command will prompt you for a confirmation of “Distinguished Name” variables that were entered earlier. Press ENTER to accept existing values.

# ./build-ca

If you get the following error:

grep: /etc/openvpn/easy-rsa/openssl.cnf: No such file or directory pkitool: KEY_CONFIG (set by the ./vars script) is pointing to the wrong version of openssl.cnf: /etc/openvpn/easy-rsa/openssl.cnf The correct version should have a comment that says: easy-rsa version 2.x

Then you need to create a symbolic link which is

#ln -s openssl-1.0.0.cnf openssl.cnf

Note: this may change in future versions. There are some suggestions that this is caused by running source ./vars before ./build-ca but the current documentation is fairly unclear on this.

The Certificate Authority is now set up but we still have to build the key for the server

Type hostname to get the name of your server

#hostname

If you do not get a proper name or it just returns “localhost” then check your /etc/hosts file for errors.

#./build-key-server OpenvpnServer

NOTE: The name here needs to be the same as the name under the X509 stanza in the vars file.

You will be asked several questions; when you get to Common Name, you need to type in the name of your server. Do the same for Name.

When you get to password just press <enter> and do the same for company name. The CA will now ask you if you want it to sign the certificate. Press y followed by <enter>. If all is well it should say

1 out of 1 certificate requests certified, commit? [y/n]

Again press “y” followd by <enter> and the CA should respond with the following 2 lines

Write out database with 1 new entries

Data Base Updated

You now have a certificate for your server. The next thing to so is to copy your certificate and keys to the correct directory.

#cp /etc/openvpn/easy-rsa/keys/{OpenvpnServer.crt,OpenvpnServer.key,ca.crt} /etc/openvpn

You can verify the copy was successful with:

#ls /etc/openvpn

We will leave easy-rsa for now and configure the openvpn server however we will need to revisit easy-rsa when we generate the certificates for our clients.

 

Openvpn Server Configuration

/etc/openvpn/server.conf is where the configuration is set for the openvpn server. This file does not exist by default and needs to unzipped and copied from the sample config files. You could of course write your own, it is entirely up to you.

For the purpose of this exercise we are going to assume that the server has a LAN IP address of 172.17.1.16 and the server is behind a NAT. The subnet is 255.255.0.0 and the local dns servers are 172.17.1.4 and 172.17.1.3

#gunzip -c /usr/share/doc/openvpn/examples/sample-config-files/server.conf.gz > /etc/openvpn/server.conf
#vi /etc/openvpn/server.conf

The following directive are the important ones

port 1194
proto tcp
dev tun
ca ca.crt
cert OpenvpnServer.crt
key OpenvpnServer.key
dh dh4096.pem
server 10.8.0.0 255.255.255.0
ifconfig-pool-persist ipp.txt
push "route 172.17.0.0 255.255.0.0"
client-config-dir ccd
push "dhcp-option DNS 172.17.1.4"
push "dhcp-option DNS 172.17.1.3"
client-to-client
user nobody
group nogroup
keepalive 10 120
**comp-lzo**
persist-key
persist-tun
status openvpn-status.log
log-append /var/log/openvpn.log
verb 4

Don’t use comp-lzo on the later versions (Debian stretch) use compress lz4-v2 This will also need to be changed in the client config.

port, proto and dev should already be set as default as should ca. You will need to set cert and key correctly and change dh from

dh1024.pem

to

dh4096.pem

server should be fine at 10.8.0.0 unless you have any special networking requirements such as a conflict with an existing network. ifconfig-pool-persist should also already be set. You will need to add the line

push "route 172.17.0.0 255.255.0.0"

or uncomment one of the existing examples and set it according to your configuration.

Now uncomment

client-config-dir ccd

Next amend the DNS directives by uncommenting them and changing them to point to the appropriate DNS servers.

push "dhcp-option DNS 172.17.1.4"
push "dhcp-option DNS 172.17.1.3"

and uncomment client-to-client. keepalive should be ok as it is, as should comp. For added security you will need to uncomment to user and group directives to prevent openvpn from running as root.

persist-tun and persist-key should be fine as they are, as should status. Uncomment log-append and change verbosity from verb 3 to verb 4 and you should be done.

Newer tunnelblick clients will generate a warning if you use an insecure cipher so you have to comment out any existing ciphers and add

cipher AES-256-CBC

Additionally later versions have the following directive

explicit-exit-notify 1

This needs to be commented out if you are using proto tcp as it only works with udp

Save and exit server.conf and run

#openvpn --genkey --secret /etc/openvpn/ta.key

to generate the ta.key

The last thing to do is make a directory called ccd in /etc/openvpn

#mkdir /etc/openvpn/ccd

Forgetting to do this will cause the openvpn service to appear to be running but when it isn’t

 

Routing tables

Before we start openvpn we need to tell our server what to do with incoming traffic. First we need to enable packet forwarding. Enter the following command

#echo 1 > /proc/sys/net/ipv4/ip_forward

You should now have a file that simply has a 1 in it

#cat /proc/sys/net/ipv4/ip_forward

Next, we’ll need to make this permanent so that this setting persists after a server reboot. Open the sysctl configuration file

#vi /etc/sysctl.conf

Near the top of the sysctl file, you will see:

#Uncomment the next line to enable packet forwarding for IPv4
#net.ipv4.ip_forward=1

Uncomment net.ipv4.ip_forward as suggested, save the file and exit.

Assuming that you have left the default configuration for the VPN subnet as it is at 10.8.0.0 255.255.255.0 in the server.conf i.e.

server 10.8.0.0 255.255.255.0

Then you need to run the following line from the command line in order to tell the server what to do with traffic coming from the VPN subnet

#iptables -t nat -A POSTROUTING -s 10.8.0.0/24 -o eth0 -j MASQUERADE

Again here, we are assuming here that the Ethernet port that you are using is eth0. If there is more than one network card in your machine then you need to make sure you are configuring the correct one, but usually it is eth0 (Be careful with some HP’s that have crazy names for their Ethernet ports). Before you start run ifconfig to check this.

Iptables is not persistent across reboots but once you have it configured correctly, there’s an app for that:

#apt-get install iptables-persistent

And follow the instructions on screen. Iptables saves the configuration in /etc/iptables/rules.v4 and rules.v6 respectively.

Congratulations, you should now have a working openvpn server. Make sure that you open port 1194 for udp on your router and point it to your server. Start your server in the usual way by running

#service openvpn start

and check that it is running with

#service openvpn status

Note that openvpn will appear as though it is started and running when it isn’t; see troubleshooting below to see how to make sure you have a live server.

The big problem that you have at this stage is that although you have a nice vpn server, your clients will not be able to connect to it. In order to get the clients connecting you will need to go back to easy-rsa and generate some client certificates

 

Bind 9

If you are using the later versions of bind 9 for dns lookups then you will have to allow the subnet that you have set for your vpn to perform recursive lookups.

Once you have connected to the vpn you should be able to access any devices on the remote network using their ordinary host names. If you cannot do this, but you can access them by IP then chances are this is the problem.

To resolve it you first need to create an access control list.

#vi /etc/bind/named.conf.options

Here we are making assumptions that the remote lan is using 172.17.0.0/16 the local lan is using 172.18.0.0/16 and the bridge is using 10.8.1.0/24 and thus the access control list stanza should look like so:

acl "trusted" {
       172.18.0.0/16;
       172.17.0.0/16;
       10.8.1.0/24;
       localhost;
       localnets;
};

Now under the “options” stanza we can tell bind that we want to allow machines in the “trusted” acl to use queries and recursion.

options {
    ....
    recursion yes;
    allow-query { trusted; };
    allow-recursion { trusted; };
    allow-query-cache { trusted; };
    ….
}

Now we can restart bind and we should be able to perform lookups on the dns server.

 

Connecting Clients

There are 4 files needed for each client ca.crt; an openvpn client configuration file; and the client certificate files.

First we will grab a copy of the default client.ovpn file and rename it as we copy it. Note that the naming convention is important here as the name of the file must match the name of the client machine. In this example we are going to assume that the client machine is called “mypc”. First run

#cp /usr/share/doc/openvpn/examples/sample-config-files/client.conf /etc/openvpn/easy-rsa/keys/mypc.ovpn

Remember to change ovpn to the name of your pc suffixed by “.ovpn”

Now we need to edit the file we have just created.

#vi /etc/openvpn/easy-rsa/keys/mypc.ovpn

Change the remote directive to reflect the public ip address of your server (If you are behind a NAT then this will be your static ip address assigned by your ISP). If you do not know it then google “What is my ip”

remote XXX.XXX.XXX.XXX 1194

Next you will need to change the certificate names to reflect the ones that you are about to generate. In this example they will be called crt and mypc.key.

cert mycp.crt
key mypc.key

change verb to 4 and add

log-append /var/log/vpnclient.log

ns-cert-type has now been depreciated so this should be commented out and replaced with

remote-cert-tls server

Although not strictly necessary you can add

auth-nocache

to the client file; This will prevent the client from caching passwords.

You will also need to set the cipher to match that in the server configuration file (i.e. AES-256) by inserting the line

cipher AES-256-CBC

and commenting out any other cipher declarations

As mentioned previously comp-lzo is in the process of being depreciated in favour of compress lz4-v2 for later servers you need to add this directive to the client file and comment out any reference to comp-lzo

compress lz4-v2

If this configuration is for a linux client then uncomment user and group directives which should be set to nobody; otherwise you are done.

 

OPTIONAL:

There is a directive that ensures that all traffic is routed through the server (which is great for security but slow as fuck so only really useful as when you are using a public network and cannot get the access that you need).

redirect-gateway def1 bypass-dhcp

This directive is only well suited for roaming computers such as laptops and phones so what I would suggest is to create a second .ovpn file and only use it when necessary.

If you want to make sure that all traffic is routed through the vpn then you can push the directive from the server.

Now to generate the certificates. Navigate to the easy-rsa directory

#cd /etc/openvpn/easy-rsa

and run the following command to generate the keys (changing mypc to the name of your client box)

#./build-key mypc

You will be presented with a series of questions, just press <enter> as the defaults should be fine as long as you have given the certificate a unique name should it be necessary to reference it in the ccd directory. You may want change the name to the same as the common name, but this is not strictly necessary. (note, sometimes you will have to source the vars file again by running source ./vars, not sure why). When asked to sign the certificate answer “y” and the same with commit.

The next thing you need to do is copy the following files into a folder and put them on your client.

/etc/openvpn/ca.crt

/etc/openvpn/ta.key

/etc/openvpn/rsa-keys/mypc.crt

/etc/openvpn/rsa-keys/mypc.key

/etc/openvpn/rsa-keys/mypc.ovpn

Note that the prefix of the file names will be the name of your client.

 

Tunnelblick

Tunnelblick is the openvpn client for mac. It does not play nice if you are using a static ip address and are using either

dhcp-option DNS xxx.xxx.xxx.xxx

Set in the *.ovpn file on the client or the push equivalent set in the server’s conf file.

push “dhcp-option DNS xxx.xxx.xxx.xxx”

To get around this you will need to set dhcp or add the dns server to the list. The problem with the latter is that it will slow your computer down when you are not connected to the vpn because it will have to wait until the lookup times out trying to access a server that it thinks has died.

If you need a static ip on your client then the best way is to bind it to you client’s mac address using your router. How to do this is beyond the scope of this manual as it is entirely dependent what router you are using.

 

Troubleshooting

nmap is your friend. With the openvpn service up and running run

#nmap -p 1194 -sU -PO xxx.xxx.xxx.xxx

note –p is the port number, -sU tells nmap it is looking at a udp port and –PO is the flag for the ip address of the interface. The output should look something like

Starting Nmap 6.47 ( http://nmap.org ) at 2016-04-07 09:46 BST

Nmap scan report for fqdn.suffix (xxx.xxx.xxx.xxx)

Host is up.

PORT     STATE         SERVICE

1194/udp open|filtered openvpn

If it says closed then this will need to be resolved before you go any further. If the status of the service is “active” but the port is closed then check that you have created the ccd directory.

On another server I hand to stop the service (even though it wasn’t actually running) and they run systemctl enable openvpn followed by systemctl start openvpn and then it worked. I found this out by running openvpn from the command line

Also try netstat which should tell you what ip and protocol openvpn is listening on

#netstat -uapn | grep openvpn

Check that it is using the udp port and that the ip address that the port is using is correct. If not then you will need to set the local directive in the conf file.

Check the log for errors at /var/log/openvpn.log

Check that you have a tun0 interface by running ifconfig

If all else fails then temporarily change to tcp by changing the proto directive in server.conf. Restart the service and then try and telnet to it.

If you can create a tunnel but cannot connect to clients then check the iptables. In particular

#iptables –t nat --list

should return something like

0     0 MASQUERADE all — *     eth0   10.8.0.0/24         0.0.0.0/0

If not then run

#iptables -t nat -A POSTROUTING -s 10.8.0.0/24 -o eth0 -j MASQUERADE

The flags are:

-t = table name

-A = append

-s = source address/mask

-o = output interface (use [+] for wildcard)

-j = target

If you have a couple of vpn servers that may at some point end up talking to each other then you might want to make sure that you put their internal addresses on different subnets (Say 10.8.1.0/24 for the second one for example).

To delete a record replace the –A flag with a –D flag

#iptables -t nat -D POSTROUTING -s 10.8.0.0/24 -o eth0 -j MASQUERADE