Connect to Private Internet Access (PIA) VPN with OpenVPN on Ubuntu

This post will go over using OpenVPN in Ubuntu 16.04 to connect to a Private Internet Access (PIA) VPN server. PIA has pre-made configuration files here which we will use as a base for our configuration file. I will walk through each option so you can understand any potential problems you may face. The first thing we need to do is install OpenVPN so to do that we run

 sudo apt-get install openvpn

Once we have that installed we need to download the certificate we are going to use to connect to the PIA servers. Download the zip file mentioned above in the openvpn directory with cd /etc/openvpn then download the zip with

sudo wget https://www.privateinternetaccess.com/openvpn/openvpn.zip

Once we have the zip file we can unzip it in a separate folder to keep the main directory clean. We probably need to install the unzipping utility so run sudo apt-get install unzip. We now will unzip the downloaded file into a new PIA directory with

sudo unzip openvpn.zip -d PIA

Putting all this together we get:

sudo apt-get install openvpn
cd /etc/openvpn
sudo wget https://www.privateinternetaccess.com/openvpn/openvpn.zip
sudo apt-get install unzip
sudo unzip openvpn.zip -d PIA

Since we are creating our own config file for OpenVPN the only files we are going to need from the zip file is the peer certification file to connect to the VPN servers ca.rsa.2048.crt and the certification revocation list file crl.rsa.2048.pem. The CRL is used to list all certificate keys that are not allowed to connect to PIA’s servers. We can move these files to the main OpenVPN directory with

sudo cp~/PIA/ca.rsa.2048.crt /etc/openvpn/ca.rsa.2048.crt
sudo cp ~/PIA/crl.rsa.2048.pem /etc/openvpn/crl.rsa.2048.pem

Now that we have the keys let’s create the config file that will be used by OpenVPN to connect to the PIA servers. We create an empty file with

sudo touch /etc/openvpn/pia.conf

We also need to create a separate file for the username and password with

sudo touch /etc/openvpn/creds.conf

Before we move on to the actual configuration let’s recap the commands:

sudo cp ~PIA/ca.rsa.2048.crt /etc/openvpn/ca.rsa.2048.crt
sudo cp ~/PIA/crl.rsa.2048.pem /etc/openvpn/crl.rsa.2048.pem
sudo touch /etc/openvpn/pia.conf
sudo touch /etc/openvpn/creds.conf

The full configuration that we will go over is:

client
dev tun
remote us-east.privateinternetaccess.com 1198 udp
remote us-east.privateinternetaccess.com 502 tcp
resolv-retry infinite
nobind
persist-key
persist-tun
cipher aes-128-cbc
auth sha1
crl-verify /etc/openvpn/pia/crl.rsa.2048.pem
ca /etc/openvpn/pia/ca.rsa.2048.crt
remote-cert-tls server
auth-user-pass /etc/openvpn/creds.conf
auth-nocache
comp-lzo
verb 1
reneg-sec 0
disable-occ client
dev tun
remote us-east.privateinternetaccess.com 1198 udp
remote us-east.privateinternetaccess.com 502 tcp
resolv-retry infinite
nobind
persist-key
persist-tun
cipher aes-128-cbc
auth sha1
crl-verify /etc/openvpn/crl.rsa.2048.pem

The first option passed to OpenVPN is client which is a shortcut to using the pull and tls-clientoptions. The pull option is used on a client to allow a server that many clients connect to (or a multi-client server) to push routes to the client. This will force all queries to go through the PIA servers. The tls-client option enables TLS encryption (frequently called SSL). The next OpenVPN option is dev which can be set to TUN or TAP. We set TUN here which allows for lower traffic overhead but can only be used in IP based traffic and cannot create Ethernet bridges. TAP on the other hand, is more compatible with a wide range of network protocols as it behaves like a real network adapter (as a virtual adapter). It can also be used to bridge Ethernet adapters but all of this is at the cost of more overhead as it adds data to each data packet being sent. You 99% of the time need TUN unless you are trying to connect to PIA with a variety of devices such as printers, networked drives, etc. The next option for OpenVPN is remote which we will have two copies, one for UDP which is less overhead but has no error recovery, and one option for TCP which is what’s used in your browser. We specify the host name of the PIA server we want to connect to, the port used for that type of connection, and the network protocol used (UDP or TCP). Using two remote options allows for a fallback option if the first one fails. I used US East as my VPN server but you should choose from the list here that best suits your needs.

client
dev tun
remote us-east.privateinternetaccess.com 1198 udp
remote us-east.privateinternetaccess.com 502 tcp

The next option is resolv-retry which we set to infinity. This means we want to keep trying to reconnect forever. This can be set to a number, for example 5 which then OpenVPN will only try to reconnect 5 times before failing. The nobind option tells OpenVPN to not use the local IP address and port. This is used with the remote option so the PIA servers can assign these values dynamically themselves. The next two, persist-key and persist-tun tell OpenVPN to not reopen/reload on OpenVPN restarts. This allows for restarts via the SIGUSR1 signal without reloading the keys and tun connection. SIGUSR1 (and SIGUSR2) are user defined signals that you can use for your own scripts. These are optional but nice to have when you want to automate reconnecting.

resolv-retry infinite
nobind
persist-key
persist-tun

The next few options are security specific. The cipher option specifies the algorithm for encryption to use. PIA uses aes-128-cbc but if you want to see a list of supported algorithms run openvpn –show-ciphers. The auth option defines the message digest algorithm which is almost always SHA-1. The next two options use the two files we copied over. The crl-verify option is used to certify the certificate revocation list. The value of this is where the CRL is located which is crl-verify /etc/openvpn/crl.rsa.2048.pem. The same goes for the ca option that specifies the certification used: ca /etc/openvpn/ca.rsa.2048.crt. The remote-cert option is a shortcut option and is equivalent to –remote-cert-ku a0 88 –remote-cert-eku “TLS Web Client Authentication”. The remote-cert-ku option requires that a peer certificate is signed specifically with a key. This is encoded in hexadecimal (the ao 88 part). The remote-cert-eku option requires that the same peer certificate is signed with an extended key. This is encoded in OpenSSL symbolic representation. This ensures proper TLS authentication with the PIA servers.

cipher aes-128-cbc
auth sha1
crl-verify /etc/openvpn/pia/crl.rsa.2048.pem
ca /etc/openvpn/pia/ca.rsa.2048.crt
remote-cert-tls server

I want to go over the auth-user-pass option on its own because this is where we will use the /etc/openvpn/creds.conf file we created. This file will have two lines, the username and password. The important thing to remember is this text file has to be in UNIX format and not dos. If you create and edit the file from Linux then you are good but if you are using Windows and SFTP the file over you should probably convert the file to Unix format. If you don’t convert it, you can get errors about an incorrectly formatted auth file. Open the creds.conf file we created with sudo nano /etc/openvpn/creds.conf. Inside the file we will have two option values: ‘YOUR_USERNAME’ is your PIA username and ‘YOUR_PASSWORD’ is your PIA password. To convert the creds.conf file to Unix format if you need to run the command

sudo dos2unix /etc/openvpn/creds.conf
YOUR_USERNAME
YOUR_PASSWORD

Save this file and since it has your password in plain text we are going to change the permissions to read only for the root user only. We set the owner to root with

 sudo chown root:root /etc/openvpn/creds.conf 

and set to read only with

sudo chmod 0400 /etc/openvpn/creds.conf

Make sure you set this AFTER you have added your username and password to the creds.conf file. We now need to reference this file inside the main OpenVPN configuration file and we do this by adding the path to your credentials file to the auth-user-pass option. We also add the auth-nocache option to not allow saving the username and password in virtual memory. This is an extra security precaution for your credentials to PIA.

auth-user-pass /etc/openvpn/creds.conf 
auth-nocache

We are done with the authorization side of things so now we add the comp-lzo option which allows for lzo compression. Ubuntu comes with lzo compression but if you don’t have it you can install it with

sudo apt-get install liblzo2–2

The verb option sets the amount of logging you want for OpenVPN operations. This can be set from a low of 0 to a high of 11. For debugging set this value in the 6–11 range. 1–4 is normal operation which I like to set to 1 when I get everything working. The related status option sets where the logs are going and I set this to /etc/openvpn/openvpn.log. Usually logs of most programs go to the /var/logs/ directory if you desire. The reneg-sec option tells OpenVPN to renegotiate the data channel key after n seconds. The default is 3600 but we are going to set this to 0 because we use the same key when connecting to the PIA servers. Finally, the disable-occ option tells OpenVPN to not display warnings if there are inconsistent options between peers. The PIA servers might update their server side options but might not affect the connection so we don’t want any errors about this. This is an optional field.

comp-lzo
verb 1
status /etc/openvpn/openvpn.log
reneg-sec 0
disable-occ

Once we have all of the options set, we just run OpenVPN with the –config option and specify the config we created. You will see a few boot up information and finally you will see Initialization Sequence Completed and you are connected to the OpenVPN servers. To make sure, we can open another terminal and type curl ipinfo.io/ip and this website will give us back our public IP address which should be PIA’s server that you configured in the remote option.

sudo openvpn --config /etc/openvpn/pia.conf 
curl ipinfo.io/ip

Now we want OpenVPN to always connect to the PIA servers on boot in the background. We do this with the init.d configuration. OpenVPN already comes with an init.d script so we just need to modify which configuration files OpenVPN will use. We only have one conf file /etc/openvpn/pia.conf so we open the init.d config file sudo nano /etc/default/openvpn and create a new line above the #AUTOSTART=’all’ line with AUTOSTART=’pia’. This AUTOSTART variable will tell the init.d script to automatically start all conf files for each AUTOSTART that you define. You can have more than one AUTOSTART value. We don’t need to add the .conf as this is implied when the script loads our configuration file. The relevant part of the OpenVPN script looks like this:

Start only these VPNs automatically via init script.
Allowed values are "all", "none" or space separated list of
names of the VPNs. If empty, "all" is assumed.
The VPN name refers to the VPN configutation file name.
i.e. "home" would be /etc/openvpn/home.conf
#
AUTOSTART='pia'
AUTOSTART="all"
AUTOSTART="none"
AUTOSTART="home office"

Now you need to run the init.d file and once OpenVPN has started the PIA config file you will see a message: Auto starting VPN ‘pia’.

sudo /etc/init.d/openvpn start

Leave a Reply

Your email address will not be published. Required fields are marked *