HOW-TO Set up a Privateinternetaccess client on OpenVPN

This How-To explains how to set up a Privateinternetaccess (PIA) client on FreeBSD using OpenVPN. This setup focuses on having PIA OpenVPN run from startup of your machine.

I assume the following
1. you have a running FreeBSD system
2a. you have ports installed or
2b. you have the package tools installed
3. you are willing and able to use a Terminal to issue some basic commands as root (or sudo if you have it installed)

If you need more information on using the ports or pkg(8) command to install applications – see the FreeBSD handbook (chapter 4) here

1. install the security/openvpn package
2. download the PIA certificates and basic configuration files
3. configure /etc/rc.conf to load OpenVPN at startup
4. create the PIA user authentication file
5. configure the OpenVPN config file
6. test the setup
7. miscellaneous comments

References for the OpenVPN setup info
- website
- and the PIA Linux setup files at
- and
- FreeBSD handbook (for installation, ports and package tools)

- a valid PIA username and password (apply online at
- security/openvpn installed package or port installed on FreeBSD
- the PIA ca.crt and crl.pem certificates; the other set up parameters will be discussed below

1. TO INSTALL OPENVPN, go to the Terminal as root and issue the command as below answer Yes to all the prompts. I prefer to use the pkg installation method for ease; use whichever suits you best. The OpenVPN port can be found under /usr/ports/security/openvpn
# pkg install openvpn

2. TO GET THE PIA ca.crt and crl.pem CERTIFICATES from the PIA site- download the zip file, which also contains actual server specific configuration files which we will use later to customize the configuration. Using the command line download into a designated directory.
2.1 Create a directory where you wish to download the zip files using
# mkdir -p /usr/local/etc/openvpn

2.2. Unzip the contents of the downloaded folder and find the ca.crt and crl.pem files
# cd /usr/local/etc/openvpn
# fetch --no-verify-peer
# tar -xvf

2.3. Copy the ca.crt and crl.pem files to the PIA directory that will contain the config files, at say /usr/local/etc/pia_openvpn. As long as you know where the files are so you can point your config parameters to the location.
# mkdir -p /usr/local/etc/pia_openvpn
# cp ca.crt crl.pem /usr/local/etc/pia_openvpn/

3. CONFIGURE /etc/rc.conf

To load OpenVPN at start up you need to edit /etc/rc.conf I am using the text editor ee(1) (as it comes installed with FreeBSD or you can use vi(1) or another editor of your choice like editors/nano – just install nano via pkg install nano On ee press escape to get to menus to save and exit)
# ee /etc/rc.conf

Add this to /etc/rc.conf – note that comments in the config text files are indicated by #, just make sure the syntax is correct.
# To enable openvpn from start up with tun activated
#this last line specifies where you will set up the openvpn config file as indicated below so that openvpn can find it when it executes

Create a password_pia file in /usr/local/etc/pia_openvpn from Terminal
# touch /usr/local/etc/pia_openvpn/password_pia.txt
You can also just open CMD]ee[/CMD] and CMD]nano[/CMD] to create the file and save it in the directory, without touch

Enter your your PIA user name and password into the password text file created above. Put the entries on separate lines in the file, like so

Make sure there is nothing else in the password file
Use the command below to make it readable by root only – for security reasons
# chmod 600 /usr/local/etc/pia_openvpn/password_pia.txt

Copy one of the sample config files from where you downloaded them - #/usr/local/etc/openvpn, I will use the US EAST.ovpn file as included in the downloaded zip file from PIA. You can use anyone of them as they contain the same set up parameters. They only differ in the server name. In the command below I copy the file and rename it.
# cp /usr/local/etc/openvpn/“US East.ovpn” /usr/local/etc/pia_openvpn/pia_vpn.conf

Now to set up the pia_vpn.conf file... we are almost there!
Using the /usr/local/etc//pia_openvpn/pia_vpn.conf file which was copied from US East.ovpn file. It looks like like this before amendments
dev tun
proto udp
remote 1194
resolv-retry infinite
ca ca.crt
remote-cert-tls server
verb 1
reneg-sec 0
crl-verify crl.pem

NOW TO CUSTOMIZE pia_vpn.conf file under /usr/local/etc/pia_openvpn/
# ee /usr/local/etc/pia_openvpn/pia_vpn.conf
The customisation is as below; I've added #comments to explain it a bit

#your PIA clientconfig file under /usr/local/etc/pia_openvpn/pia_vpn.conf

dev tun
#make sure the correct protocol is used
proto udp
# use the vpn server of your choice; rather put the name of the server in then the IP address;
# the ip addresses change frequently
remote 1194

# you can add other servers here and comment them out in case you want to change servers later
# you can do this as your username and password stays the same
# But only use one server at a time, you must comment out the one above before activating the ones below
#remote 1194
#remote 1194
#remote 1194

resolv-retry infinite

# copy the ca.crt files to wherever you wish to store them in /usr/local/etc/pia_openvpn
# but you must specify where to find the file example:
ca /usr/local/etc/pia_openvpn/ca.crt
crl-verify  /usr/local/etc/pia_openvpn/crl.pem

remote-cert-tls server

#indicate where you have stored the password file if you want to log in from boot example:
auth-user-pass /usr/local/etc/pia_openvpn/password_pia.txt
# and make it only readable by root with: chmod 600 filename

#this suppresses the caching of the password and user name

verb 1
reneg-sec 0

You can start and test the PIA client connection via terminal as sudo or as root
# openvpn --config /usr/local/etc/pia_openvpn/pia_vpn.conf

The output should resemble something like this:
Sun Dec 27 09:06:07 2015 OpenVPN 2.3.9 amd64-portbld-freebsd10.1 [SSL (OpenSSL)] [LZO] [MH] [IPv6] built on Dec 22 2015

Sun Dec 27 09:06:07 2015 library versions: OpenSSL 1.0.1l-freebsd 15 Jan 2015, LZO 2.09
Sun Dec 27 09:06:08 2015 UDPv4 link local: [undef]
Sun Dec 27 09:06:08 2015 UDPv4 link remote: [AF_INET]
Sun Dec 27 09:06:09 2015 [Private Internet Access] Peer Connection Initiated with [AF_INET]
Sun Dec 27 09:06:12 2015 TUN/TAP device /dev/tun0 opened
Sun Dec 27 09:06:12 2015 do_ifconfig, tt->ipv6=0, tt->did_ifconfig_ipv6_setup=0
Sun Dec 27 09:06:12 2015 /sbin/ifconfig tun0 mtu 1500 netmask up
add net gateway
add net gateway
add net gateway
add net gateway
Sun Dec 27 09:06:12 2015 Initialization Sequence Completed


I tested the set up on a:

-FreeBSD VM – it didn't boot into the VPN connection directly but only when I issued the command under TEST THE SETUP. I suspect its the way I connect to my network via the bridge adapter on Virtualbox. If anyone can shed light on this I would appreciate it?

-PC-BSD loaded laptop booting straight from disk. It connects to the VPN straight away. You will see the
interface and IP address it connects to once you issue the command below
# ifconfig

-Linux Mint (on Linux you will have to consult the distro help files / forums to find out where you must store the OpenVPN config files. It seems to vary between distros(?)).

I think the Openvpn basic set up to connect to PIA as a client will also work with other VPN providers as long as you get the user name, password, protocols, compression, and other security settings. You can just amend the config files for OpenVPN under /usr/local/etc/pia_openvpn/pia_vpn.conf

Hope this helps

Edits Jan 11,2016

  • Removed - 2.1. Ensure you have wget installed, run as root
  • # pkg install wget
  • Changed numbering under section 2
  • Replaced wget instructions to get the file with fetch command
  • Amended previous location of file from "Copy the ca.crt and crl.pem files to /etc or a directory say under /etc/pia_openvpn." to /usr/local/etc/pia_openvpn
  • Made changes to the file locations under section 2 to simplify for new user where to copy and set up files to
  • Removed and simplified some aspects of section 5
Last edited by a moderator:
For some reason, my ISP's DNS servers (configured with DHCP on boot of my FreeBSD system) do not work after starting the OpenVPN PIA tunnel. I found one way to get around this is to have the dhclient.conf file 'prepend' the DNS servers of your choice ahead of what your ISP thinks you should use for DNS. If you need more info, read the dhclient.conf(5) man page.

I edited my dhclient.conf file to say:

interface "re1" {
           prepend domain-name-servers;
           prepend domain-name-servers;

In my case, my WAN side interface is re1. Yours might be another interface.

This drops in the OpenDNS server addresses ahead of anything my ISP does when assigning my WAN IP via DHCP. As a result, I don't lose name resolution when I bring up my PIA tunnel. Changing the dhclient.conf file also 'sticks' through a reboot of my FreeBSD system. You may be able to use another publicly available DNS server like Google's, etc., but I prefer to use OpenDNS' servers.
Last edited by a moderator:
For some reason, my ISP's DNS servers (configured with DHCP on boot of my FreeBSD system) do not work after starting the OpenVPN PIA tunnel...
Most likely because they are configured to only answer requests from your ISP's private networks. And once your VPN is up your requests come through your PIA-provided public address elsewhere.
I really like this article and refer to it from time to time when setting up a FreeBSD machine. However, I found that I was still encountering a DNS leak. I did the following to resolve this:

1. Add the PIA nameservers to /etc/resolv.conf (Look under the DNS Leak Protection section of this page)
2. Set the system immutable flag on /etc/resolv.conf

# chflags schg /etc/resolv.conf

I think that does it. You can test at

Hope this helps others with the same issue.
Thanks for this.

I used to use PIA and was pretty happy with the service. I am with a different VPN provider now just because of pricing. With both I often need to change my VPN exit point, chasing the best speed. For this reason I tend to let each device that needs VPN run its own client, as it's much easier to change settings via the various GUIs than to log in to the firewall, then make a global change that may disrupt connections already in place.
PeteDana: This is a model of documentation. I'm going to keep it handy for configuring PIA on FreeBSD and also as an example of how to write clear docs. Thank you very much.
I am getting Options error: --up script fails with /etc/openvpn/update-resolv-conf: no such file or directory (errno=2)

The file exists and I have permissions for it... ideas?
Is there a simple way to change which server you are using? In other words I am currently using the New York City VPN server and perhaps I would like to use the California one or the Toronto one. How can I switch over to one of those? Thanks.
-FreeBSD VM – it didn't boot into the VPN connection directly but only when I issued the command under TEST THE SETUP
Exactly the same problem. FreeBSD 12.0, vmware workstation 12, OpenVPN 2.4.6_3, but another vpn service provider.

I am not quite sure what really mitigated the problem, but that is what I had done:

1. Moved the lines in the very end of /etc/rc.conf (before End-of-file symbol)

2. Renamed the /usr/local/etc/pia_openvpn to /usr/local/etc/openvpn

3. Renamed the cert files to match the config.ovpn as follows:

...and put them all in the /usr/local/etc/openvpn
Actually, I have 3 files: ...-ca.pem, ...-cert.pem and ...-key.pem. Additionally, my config file VPN-Provider-name.ovpn had alredy contained all three certificates inside.

After that I hopelessly rebooted my VM and surprisingly found out the vpn connected and works.

Also, the one can use multiple 'remote' servers in a config.
(look for –remote host )
This can provide some redundancy. For instance, I can connect to many server in Europe, but the one of the servers I often use sometimes fails. So, I must manually change the connection. When multiple 'remote' placed in a config, the openvpn client attempts to connect to the next in the list server in a case the vpn-server fails to connect. I think, the same true for a disconnect and failure a vpn-server when my client is connected: it simply tries another server on disconnect.
My apologies to dig up this thread.

I am running FreeBSD 12.2 in Oracle VirtualBox 6.1. OpenVPN package is 2.4.9.

I have followed the the steps as described in the thread and it looks like I am able to successfully login however resolving does not seem to work.

root@FreeBSD:/usr/local/etc/pia_openvpn # openvpn --config pia_vpn.conf
Sun Nov 22 16:22:38 2020 WARNING: file '/usr/local/etc/pia_openvpn/password_pia.txt' is group or others accessible
Sun Nov 22 16:22:38 2020 OpenVPN 2.4.9 amd64-portbld-freebsd12.1 [SSL (OpenSSL)] [LZO] [LZ4] [MH/RECVDA] [AEAD] built on Oct  4 2020
Sun Nov 22 16:22:38 2020 library versions: OpenSSL 1.1.1h-freebsd  22 Sep 2020, LZO 2.10
Sun Nov 22 16:22:38 2020 CRL: loaded 1 CRLs from file /usr/local/etc/pia_openvpn/crl.pem
Sun Nov 22 16:22:38 2020 TCP/UDP: Preserving recently used remote address: [AF_INET]
Sun Nov 22 16:22:38 2020 UDP link local: (not bound)
Sun Nov 22 16:22:38 2020 UDP link remote: [AF_INET]
Sun Nov 22 16:22:38 2020 WARNING: this configuration may cache passwords in memory -- use the auth-nocache option to prevent this
Sun Nov 22 16:22:38 2020 [d37e97fd60a90edcec779ab9ca9d8fa9] Peer Connection Initiated with [AF_INET]
Sun Nov 22 16:22:39 2020 TUN/TAP device /dev/tun0 opened
Sun Nov 22 16:22:39 2020 /sbin/ifconfig tun0 mtu 1500 netmask up
add net gateway
add net gateway
add net gateway
add net gateway
Sun Nov 22 16:22:39 2020 Initialization Sequence Completed
Sun Nov 22 16:22:49 2020 event_wait : Interrupted system call (code=4)
delete net gateway
delete net gateway
delete net gateway
delete net gateway
Sun Nov 22 16:22:49 2020 /sbin/ifconfig tun0 destroy
Sun Nov 22 16:22:49 2020 SIGINT[hard,] received, process exiting

root@FreeBSD:~ # ifconfig
em0: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> metric 0 mtu 1500
    ether 08:00:27:7e:06:81
    inet netmask 0xffffff00 broadcast
    media: Ethernet autoselect (1000baseT <full-duplex>)
    status: active
lo0: flags=8049<UP,LOOPBACK,RUNNING,MULTICAST> metric 0 mtu 16384
    inet6 ::1 prefixlen 128
    inet6 fe80::1%lo0 prefixlen 64 scopeid 0x2
    inet netmask 0xff000000
    groups: lo
tun0: flags=8051<UP,POINTOPOINT,RUNNING,MULTICAST> metric 0 mtu 1500
    inet6 fe80::a00:27ff:fe7e:681%tun0 prefixlen 64 scopeid 0x3
    inet --> netmask 0xffffffff
    groups: tun
    Opened by PID 1431

I have a fair share in Slackware and have it up and running in there.

Am I missing something here ?