Secure Auto-Starting Private Internet Access (PIA) Using OpenVPN on Ubuntu 16.04 LTS

By | 20/03/2017

The goal of this article is to create a Linux server that can only talk to Private Internet Access’ servers before the VPN is brought up, or if it goes down.

To remove the need for DNS before the VPN is operational, we will specify the PIA servers by IP address. The allows us to also block outgoing DNS queries as an added privacy measure (DNS Leakage).

Installing and Configuring OpenVPN

Install OpenVPN

$ sudo apt install openvpn

Download and Unpack OpenVPN Configuration Files (IP)

$ sudo apt install unzip
$ mkdir PIA
$ cd PIA
$ wget https://www.privateinternetaccess.com/openvpn/openvpn-ip.zip
$ unzip openvpn-ip.zip
$ sudo cp ca.rsa.2048.crt /etc/openvpn/
$ sudo cp crl.rsa.2048.pem /etc/openvpn/

Create the OpenVPN Configuration File

Create the file /etc/openvpn/pia.conf

$ sudo nano /etc/openvpn/pia.conf

and paste the following into it:

client
dev tun
proto udp
remote-random
#AU Melbourne
;remote 168.1.99.250 1198
#AU Sydney
;remote 168.1.6.61 1198
#Brazil
;remote 177.154.139.199 1198
#CA Montreal
;remote 173.199.65.48 1198
#CA Toronto
;remote 172.98.67.68 1198
#Denmark
;remote 192.40.89.17 1198
#Finland
;remote 192.40.95.8 1198
#France
;remote 108.61.122.214 1198
#Germany
;remote 46.165.251.68 1198
#Hong Kong
;remote 119.81.249.133 1198
#India
;remote 138.128.180.194 1198
#Ireland
;remote 185.108.128.9 1198
#Israel
;remote 31.168.172.147 1198
#Italy
;remote 159.122.133.226 1198
#Japan
;remote 161.202.72.147 1198
#Mexico
;remote 169.57.0.219 1198
#Netherlands
;remote 46.166.190.217 1198
#New Zealand
;remote 107.150.94.6 1198
#Norway
;remote 192.40.88.12 1198
#Romania
;remote 93.115.84.122 1198
#Singapore
;remote 216.185.103.139 1198
#South Korea
;remote 211.104.154.2 1198
#Sweden
;remote 5.157.7.27 1198
#Switzerland
;remote 179.43.155.162 1198
#Turkey
;remote 176.53.21.214 1198
#UK London
;remote 104.238.169.85 1198
#UK Southampton
;remote 5.63.151.156 1198
#US California
;remote 198.8.80.78 1198
#US Chicago
;remote 104.200.153.91 1198
#US East
;remote 66.55.134.219 1198
#US Florida
;remote 108.61.226.30 1198
#US Midwest
;remote 104.207.136.115 1198
#US New York City
;remote 209.95.50.127 1198
#US Seattle
;remote 104.200.154.67 1198
#US Silicon Valley
;remote 104.156.228.134 1198
#US Texas
;remote 162.216.46.86 1198
#US West
;remote 104.200.151.43 1198
resolv-retry infinite
nobind
persist-key
persist-tun
cipher aes-128-cbc
auth sha1
tls-client
remote-cert-tls server
comp-lzo
verb 1
reneg-sec 0
crl-verify crl.rsa.2048.pem
ca ca.rsa.2048.crt
disable-occ
--script-security 2
up /etc/openvpn/update-resolv-conf
down /etc/openvpn/update-resolv-conf
keepalive 10 60

To select a VPN server, uncomment (remove the semi-colon) in front of the server you wish to use. If you uncomment more than one server, this configuration will randomly select a server from the uncommented servers every time it connects.

Configuring Credentials

Create a text file in your home directory called .pia_auth and put your PIA username and password on separate lines:

$ echo PIAUsername > ~/.pia_auth
$ echo SecretPIAPassword >> ~/.pia_auth

Don’t forget to change the values for your username and password above to the ones you use for your account.

Add the username and password file to the PIA configuration file for OpenVPN:

$ echo auth-user-pass ~/.pia_auth | sudo tee --append /etc/openvpn/pia.conf

You can now test the VPN by typing:

$ sudo openvpn /etc/openvpn/pia.conf

If everything went well, it should successfully connect. You can cancel the connection with ctrl-c.

Starting Private Internet Access on Start-up

Edit the file/etc/default/openvpn

$ sudo nano /etc/default/openvpn

and add the line

AUTOSTART="pia"

below the other lines starting with #AUTOSTART. Now, when you start the server, it will automatically start the VPN. You should restart the server now and then use the ifconfig command to check the VPN is running.

$ sudo shutdown -r now

*** Wait for Reboot ***

$ sudo service openvpn start

Configuring UFW to Block All Traffic Except OpenVPN

Locate the Name of Your Ethernet

$ sudo ifconfig

Look for the entry that starts with ‘ens’ or ‘eth’. My server has ‘ens18’, but ‘eth0’ is standard. Remember this for the firewall rules below. Where I use ‘ens18’, you should replace it with the value for your ethernet card.

Allow Incoming SSH Connections on the Local Ethernet

$ sudo ufw allow in on ens18 to any port 22 proto tcp

Disable IPV6

Edit the file /etc/sysctl.conf:

$ sudo nano /etc/sysctl.conf

and add the following lines at the end of the file:

net.ipv6.conf.all.disable_ipv6 = 1
net.ipv6.conf.default.disable_ipv6 = 1
net.ipv6.conf.lo.disable_ipv6 = 1

Block IPV6 and All Incoming and Outgoing Connections

Edit /etc/default/ufw:

$ sudo nano /etc/default/ufw

Change the appropriate lines in the configuration file to match below:

IPV6=no
DEFAULT_INPUT_POLICY="DROP"
DEFAULT_OUTPUT_POLICY="DROP"
DEFAULT_FORWARD_POLICY="DROP"

Save and quit. Then restart your firewall with the following commands:

$ sudo ufw disable
$ sudo ufw enable

Allow Outbound VPN Connections

$ sudo ufw allow out on ens18 to any port 1198 proto udp

Allow Traffic Over the VPN Link

To allow outgoing connections over the VPN link, add the following UFW rule:

$ sudo ufw allow out on tun0 to any

To allow specific incoming connections on the VPN link, you need to specify the port number and be sure to specify the interface name for the VPN link. For example, you might want qBittorrent to accept incoming connections when downloading Ubuntu ISOs. Replace the 8999 in the command below with the port number your service is listening to.

$ sudo ufw allow in on tun0 to any port 8999 proto tcp
$ sudo ufw allow in on ens18 to any port 8080 proto tcp

Finally, restart the computer to make sure all of the changes have taken place.

$ sudo shutdown -r now

When the computer has restarted, you can check that the VPN is running from the command line with:

$ sudo ifconfig
tun0 Link encap:UNSPEC HWaddr 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00 
 inet addr:10.55.10.6 P-t-P:10.55.10.5 Mask:255.255.255.255
 UP POINTOPOINT RUNNING NOARP MULTICAST MTU:1500 Metric:1
 RX packets:1249926 errors:0 dropped:0 overruns:0 frame:0
 TX packets:1073005 errors:0 dropped:1 overruns:0 carrier:0
 collisions:0 txqueuelen:100 
 RX bytes:1704370992 (1.7 GB) TX bytes:57204011 (57.2 MB)

You should see output similar to above that lists the details for an interface called ‘tun0’.

Making Sure It Stays Running

To make sure the VPN stays running, I created this script which tests connectivity to PIA’s DNS server. If the connection fails, the VPN is restarted. I added this to s CRON job to check every 5 minutes.

#!/bin/bash
# Set LOG to true to have the status of the VPN logged to the file specified at LOGPATH
LOG=false

# Specify the file name for where the VPN status should be logged to
LOGPATH="/var/log/vpncheck.log"

function log
{
    if [ ${LOG} = true ] ; then
        DATE=`/bin/date`
        /usr/bin/sudo /bin/echo "${DATE} ${1}" >> ${LOGPATH}
    fi
    /usr/bin/sudo /bin/echo ${1}
}

/bin/ping -c 1 -I tun0 -q resolver1.privateinternetaccess.com. 2>&1 >/dev/null
if [[ $? -ne 0 ]] ; then
    /usr/bin/sudo /usr/sbin/service openvpn restart # user must have root access permitted by sudo for this to work
    log "VPN RESTARTED"
else
    log "VPN OK"
fi

In order for this script to work properly, you will need access to SUDO and have it set not to need a password. Alternatively, you can run it as root.

Leave a Reply

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

This site uses Akismet to reduce spam. Learn how your comment data is processed.