From wiki-ben
Jump to: navigation, search

OpenVPN is a open source VPN application that uses a unique security protocol to implement virtual private networks. Read more about it at:

Install OpenVPN

OpenVPN comes with Easy-RSA, a lightweight package for using the RSA encryption method.
The install needs to be run as root so execute sudo su

Adding apt repositiories

Lets add OpenVPN's apt repository to our own list of repositories so that we can get a more up-to-date release than what is in your distribution's repositories.
Run the following commands:

wget -O -|apt-key add -
echo "deb <osrelease> main" > /etc/apt/sources.list.d/openvpn-aptrepo.list

Where <osrelease> depends your distribution:

  • squeeze (Debian 6.x)
  • wheezy (Debian 7.x)
  • jessie (Debian 8.x)
  • lucid (Ubuntu 10.04)
  • precise (Ubuntu 12.04)
  • trusty (Ubuntu 14.04)


Now run apt-get install openvpn and let the install execute. Easy-rsa should be installed along with it, otherwise update and install your dependencies.

OpenVPN installs to /etc/openvpn.

Setting Up SSL Certificates

Lets get cryptographic.

Preparing Easy-RSA

  1. Create an Easy-RSA folder in your OpenVPN install directory
    mkdir /etc/openvpn/easy-rsa
  2. Move your Easy-RSA install to your OpenVPN install directory
    cp -r /usr/share/easy-rsa /etc/openvpn/
  3. Navigate to the Easy-RSA folder we just created
    cd /etc/openvpn/easy-rsa
  4. Edit the Easy-RSA variables file to generate keys in our new /etc/openvpn/easy-rsa directory
    nano vars
    change EASY_RSA variable to: export EASY_RSA="/etc/openvpn/easy-rsa"
    and change KEY_SIZE variable to: export KEY_SIZE=4096
    also change the default values for KEY_COUNTRY="US", KEY_PROVINCE="CA", KEY_CITY="SanFrancisco", KEY_ORG="Fort-Funston", KEY_EMAIL="[email protected]", and KEY_OU="MyOrganizationalUnit" so you don't have to do it multiple times later in the key generation process.

Building and Signing you Certificate Authority

  1. Build your certificate authority(CA):
    source ./vars
  2. During the build process it will prompt you for some name values for the CA. If you modified and sourced the vars file correctly these values should default to the ones you entered earlier.
  3. Sign your CA:
    ./build-key-server "Server_Name"
    It will prompt you for those same values. Common Name must be the same as "Server_Name" you just picked. You MUST leave the Challenge Password blank.

Creating and Signing Clients

  • For desktop clients use: ./build-key-pass "UserName"
  • For mobile clients use: ./build-key-pkcs12 "UserName"

When prompted to Enter PEM pass phrase enter a password that will be used to encrypt your private key. Make sure to remember it as you will need it each time you want to connect to your VPN. Again you MUST leave the Challenge Password blank.
You could only generate one client key and use the same certificate for every device you wanted to connect to the VPN, however each device connected to the VPN concurrently needs to have a unique certificate and username.

Build the DH parameters

Diffie Hellman parameters must be generated for the OpenVPN server. Run the following commands:

cd /etc/openvpn/easy-rsa/

This process will take the longest time to compute as it is using random numbers and looking for some specific relationships.

OpenVPN's DoS Protection

OpenVPN has build in protection against a hacker finding out your server’s address, and generating such a large number of access requests that your server crashes. By generating a HMAC key, your server wont attempt to authenticate unless it sees this static key first. Generate one by:

openvpn –-genkey –-secret keys/ta.key

Understanding your Keys

Now we will find our newly-generated keys and certificates in the keys subdirectory. Here is an explanation of the relevant files:

Filename Needed By Purpose Secret
ca.crt server + all clients Root CA certificate NO
ca.key key signing machine only Root CA key YES
dh{n}.pem server only Diffie Hellman parameters NO
server.crt server only Server Certificate NO
server.key server only Server Key YES
client1.crt client1 only Client1 Certificate NO
client1.key client1 only Client1 Key YES
client2.crt client2 only Client2 Certificate NO
client2.key client2 only Client2 Key YES
client3.crt client3 only Client3 Certificate NO
client3.key client3 only Client3 Key YES
ta.key server + all clients TA Key YES

The final step in the key generation process is to copy all files to the machines which need them, taking care to copy secret files over a secure channel like scp.

CONGRATULATIONS! You have now created all required SSL certificates needed for your VPN.

Config Files

It would take too long to go into details about everything in these files. You can find details in the resources mentioned above.

Server Config

Edit /etc/openvpn/server.conf to contain the following:

port 1194
proto udp
dev tun

ca ca.crt
cert server.crt
key server.key

dh dh4096.pem

tls-auth ta.key 0

topology subnet

# Add route for local subnet
push "route"

# all clients redirect their default network gateway through the VPN
push "redirect-gateway def1"

# DNS servers provided by
;push "dhcp-option DNS"
;push "dhcp-option DNS"
# Or Google Developers Public DNS
;push "dhcp-option DNS"
;push "dhcp-option DNS"
push "dhcp-option DNS"


keepalive 10 120

cipher AES-256-CBC


max-clients 5

user nobody
group nogroup


status /var/log/openvpn/openvpn-status.log
log /var/log/openvpn/openvpn.log
verb 3

Client Config

The following is used in a client.conf by the openVPN application on a client computer.

proto udp
dev tun

remote my-openVPN-server-IP 1194
resolv-retry infinite


user nobody
group nobody


ca ca.crt
cert client.crt
key client.key

remote-cert-tls server

tls-auth ta.key 1

cipher AES-256-CBC



verb 3

Server Firewall Setup

Choose between a simple or more secure firewall script.


Since in this setup we are routing all of the clients internet traffic through the VPN we need to be configured to deal with this traffic somehow, such as by NATing it to the internet. This can be accomplished by:

iptables -t nat -A POSTROUTING -s -o eth0 -j MASQUERADE

Note that this solution will only get things up and running. It provides no security whatsoever to your VPN Server.


Below is a link to a sample IPTables firewall that can be tweaked to control traffic passing through the VPN. This configuration includes the masquerading rules mentioned above along with additional security measures for your VPN firewall. This script includes rules to only allow systems located in the local network of the VPN can access the VPN via SSH. Additionally, VPN users cannot access the VPN Server or the Gateway Router, but do have access to all other machines in the local network, and the internet outside of the network. A commented section has been highlighted in the script for users to add additional rules to control what data is allowed through the network.

To use this script:

  1. Download and copy it to your VPN server with IPTables installed.
  2. Open the script using a text editor and update the variables listed in the USER CONFIGURATION section to match that of your network the VPN is being hosted in (see script comments for details).
  3. Execute the script with the following command: sudo ./

Status messages will print out as each section of the firewall is applied. To change the firewall, simply update the script and rerun it. The script contains logic to clear the previous firewall settings before applying the newly listed ones. If there is an error, follow the prompts given in the console with their locations in the script (a printout in the shell script is preceded with the command 'echo') and adjust the code as needed.

Script Execution and Firewall Persistance

Using The Network Interface

In order for this iptables rule to be applied every time you turn on the VPN, you can turn it into a shell script and modify /etc/network/interfaces so it will execute the script every time it initializes the network interface eth0.

iface eth0 inet dhcp
Using iptables-save

You can also use iptables-save a tool available for Debian, Ubuntu, CentOS and RHEL based distros. After executing your script run the following command to export it:

#Debian / Ubuntu
iptables-save > /etc/iptables/rules.v4
ip6tables-save > /etc/iptables/rules.v6
#RHEL / CentOS
iptables-save > /etc/sysconfig/iptables
iptables-save > /etc/sysconfig/ip6tables

You may need to mkdir the directory if this is the first use. Ensure also that these directories only have read and write permissions for sudo, and only read for others (sudo chmod 777)

Then install iptables-persistent

sudo apt-get install iptables-persistent

The installation will prompt to re-export the current iptables rules again. You can say no at this step since we just did it. The iptables-persistance will then ensure that everytime the system boots up the the iptables rules we exported above are impported and set. To update the persistence rules at a later time, simply re-export them as done initialy

To explore the iptables-save its co-tool iptables-restore and iptables-persistent. See the Iptables page for details

Enabling Forwarding

If you are running a Raspbian VPN you have to modify /etc/sysctl.conf to allow packet forwarding. Uncomment the line net.ipv4.ip_forward=1
Apply the changes we just made by executing: sysctl -p

Revoking Certificates

Using Easy-RSA

Easy-RSA handles revoking client certificates. Navigate to your Easy-RSA directory in your OpenVPN folder:

cd /etc/openvpn/easy-rsa/

Run the following to revoke the certificate for the client called 'unwanted-client':

./revoke-full unwanted-client

The index.txt file in you keys directory will be updated. You’ll see an ‘R’ (for Revoked) on the first column from the left for unwanted-client. View this with:

cat keys/index.txt

You can also examine the CRL (certificate revocation list) file with:

openssl crl -in keys/crl.pem -text

Configure OpenVPN

Now we need to configure our OpenVPN server to enable CRL verification. Add the following line to your server.conf file:

crl-verify /etc/openvpn/easy-rsa/keys/crl.pem

Reload the OpenVPN config file by:

service openvpn reload

When the crl-verify option is used in OpenVPN, the CRL file will be re-read any time a new client connects or an existing client renegotiates the SSL/TLS connection (by default once per hour). This means that you can update the CRL file while the OpenVPN server daemon is running, and have the new CRL take effect immediately for newly connecting clients.

Adding LDAP for Active Directory Authentication

LDAP is the underlying protocol of Active Directory. In an organization context where there may be multiple servers, controlling authentication in a single place may be desirable. This can also be applied to OpenVPN. OpenVPN can be configured to authenticate with both Certificates and LDAP or LDAP alone. The following instructions will configure for both, as it is the more secure option


On your linux machine install

apt-get install openvpn-auth-ldap

Depending on whether you are RPM or Debian based will change where the module is installed. On Debian the module will be installed in /etc/openvpn/ On RPM it is installed in /etc/openvpn/plugin/lib/

You will also need to create the following directory to store your ldap configuration

mkdir /etc/openvpn/auth


Copy the following into ldap.conf inside your newly created directory:

# LDAP server URL
URL ldap://
# Bind DN (If your LDAP server doesn't support anonymous binds)
#BindDN uid=admin,ou=Users,dc=test,dc=com
BindDN [email protected]
# - for domain users <domain>\<username> also works

# Bind Password
Password humus
# - this is the password to login to the LDAP server to authenticate connecting users

# Network timeout (in seconds)
Timeout 15

# Enable Start TLS
TLSEnable no

# Follow LDAP Referrals (anonymously)
FollowReferrals yes

# - Only Add The Following if you are connecting securely to the AD/LDAP server
# TLS CA Certificate File
TLSCACertFile /usr/local/etc/ssl/ca.pem

# TLS CA Certificate Directory
TLSCACertDir /etc/ssl/certs

# Client Certificate and key
# If TLS client authentication is required
TLSCertFile /usr/local/etc/ssl/client-cert.pem
TLSKeyFile /usr/local/etc/ssl/client-key.pem

# Cipher Suite
# The defaults are usually fine here

# Base DN
#BaseDN "CN=Users,DC=test,DC=com"
BaseDN "CN=Users,DC=test,DC=com"
# - BaseDN sets the base point to start searching for users. To search everywhere in the domain, remove the CN portion. Each DC is a part of the domain split by the dots

# User Search Filter
#SearchFilter "(&(uid=%u)(accountStatus=active))"
#SearchFilter "(&(sAMAccountName=%u)(msNPAllowDialin=TRUE))"
SearchFilter "(&(sAMAccountName=%u))"
# - SearchFilter is the search query made within the BaseDN location - the above one searchs for matching usernames

# Require Group Membership
# - Add this if you want to control the AD users needing to belong to a group. Comment out if not
RequireGroup true

# Add non-group members to a PF table (disabled)
#PFTable ips_vpn_users

# - This section is only required if RequireGroup is true, however it can still be here even if it is removed
BaseDN "CN=Users,DC=test,DC=com"
# - BaseDN sets the base point to start searching for users. To search everywhere in the domain, remove the CN portion and replace each DC with each part of the domain
SearchFilter "(cn=vpn-users)"
# - vpn-users is the name of the group that users must be part of to join
MemberAttribute "member"
# Add group members to a PF table (disabled)
#PFTable ips_vpn_eng

After saving and configurating the above contents in ldap.conf, add the following line to the bottom of the main server.conf

plugins /etc/openvpn/ "/etc/openvpn/auth/ldap.conf" 

This tells openvpn to use the ldap plugin and load the just created plugin

Finaly, include the following line in the server.conf depending on what you would like to do:

  • To force Certificate and LDAP authentication add auth-user-pass below the plugin line
  • To only require LDAP authentication add client-cert-not-required below the plugin line

Finally give openvpn a restart to load the plugin. Check the logs to ensure configuration is correct (Authentication for LDAP typically is an issue if it is not the proper format)

For full details on this configuration see: for details


  • easy-rsa might not have installed to /usr/share/easy-rsa. It should be somewhere in /usr/share, but you might have to search to find the exact path.
  • The mathematical relation between a 4096 bit SSL key pair takes too long to generate on a small computer like a RaspberryPi, use 2048.
  • the n in dh{n}.pem is the size of your SSL keys (2048 or 4096)