OpenVPN on Debian 8 (Jessie)

Update: I wrote a post how to harden OpenVPN on CentOS. It includes DoS mitigation, daemon privilege reduction, better certificate checks, enforcing use of TLS 1.2, stronger ciphers and more. The methods used to harden it can be applied to this post easily. See here:

This how-to will cover setting up a TLS-enabled OpenVPN server on Debian 8 (Jessie)
Not covered in this how-to: opening ports in the firewall.

Update the system:

apt-get update
apt-get upgrade -y

Install OpenVPN and easy-rsa:

apt-get -y install openvpn easy-rsa

Copy the easy-rsa directory for creating keys:

cp -R /usr/share/easy-rsa /etc/openvpn/

Edit the following variables in the /etc/openvpn/easy-rsa/vars file:

export KEY_CITY="SanFrancisco"
export KEY_ORG="Fort-Funston"
export KEY_EMAIL="mail@domain"
export KEY_EMAIL=mail@domain

Increase the key size to something above 3072 (4096 if you are paranoid, see:

sed -i 's/KEY_SIZE=2048/KEY_SIZE=3072/g' /etc/openvpn/easy-rsa/vars

Create the server side keys and certificates:

cd /etc/openvpn/easy-rsa/
source vars
./build-key-server server

Build the Diffie-Hellman parameters (this will take a long time, in some cases more than an hour):


Copy the server certificate, key and CA to the openvpn directory:

cd /etc/openvpn/easy-rsa/keys
cp server.crt server.key ca.crt dh3072.pem /etc/openvpn/

Copy the sample server config:

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

Edit the server config file:

sed -i -r 's/^dh (.+)/dh dh3072.pem/g' /etc/openvpn/server.conf #new dh parameter
echo 'crl-verify easy-rsa/keys/crl.pem' >> /etc/openvpn/server.conf #certificate revocation list
echo 'push "redirect-gateway def1 bypass-dhcp"' >> /etc/openvpn/server.conf #redirect default gateway
echo 'push "dhcp-option DNS"' >> /etc/openvpn/server.conf #use google DNS
echo 'push "explicit-exit-notify 3"' >> /etc/openvpn/server.conf #send exit notification instead of timing out

OpenVPN won’t start if the CRL file doesn’t exist or is invalid, so we create a dummy client certificate and revoke it:

cd /etc/openvpn/easy-rsa/
source vars
./build-key dummy-client
./revoke-full dummy-client

Enable IPv4 forwarding:

echo 'net.ipv4.ip_forward=1' > /etc/sysctl.d/net.ipv4.ip_forward.conf
sysctl -p /etc/sysctl.d/net.ipv4.ip_forward.conf

Set up the following iptables rules:

iptables -A INPUT -p udp -m state --state NEW -m udp --dport 1194 -j ACCEPT # allow traffic to the openvpn server
iptables -A FORWARD -s -j ACCEPT # allow forwarding from the vpn subnet
iptables -A FORWARD -m state --state RELATED,ESTABLISHED -j ACCEPT # allow forwarding of related and established packets
iptables -t nat -A POSTROUTING -s -o eth0 -j MASQUERADE # masquerade packets leaving eth0 from the vpn subnet

Note: These firewall rules will not survive a reboot unless configured to:

Enable and start the OpenVPN service:

systemctl enable openvpn@server
systemctl start openvpn@server

Note: the @server means systemd will start openvpn with the config file “server.conf”.
For multiple servers/clients use systemctl enable openvpn@server2, systemctl enable openvpn@client1, etc..

Generate a client certificate:

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

Generate a client config file that works with the Windows OpenVPN GUI client with in-line ca, cert, and key:

echo 'client
dev tun
proto udp
remote 1194
resolv-retry infinite
remote-cert-tls server
verb 3' > /etc/openvpn/client1.ovpn
echo '<ca>' >> /etc/openvpn/client1.ovpn
cat /etc/openvpn/ca.crt >> /etc/openvpn/client1.ovpn
echo '</ca>' >> /etc/openvpn/client1.ovpn
echo '<cert>' >> /etc/openvpn/client1.ovpn
cat /etc/openvpn/easy-rsa/keys/client1.crt >> /etc/openvpn/client1.ovpn
echo '</cert>' >> /etc/openvpn/client1.ovpn
echo '<key>' >> /etc/openvpn/client1.ovpn
cat /etc/openvpn/easy-rsa/keys/client1.key >> /etc/openvpn/client1.ovpn
echo '</key>' >> /etc/openvpn/client1.ovpn

Note: Make sure the client key is delivered securely (in this case it’s inline in the client config file)! No point in using strong crypto if you post the keys to pastebin…

My brain

OpenVPN on Debian 8 (Jessie)

9 thoughts on “OpenVPN on Debian 8 (Jessie)

  1. Dan says:

    Thanks for the tutorial, I got OpenVPN working on my machine. Can I delete any of the files in the /easy-rsa/keys-folder? Which files do I need to keep? There’s a lot of stuff, like the revoked dummy client-files, .old-files, etc.

    Liked by 1 person

    1. If you started with a clean easy-rsa/keys folder, there shouldnt be anything to delete except maybe the dummy-client keys for the CRL, but I don’t see a reason to delete that. Whatever you delete, just make sure you have a backup!


      1. Dan says:

        What I actually tried to ask is if I can delete any of the files that are generated during your tutorial, or if the VPN access won’t work without them. The keys-folder didn’t exist before, and now it’s full of stuff like dummy-client.*, index.txt.old, 01.pem – 03.pem, serial.old and so on.


      2. Ah, I see.
        AFAIK you can safely delete the dummy-client* files, which includes the certificate with the number name. If you list files in the directory by date/time (ls -lart) you should see the dummy-client* files and a certificate with a number name (in my case 02.pem) with the same timestamp and m5sum. You can delete the .old files, but they will be recreated when you create new keys/certs, so there’s little point in deleting them.


Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s