Setting Up Secure OpenVPN on Ubuntu Server

With Defcon right around the corner, it’s time to ensure that you can take advantage of the ‘Most Hostile Network On the Planet’ at the conference without risking being compromised within seconds of connecting.

For this guide you will need to be running the latest LTS version of Ubuntu Server and have external UDP access to port 1198 configured for the server in your network firewall. If setting this up in a home or office network; port forward UDP port 1198 to the server running OpenVPN in the router firewall settings.

1. Ensure that your installation of Ubuntu Server 16.04 is fully updated

sudo apt-get update
sudo apt-get upgrade

2. Install OpenVPN and Easy-RSA

Privileges must be escalated to root for the remainder of the installation, configuration and key generation portions of the guide. Once OpenVPN has been fully configured and client device keys packaged for transit to the client systems, you may return to normal user permissions. Escalate privileges to root user by issuing the sudo su command and providing your user password.

NOTE: Ensure that your terminal session indicates the user is root in the command line.

sudo su

Install the openvpn and easy-rsa packages using the apt-get command.

apt-get install openvpn easy-rsa

Extract the template OpenVPN configuration file and place in /etc/openvpn/ folder.

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

Create the Certificate Authority directory at /etc/openvpn/easy-rsa/ with the make-cadir command and navigate to the newly created certificate authority folder.

make-cadir /etc/openvpn/easy-rsa
cd /etc/openvpn/easy-rsa

Create a symlink for the /etc/openvpn/easy-rsa/openssl-1.0.0.cnf file to /etc/openvpn/easy-rsa/openssl.cnf within the /etc/openvpn/easy-rsa/ certificate authority folder.

ln -s /etc/openvpn/easy-rsa/openssl-1.0.0.cnf /etc/openvpn/easy-rsa/openssl.cnf

3. Configure the OpenVPN Server Settings

Modify the /etc/openvpn/server.conf file so that it points to the correct certificate authority certificate and keys which will be created later in this guide and enable Diffie-Hellman key exchange 4096bit certificate.

NOTE: The /etc/openvpn/server.conf file can be edited using vi, vim or nano (GNU Pico) text editors. If you are new to editing text files from the command line, the nano text editor is more user friendly than vi or vim (albeit less feature rich in its operation).

ca /etc/openvpn/easy-rsa/keys/ca.crt
cert /etc/openvpn/easy-rsa/keys/server.crt
key /etc/openvpn/easy-rsa/keys/server.key
dh /etc/openvpn/dh4096.pem

Harden OpenVPN Settings Within the /etc/openvpn/server.conf File

While modifying the /etc/openvpn/server.conf file, harden OpenVPN’s data channel to use better encryption by adding the cipher line to the configuration file. For this example we will be using the AES-256-CBC cipher.

cipher AES-256-CBC

Enhance the data channel’s authentication digest by upgrading it to SHA512 by adding the auth line to the configuration file.

auth SHA512

To further harden OpenVPN from attackers, require keyed-hash message authentication code (HMAC) by adding the tls-auth line to the configuration file. This line points to a ta.key file which will be created following the client key generation portion of this guide.

tls-auth /etc/openvpn/easy-rsa/keys/ta.key 0

Un-comment the user and group lines, and set the user to openvpn_server. This will force client connections to use a restricted user account and will reduce the client’s privileges on the server itself.

user openvpn_server
group nogroup

Restrict the OpenVPN control channel to use only strong cipher suites. It is recommended to be as restrictive as possible, but be aware that not all cipher suites can be used with all versions of OpenVPN.

Limit the cipher pool to AES in GCM mode over TLS 1.2 using SHA256 and both AES and Camellia in CBC mode using SHA1 over TLS 1.0. Do this by adding the tls-cipher line to the configuration file.

tls-cipher TLS-DHE-RSA-WITH-AES-256-GCM-SHA384:TLS-DHE-RSA-WITH-AES-128-GCM-SHA256:TLS-DHE-RSA-WITH-AES-256-CBC-SHA:TLS-DHE-RSA-WITH-CAMELLIA-256-CBC-SHA:TLS-DHE-RSA-WITH-AES-128-CBC-SHA:TLS-DHE-RSA-WITH-CAMELLIA-128-CBC-SHA

A completed /etc/openvpn/server.conf file is presented below as an example of a properly configured and hardened server configuration.

# /etc/openvpn/server.conf

port 1194
proto udp
dev tun
ca /etc/openvpn/easy-rsa/keys/ca.crt
cert /etc/openvpn/easy-rsa/keys/server.crt
key /etc/openvpn/easy-rsa/keys/server.key
tls-auth /etc/openvpn/easy-rsa/keys/ta.key 0 
dh /etc/openvpn/dh4096.pem
server 10.8.0.0 255.255.255.0
ifconfig-pool-persist ipp.txt
keepalive 10 120
comp-lzo
user openvpn_server
group nogroup
persist-key
persist-tun
status openvpn-status.log
verb 3
auth SHA512
cipher AES-256-CBC 
tls-cipher TLS-DHE-RSA-WITH-AES-256-GCM-SHA384:TLS-DHE-RSA-WITH-AES-128-GCM-SHA256:TLS-DHE-RSA-WITH-AES-256-CBC-SHA:TLS-DHE-RSA-WITH-CAMELLIA-256-CBC-SHA:TLS-DHE-RSA-WITH-AES-128-CBC-SHA:TLS-DHE-RSA-WITH-CAMELLIA-128-CBC-SHA

The user specified in the /etc/openvpn/server.conf file must be created on the system for privilege restrictions to function correctly.

Add the user ‘openvpn_server‘ with the following command in the terminal:

adduser --system --shell /usr/sbin/nologin --no-create-home openvpn_server

4. Creating Keypairs

Create the Diffie-Hellman PEM certificate using OpenSSL’s certificate generation capabilities by running the openssl dhparm 4096 command.

openssl dhparam 4096 > /etc/openvpn/dh4096.pem

Navigate to the /etc/openvpn/easy-rsa/ folder and modify the vars file. This file contains all the default organization information which will be used when generating the root certificate and key pairs.

NOTE: Not all of the options must be used, but there must be something in each field to prevent breakage of the key generation script. If valid options are not available, false values can be provided.

# These are the default values for fields
# which will be placed in the certificate.
# Don’t leave any of these fields blank.
export KEY_COUNTRY=”US”
export KEY_PROVINCE=”AZ”
export KEY_CITY=”Phoenix”
export KEY_ORG=”XipherZero”
export KEY_EMAIL=”me@myself.mydomain”
export KEY_OU=”MyCompany”

Use the source command to inform the key generation scripts to use the variables you setup in vars file. Once this is done, the ./clean-all command can be run to ensure that the /etc/openvpn/easy-rsa/keys/ directory is cleared of any obsolete keys.

NOTE: Key generation commands must be run from within the /etc/openvpn/easy-rsa/ directory. Attempts to run these commands elsewhere will fail.

IMPORTANT: Running the ./clean-all command will delete any previously generated keys within the /etc/openvpn/easy-rsa/keys/ folder.

cd /etc/openvpn/easy-rsa/
source ./vars
./clean-all

Issue the ./build-ca command to generate a root certificate for the certificate authority. A root certificate is the certificate used to generate client keypairs. During the root certificate generation process you will be prompted to verify the values which you created in the vars file. Press the ENTER key to proceed to the next value.

Once the root certificate generation process has confirmed all values from the vars file, confirm the certificate generation making sure to leave the challenge password blank.

./build-ca

Create the server’s private key using the ./build-key-server server command. You will be prompted to verify the values which were created in the vars file. Complete the server key generation in the same manner as was used when generating the root certificate.

./build-key-server server

Each client device connecting to the VPN should have its own unique key client certificate and key. Each client certificate and key should have its own unique name. When generating the client certificate and key information, validate the information contained in the vars file the same as when generating the root certificate and system keys.

NOTE: Additional users will require new keys be generated using this same command, but substituting the new user name.

Keys generated using the ./build-key command can be used to connect to the VPN by anyone that acquires the keys. Ensure that the user is aware of this issue and maintains control of the client keys.

In the example below, the user name client1 is used for illustrative purposes.

cd /etc/openvpn/easy-rsa
source ./vars && sudo ./build-key client1

For added security the client certificates and keys can be generated with the ./build-key-pass instead of the ./build-key command which will add a passphrase to the key which must be entered by the client when configuring their OpenVPN client software or when connecting to the OpenVPN server.

In the example below, the user name client1 is used for illustrative purposes.

cd /etc/openvpn/easy-rsa 
source ./vars && sudo ./build-key-pass client1

Create the ta.key which will be used for keyed-hash message authentication code (HMAC) during TLS authentication using the openvpn –genkey –secret command.

openvpn --genkey --secret /etc/openvpn/easy-rsa/keys/ta.key

Once all key files have been generated, enable and restart the OpenVPN service to complete the configuration process using the systemctl command.

systemctl enable openvpn
systemctl start openvpn
systemctl restart openvpn

 

5. Package Client Keys and Necessary Files

Package the necessary client files into a tarball for transferring to client workstations. The tarball will be created in the directory where the tar command is run.

NOTE: Ensure that if you used custom client identifiers for the key names during the client key generation process, that you adjust the tar command to include the correct client certificate and key filenames.

The specific files being packaged for the client workstations are:

In the example below, the user name client1 is used for illustrative purposes.

/etc/openvpn/easy-rsa/keys/ca.crt
/etc/openvpn/easy-rsa/keys/client1.crt
/etc/openvpn/easy-rsa/keys/client1.key
/etc/openvpn/easy-rsa/keys/ta.key
sudo tar -C /etc/openvpn/easy-rsa/keys -cvzf ./$CLIENT.tar.gz {ca.crt,$CLIENT.crt,$CLIENT.key,ta.key}

6. Modify IPTables to Allow VPN Users to Access External Networks Through VPN

Allow UDP connections to the openvpn port. Ensure that the network interface provided in the command matches the network interface which you have connected to your external network connection. The example below uses the eth0 interface.

sudo iptables -A INPUT -i eth0 -m state --state NEW -p udp --dport 1194 -j ACCEPT

Allow TUN interface connections to OpenVPN server.

sudo iptables -A INPUT -i tun+ -j ACCEPT

Allow TUN interface connections to be forwarded through other interfaces

sudo iptables -A FORWARD -i tun+ -j ACCEPT
sudo iptables -A FORWARD -i tun+ -o eth0 -m state --state RELATED,ESTABLISHED -j ACCEPT
sudo iptables -A FORWARD -i eth0 -o tun+ -m state --state RELATED,ESTABLISHED -j ACCEPT

Enable Network Address Translation (NAT) for the VPN client traffic from the TUN interfaces to the external Internet.

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

Set the default iptables OUTPUT value to ACCEPT output from the TUN interfaces.

sudo iptables -A OUTPUT -o tun+ -j ACCEPT

Restart the iptables service with the service command to load the new modified configuration.

sudo service iptables restart

7. Configure Linux Client Device to Use the OpenVPN Server

Copy the packaged archive created earlier which contains the client certificates and keys to the local Linux device. Create a folder where the keys will be kept.

As an example, you can create a folder under /opt called vpn-keys which will prevent accidental deletion by the user. Change the ownership of this folder to the main user account which will be using the VPN so that that account can access the VPN certificates and keys.

sudo mkdir /opt/vpn-keys
sudo chown $USER.$GROUP /opt/vpn-keys

Extract the tarball package within folder using the tar command.

cd /opt/vpn-keys
tar xfz $CLIENT.tar.gz

Ensure that the OpenVPN setting configuration for Network Manager is installed on the system.

sudo apt-get install network-manager-openvpn

Open network manager by right clicking on the network icon in the upper right portion of the screen and select ‘Configure Network Connections’. This opens the network configuration settings where the OpenVPN server can be added.

Select the + (Plus) button in the left pane to create a new connection and select OpenVPN from the list that is presented. Select the Create button to open the new connection window.

Within the new connection window choose a name for the Connection, set the gateway to the IP address or DNS name of the server running OpenVPN and leave the Connection type as Certificate (TLS). Select the browse button for each certificate and key and navigate to the location where the VPN certificates and keys were extracted and set each one accordingly.

NOTE: If you generated the client device certificates and keys with a passphrase, ensure that the passphrase is entered in the ‘Private Key Password” field.

Select the Advanced Button and enable the following options under the General tab:

Select the Security tab and set the options as follows:

Select the TLS Settings tab and enable the use of additional TLS authentication. Ensure that the Key Direction is set to “Client (1)“.

Select the OK button at the bottom of the window to return to the Connection Settings window and then select the OK button to close.

You are now able to test the VPN connectivity and functionality by right clicking on the network icon in the upper right portion of the screen and selecting the newly added VPN connection.

Leave a Reply

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