Practice
Want to have safe and secure access to the Internet from your smartphone or laptop when connecting to an unsecured network over a hotel or café's WiFi? A Virtual Private Network (VPN) lets you use unsecured networks as if you were working on a private network. In this case, all of your traffic passes through a VPN server.
Combined with the use of an HTTPS connection, the setup described further below will let you protect your private information, such as logins and passwords, as well as your purchases. Moreover, you'll be able to bypass regional restrictions and censorship, and hide your location and unencrypted HTTP traffic from an unsecured network.
OpenVPN is a powerful, flexibly configurable, open-source piece of software for working with Secure Socket Layer (SSL) VPNs. In this article, we'll install and configure an OpenVPN server, and learn how to access it from Windows, Mac OS, iOS, and Android. To do this, we'll go through several simple steps.
First of all, you need a server running Ubuntu 16.04.
Before you start following the steps described in this article, you need to set up a separate, non-root user profile with
When you're ready to begin, log in to your server as the
First, let's install OpenVPN on our server. OpenVPN is available in the standard Ubuntu repositories, so we can use
Let's update the server's package list and install the necessary packages with the following commands:
The necessary software is now installed and ready to be configured.
OpenVPN is a virtual private network that uses TLS/SSL. This means OpenVPN uses certificates to encrypt traffic between the server and clients. To issue trusted certificates, we'll need to create our own certificate authority.
First, let's copy the
Next, let's go into this directory to begin configuring the certificate authority:
To configure our certificate authority's variables, we need to edit the
Inside the file you'll find variables that can be edited and that set the parameters used when certificates are created. We only need to change a few variables.
Scroll near the end of the file and find the default field settings used when creating certificates. They should look something like this:
. . . export KEY_COUNTRY="US" export KEY_PROVINCE="CA" export KEY_CITY="SanFrancisco" export KEY_ORG="Fort-Funston" export KEY_EMAIL="me@myhost.mydomain" export KEY_OU="MyOrganizationalUnit" . . .
Replace the highlighted values with something else — don't leave them blank:
. . . export KEY_COUNTRY="US" export KEY_PROVINCE="NY" export KEY_CITY="New York City" export KEY_ORG="DigitalOcean" export KEY_EMAIL="admin@example.com" export KEY_OU="Community" . . .
While we're in this file, let's edit the
export KEY_NAME="server"
Save and close the file.
Now we can use the variables we set and the
Make sure you're in the certificate authority directory, and
You should see the following output:
NOTE: If you run ./clean-all, I will be doing a rm -rf on /home/sammy/openvpn-ca/keys
Let's make sure we're working in a "clean environment" by running the following command:
Now we can create our root certificate authority with the command:
This command will start the process of creating the root certificate authority's key and certificate. Since we set all the variables in the
Generating a 2048 bit RSA private key ..........................................................................................+++ ...............................+++ writing new private key to 'ca.key' ----- You are about to be asked to enter information that will be incorporated into your certificate request. What you are about to enter is what is called a Distinguished Name or a DN. There are quite a few fields but you can leave some blank For some fields there will be a default value, If you enter '.', the field will be left blank. ----- Country Name (2 letter code) [US]: State or Province Name (full name) [NY]: Locality Name (eg, city) [New York City]: Organization Name (eg, company) [DigitalOcean]: Organizational Unit Name (eg, section) [Community]: Common Name (eg, your name or your server's hostname) [DigitalOcean CA]: Name [server]: Email Address [admin@email.com]:
Now we have a certificate authority, which we can use to create all the other files we need.
Next, let's create a certificate, a key pair, and some additional files used for encryption, for our server.
Let's start by creating the OpenVPN certificate and keys for the server. This can be done with the following command:
Warning: If you previously chose a name other than
The output will again contain the defaults passed to this command (
Accept all the default values by pressing ENTER. Do not set a challenge password. At the end of the process, enter y twice to sign and confirm creation of the certificate:
. . . Certificate is to be certified until May 1 17:51:16 2026 GMT (3650 days) Sign the certificate? [y/n]:y 1 out of 1 certificate requests certified, commit? [y/n]y Write out database with 1 new entries Data Base Updated
Next, let's create the remaining files. We can generate strong Diffie-Hellman parameters, used during key exchange, with the command:
This command may take a few minutes to complete.
Next we can generate an HMAC signature to strengthen the server's ability to verify TLS integrity:
Next, we can generate a certificate and key pair for the client. This could actually be done on the client machine itself, with the resulting key then signed by the server's certificate authority, but in this article, for simplicity, we'll generate a signed key on the server.
In this article, we'll create a key and certificate for just one client. If you have multiple clients, you can repeat this process as many times as you like. Just pass a unique value to the script each time.
Since we may come back to this step later, let's source the
To create files without a password for easier automated connections, use the
To create password-protected files, use the
During the file creation process, all the default values will be pre-filled, and you can press ENTER. Don't set a challenge password, and enter y at the prompts about signing and confirming creation of the certificate.
Next, let's configure the OpenVPN service using the files we created earlier.
We need to copy the files we need into the
First, let's copy the files we created. They're located in the
Next, we need to copy and unpack the sample OpenVPN configuration file into the configuration directory; we'll use this file as the base for our settings:
Now that our files are in place, let's configure the server's configuration file:
First, let's find the HMAC section by searching for the
tls-auth ta.key 0 # This file is secret key-direction 0
Next, let's find the encryption section — we're interested in the commented-out
cipher AES-128-CBC
Below this line, add an
auth SHA256
Finally, find the
user nobody group nogroup
The settings we've made create a VPN connection between two machines, but they don't force those machines to actually use the VPN connection. If you want to route all of your traffic through the VPN connection, you need to push the DNS settings to the client machines.
To do this, you need to uncomment a few directives. Find the
push "redirect-gateway def1 bypass-dhcp"
A bit further down is the
push "dhcp-option DNS 208.67.222.222" push "dhcp-option DNS 208.67.220.220"
This will let clients configure their DNS settings to use the VPN connection as their primary one.
By default, OpenVPN uses port 1194 and the UDP protocol to connect to clients. If you need to change the port due to some restrictions on your clients' side, you can do so by changing the
# Optional! port 443
The protocol you use may have restrictions on the port number. In that case, change
# Optional! proto tcp
If you don't have an explicit need to use a different port, it's best to leave both of these settings at their defaults.
If, when using the
cert server.crt key server.key
Save and close the file.
Next, we need to configure the server's network settings so that OpenVPN can correctly forward traffic.
First, let's allow the server to forward traffic. This is key functionality for our VPN server.
Let's configure this in the
Find the
net.ipv4.ip_forward=1
Save and close the file.
To apply the settings to the current session, run the command:
If you followed the article about setting up Ubuntu 16.04 mentioned at the start of this article, you should have the UFW firewall installed and configured. Regardless of whether you use the firewall to block unwanted traffic (which you should pretty much always do), in this article we need the firewall to manipulate the traffic coming into the server. We need to modify the settings file to enable masquerading.
Before modifying this file, we need to find the public network interface. To do that, run the command:
The public interface should follow the word "dev". For example, in our case, this interface is called
default via 203.0.113.1 dev wlp11s0 proto static metric 600
Now that we know the interface name, let's open the
This file contains UFW settings that are applied before UFW's own rules are applied. Add the highlighted lines to the start of the file. This will configure the default rules applied to the
Warning: don't forget to replace
# # rules.before # # Rules that should be run before the ufw command line added rules. Custom # rules should be added to one of these chains: # ufw-before-input # ufw-before-output # ufw-before-forward # # START OPENVPN RULES # NAT table rules *nat :POSTROUTING ACCEPT [0:0] # Allow traffic from OpenVPN client to eth0 -A POSTROUTING -s 10.8.0.0/8 -o eth0 -j MASQUERADE COMMIT # END OPENVPN RULES # Don't delete these required lines, otherwise there will be errors *filter . . .
Save and close the file.
Now we need to tell UFW that it should allow forwarded packets by default. To do that, open the
Find the
DEFAULT_FORWARD_POLICY="ACCEPT"
Save and close the file.
Next, let's configure the firewall itself to allow OpenVPN traffic.
If you didn't change the port and protocol in the
We'll also add the SSH port in case you haven't done so already.
Now let's disable and re-enable UFW to apply the changes we made:
Now our server is configured to handle OpenVPN traffic.
We're ready to start the OpenVPN service on our server. We can do this using systemd.
We need to start the OpenVPN server by specifying the name of our configuration file as a variable after the systemd unit's name. Our server's configuration file is called
Let's make sure the service started successfully with the command:
If everything went well, the output should look something like this:
● openvpn@server.service - OpenVPN connection to server Loaded: loaded (/lib/systemd/system/openvpn@.service; disabled; vendor preset: enabled) Active: active (running) since Tue 2016-05-03 15:30:05 EDT; 47s ago Docs: man:openvpn(8) https://community.openvpn.net/openvpn/wiki/Openvpn23ManPage https://community.openvpn.net/openvpn/wiki/HOWTO Process: 5852 ExecStart=/usr/sbin/openvpn --daemon ovpn-%i --status /run/openvpn/%i.status 10 --cd /etc/openvpn --script-security 2 --config /etc/openvpn/%i.conf --writepid /run/openvpn/%i.pid (code=exited, sta Main PID: 5856 (openvpn) Tasks: 1 (limit: 512) CGroup: /system.slice/system-openvpn.slice/openvpn@server.service └─5856 /usr/sbin/openvpn --daemon ovpn-server --status /run/openvpn/server.status 10 --cd /etc/openvpn --script-security 2 --config /etc/openvpn/server.conf --writepid /run/openvpn/server.pid May 03 15:30:05 openvpn2 ovpn-server[5856]: /sbin/ip addr add dev tun0 local 10.8.0.1 peer 10.8.0.2 May 03 15:30:05 openvpn2 ovpn-server[5856]: /sbin/ip route add 10.8.0.0/24 via 10.8.0.2 May 03 15:30:05 openvpn2 ovpn-server[5856]: GID set to nogroup May 03 15:30:05 openvpn2 ovpn-server[5856]: UID set to nobody May 03 15:30:05 openvpn2 ovpn-server[5856]: UDPv4 link local (bound): [undef] May 03 15:30:05 openvpn2 ovpn-server[5856]: UDPv4 link remote: [undef] May 03 15:30:05 openvpn2 ovpn-server[5856]: MULTI: multi_init called, r=256 v=256 May 03 15:30:05 openvpn2 ovpn-server[5856]: IFCONFIG POOL: base=10.8.0.4 size=62, ipv6=0 May 03 15:30:05 openvpn2 ovpn-server[5856]: IFCONFIG POOL LIST May 03 15:30:05 openvpn2 ovpn-server[5856]: Initialization Sequence Completed
You can also check that the
You should see the interface's configuration:
4: tun0:mtu 1500 qdisc noqueue state UNKNOWN group default qlen 100 link/none inet 10.8.0.1 peer 10.8.0.2/32 scope global tun0 valid_lft forever preferred_lft forever
If everything looks good, let's configure the service to start automatically when the server boots:
Next, let's set up a system for easily generating client configuration files.
In your home directory, create a directory structure to store the files:
Since our configuration files will contain client keys, we need to set the appropriate permissions on the directories we created:
Next, let's copy the sample configuration to our directory for use as our base configuration:
Open this file in your text editor:
Let's make a few changes to this file.
First, find the
. . . # The hostname/IP and port of the server. # You can have multiple remote entries # to load balance between the servers. remote server_IP_address 1194 . . .
Make sure the protocol matches the server's settings:
proto udp
Next, uncomment the
# Downgrade privileges after initialization (non-Windows only) user nobody group nogroup
Find the
# SSL/TLS parms. # See the server config file for more # description. It's best to use # a separate .crt/.key file pair # for each client. A single ca # file can be used for all clients. #ca ca.crt #cert client.crt #key client.key
Add the
cipher AES-128-CBC auth SHA256
Next, add the
key-direction 1
Finally, add a few commented-out lines. We want to add these lines to every configuration file, but they will only be enabled for Linux clients that use the
# script-security 2 # up /etc/openvpn/update-resolv-conf # down /etc/openvpn/update-resolv-conf
If your client runs on Linux and uses the
Save and close the file.
Now let's create a simple script for generating configuration files with the relevant certificates, keys, and encryption files. It will place the generated configuration files in the
Create and open the
Paste the following text into this file:
#!/bin/bash # First argument: Client identifier KEY_DIR=~/openvpn-ca/keys OUTPUT_DIR=~/client-configs/files BASE_CONFIG=~/client-configs/base.conf cat ${BASE_CONFIG} \ <(echo -e '') \ ${KEY_DIR}/ca.crt \ <(echo -e ' \n') \ ${KEY_DIR}/${1}.crt \ <(echo -e ' \n') \ ${KEY_DIR}/${1}.key \ <(echo -e ' \n') \ ${KEY_DIR}/ta.key \ <(echo -e ' ') \ > ${OUTPUT_DIR}/${1}.ovpn
Save and close the file.
Make it executable with the command:
Now we can easily generate client configuration files.
If you followed all the steps in this article, you created the
If everything went well, we should get a
client1.ovpn
Now we need to move the configuration file to the client device. For example, to a computer or smartphone.
How you deliver the file depends on your device's operating system and what software you want to use to transfer the file. We recommend transferring the file over a secure connection, for example using SFTP or SCP.
Below is an example of transferring the client1.ovpn file using SFTP. The following command can be used on your local computer running Mac OS or Linux. It moves the
Below are a few links to tools and articles about securely transferring files from a server to your local computer:
Now let's talk about how to install client VPN profiles on Windows, Mac OS, iOS, and Android. The installation process is unique to each platform, so skip the platforms you don't plan to use.
The name of the OpenVPN connection depends on what you named your
You can download the OpenVPN client for Windows from the OpenVPN downloads page. Choose the installer version you need.
Warning: installing OpenVPN requires an administrator account.
After installing OpenVPN, copy your
C:\Program Files\OpenVPN\config
Launch OpenVPN, and the client should automatically detect your profile.
The OpenVPN client requires running with administrator rights, even for administrator accounts. To launch it, right-click the client and select Run as administrator every time you start the client. This also means that regular users will have to enter the administrator password to use OpenVPN.
To have the OpenVPN application always launch with administrator rights, right-click the client's icon and go to Properties. At the bottom of the Compatibility tab, click Change settings for all users. In the window that opens, select Run this program as an administrator.
Every time you launch the OpenVPN client, Windows will ask whether you want to allow the program to make changes to your computer. Click Yes. Launching the OpenVPN client simply places the application in the system tray; the connection itself is not established automatically.
To establish a connection, right-click the OpenVPN icon in the system tray. In the context menu that opens, select client1 (this is our
A status window will open showing the connection log. When the connection is established, you'll see a corresponding message.
You can close the VPN connection the same way: right-click the OpenVPN icon in the system tray, select the client profile, and click Disconnect.
Tunnelblick is a free, open-source OpenVPN client for Mac OS. You can download it from the Tunnelblick downloads page. Double-click the downloaded
At the end of the installation process, Tunnelblick will ask if you have configuration files. The easiest option is to answer No and finish the Tunnelblick installation. Open Finder and double-click
Launch Tunnelblick by double-clicking it from the Applications folder. Once launched, the Tunnelblick icon will appear in the menu bar at the top right of the screen. To establish a connection, click the icon, then click Connect. Then select the client1 connection.
Depending on the Linux distribution you're using, you can use a wide variety of programs to establish the connection. Your window manager may even be able to do this itself.
The most universal way to establish the connection, however, is the OpenVPN software.
On Ubuntu or Debian, you can install it exactly the same way as on the server:
On CentOS, you can enable the EPEL repository and then run the following commands:
First, check whether your distribution includes the
update-resolve-conf
Next, edit the OpenVPN client configuration file you received from the server:
If you were able to find the
script-security 2 up /etc/openvpn/update-resolv-conf down /etc/openvpn/update-resolv-conf
If you're using CentOS, change
group nobody
Save and close the file.
Now you can connect to the VPN using the
As a result, you'll be connected to the server.
Search for the official OpenVPN Connect client in the iTunes App Store and install it. To transfer the client configuration file to your device, connect the device to your computer.
Launch iTunes on your computer and select iPhone > apps. Find the File Sharing section and click the OpenVPN app. Drag your

Next, launch the OpenVPN app on your iPhone. You'll get a notification that a new profile is ready to be imported. Tap the green plus icon to import the profile.

OpenVPN is now ready to use with the new profile. To establish a connection, slide the Connect slider to the On position. To stop the connection, move the same slider to the Off position.

Open the Google Play Store. Find and install the official OpenVPN Android app, OpenVPN Connect.
You can transfer the profile from your computer to your phone by connecting the Android device to your computer via USB and copying the file. You can also transfer the profile file using an SD card, by copying the profile onto the card and inserting the card into the Android device.
Launch the OpenVPN app and tap the menu to import the profile.

Next, find the file in the file system (in our example this is

To establish a connection, click the Connect button. You'll be asked whether you trust the OpenVPN app. Answer OK to establish the connection. To stop the connection, go into the OpenVPN app and select Disconnect.

Now that everything is installed and configured, let's make sure everything is working correctly. Without establishing a VPN connection, open a browser and go to DNSLeakTest.
This site will return the IP address assigned to you by your Internet provider. To check which DNS servers are being used, click Extended Test.
Now establish a connection using your VPN client and refresh the page in your browser. The IP address shown to you should be completely different. Now, to everyone on the Internet, you're using this new IP address. Click Extended Test again to check your DNS settings and make sure you're now using your VPN's DNS servers.
From time to time, you may need to revoke a client certificate to prevent access to the VPN server.
To do this, go into your certificate authority directory and enter the commands:
Next, use the
The output of this command will end with error 23. This is normal. As a result, a
Move this file to the
Next, open the OpenVPN server's configuration file:
Add the
crl-verify crl.pem
Save and close the file.
Restart OpenVPN to complete the certificate revocation process:
Now the client will no longer be able to establish a connection to the OpenVPN server using the old certificate.
To revoke additional certificates, follow these steps:
Generate a new certificate revocation list by running
Copy the new certificate revocation list to the
Restart the OpenVPN service.
This procedure can be used to revoke any certificates you've created previously.
Congratulations! You can now safely browse the Internet, with all of your traffic protected from eavesdropping by censors and attackers.
To configure additional clients, repeat steps 6 and 11-13 for each new device. To revoke access for a given client, use step 14.
Comments