OpenVPN installieren und härten

Update 17.01.2017:

  • Abweichungen zu Debian Jessie ergänzt.
  • (Umstieg auf RPI3 und Jessie)

Update 31.10.2016:

  • Parameter "openvpn --genkey --secret keys/ta.key" geändert. Der Schlüssel wurde im falschen Ordner erstellt und musste nach keys/ verschoben werden.

Update 23.05.2016:

  • Parameter "client" hinzugefügt.

(Ich habe mir wieder OpenVPN 2.2.1. auf dem Raspberry Pi 2 installiert und gleich gehärtet. Bei meiner letzten Systemumstellung hatte ich OpenVPN nicht wieder installiert, da mir das Einrichten der neuen Programme und die damit verbundenen Probleme (aus Unwissenheit) gereicht hatten. Aber jetzt wollte ich wieder etwas mit meinem Pi machen! Meine letzten Quellen zum Konfigurieren habe ich dummerweise nicht abgespeichert und zum Teil auch nicht wieder gefunden... Ich habe auch keine Anleitung, die meine Wünsche abdeckt, gefunden und musste mir alles "neu" zusammensuchen. Hier also jetzt eine, für mich, vollständige Anleitung!

Mein System: Raspberry Pi 2 mit Debian Wheezy und OpenVPN 2.2.1) - Update 17.01.2017

Mein System: Raspberry Pi 3 mit Debian Jessie und OpenVPN 2.3.4

OpenVPN installieren

Zuerst wird OpenVPN und OpenSSL über den Paketmanager installiert.

sudo apt-get install openvpn openssl

Im Hauptverzeichnis von OpenVPN werden als nächstes benötigte Dateien kopiert.

cd /etc/openvpn
# Debian Wheezy
sudo cp -r /usr/share/doc/openvpn/examples/easy-rsa/2.0 ./easy-rsa

# Debian Jessie
sudo cp -r /usr/share/easy-rsa  ./easy-rsa

Schlüssellänge der Zertifikate erhöhen und OpenVPN initialisieren

An der Datei vars müssen nun einige Änderungen vorgenommen werden, die u.a. die Sicherheit der Zertifikate erhöht.

sudo nano easy-rsa/vars
  • export EASY_RSA="/etc/openvpn/easy-rsa"
  • export KEY_SIZE=4096
  • export CA_EXPIRE=1826
  • export KEY_EXPIRE=365

Anschließend werden die folgenden Befehle als Root ausgeführt, um OpenVPN mit den Änderungen zu initialisieren.

cd easy-rsa
sudo su
source vars
./clean-all
./pkitool --initca
ln -s openssl-1.0.0.cnf openssl.cnf

Zertifikate erstellen

Die Zertifikate für Server und den ersten Client können jetzt erstellt werden. Dabei muss lediglich das Länderkürzel richtig angegeben werden, die restlichen Fragen können einfach bestätigt werden. Die Standardwerte können bei Bedarf in der zuvor schon bearbeiteten Datei vars geändert werden. Wird die Datei vars nachträglich verändert, müssen die vorherigen Befehle neu ausgeführt werden. Da wir die Schlüssellänge auf 4096 Bit erhöht haben, braucht die Erstellung der Zertifikate einige Zeit.

./build-ca OpenVPN
./build-key-server server
./build-key client1
./build-dh
openvpn --genkey --secret keys/ta.key
exit

Server Konfiguration

Nun wird die Konfigurationsdatei für den Server erstellt. An dieser Stelle soll noch darauf hingewiesen werden, dass die meisten Probleme aus einem Unterschied zwischen Server und Client Konfiguration entstehen. Es muss also darauf geachtet werden, dass möglichst alle Parameter mit entsprechenden Werten in beiden Dateien vorhanden sind. Parameter, die nicht angegeben sind, erhalten Default-Werte. Die Werte der Parameter können allerdings je nach Konfigurationsdatei variieren: So z.B. für einen Client "tls-auth ta.key 1" und für den Server "tls-auth ta.key 0".

cd ..
sudo touch openvpn.conf
sudo nano openvpn.conf

(Optional können die Konfigurationsdateien am Ende des Artikels heruntergeladen werden.)

# Device-type should be tun (OSI Layer 3) or tap (OSI Layer 2).
dev tun
# Enable TLS and assume server role during TLS handshake.
tls-server
# UDP operation
proto udp
# TCP/UDP port number for both local and remote. 
port 1194
# Require that peer certificate was signed with an explicit nsCertType designation of "client" or "server".
remote-cert-tls client
# Certificate authority (CA) file in .pem format, also referred to as the root certificate.
ca /etc/openvpn/easy-rsa/keys/ca.crt
# Local peer's signed certificate in .pem format -- must be signed by a certificate authority whose certificate is in ca file.
cert /etc/openvpn/easy-rsa/keys/server.crt
# Local peer's private key in .pem format.
key /etc/openvpn/easy-rsa/keys/server.key
# File containing Diffie Hellman parameters in .pem format
dh /etc/openvpn/easy-rsa/keys/dh4096.pem
# Authenticate packets with HMAC using message digest algorithm
auth SHA384
# Add an additional layer of HMAC authentication on top of the TLS control channel to protect against DoS attacks.
tls-auth /etc/openvpn/easy-rsa/keys/ta.key 0
# A list of allowable TLS ciphers delimited by a colon (":"). 
tls-cipher DHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-SHA256:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES128-SHA256:DHE-RSA-CAMELLIA256-SHA:DHE-RSA-AES256-SHA:DHE-RSA-CAMELLIA128-SHA:DHE-RSA-AES128-SHA:CAMELLIA256-SHA:AES256-SHA:CAMELLIA128-SHA:AES128-SHA 
# Encrypt packets with cipher algorithm
cipher AES-256-CBC
# This directive offers policy-level control over OpenVPN's usage of external programs and scripts.
script-security 1
# The chroot directive allows you to lock the OpenVPN daemon into a so-called chroot jail.
chroot /etc/openvpn/jail
# Change the user ID of the OpenVPN process to user after initialization, dropping privileges in the process.
user openvpn
# Similar to the --user option, this option changes the group ID of the OpenVPN process to group after initialization.
group openvpn
# Set the number of clients
max-clients 3
# A helper directive designed to simplify the configuration of OpenVPN's server mode.
server 10.8.0.0 255.255.255.0
# Don't re-read key files across SIGUSR1 or ping-restart.
persist-key
# Don't close and reopen TUN/TAP device or run up/down scripts across SIGUSR1 or ping-restart restarts.
persist-tun
#Append logging messages to file.
log-append /var/log/openvpn
# Write operational status to file every n seconds.
status /var/log/openvpn-status.log 
# Set output verbosity
verb 3
# When this option is used, each client will "see" the other clients which are currently connected.
# client-to-client
# Push a config file option back to the client for remote execution.
push "redirect-gateway def1 bypass-dhcp"
push "dhcp-option DNS 8.8.8.8"
push "dhcp-option DNS 8.8.4.4"
# # Use fast LZO compression
comp-lzo
# A helper directive designed to simplify the expression of --ping and --ping-restart in server mode configurations.
keepalive 10 120

Benutzer anlegen

In der Konfigurationsdatei ist ein Nutzer "openvpn" angegeben, unter dem der Prozess nach der Initialisierung der Verbindung weiterläuft. Dieser Nutzer sollte also nur über die notwendigen Rechte für OpenVPN verfügen. Wir legen den Nutzer daher wie folgt an:

sudo adduser --no-create-home --disabled-login --shell /bin/false openvpn

Internetzugriff einrichten

Damit die Geräte auch Zugriff auf das Internet haben, muss eine Weiterleitung mit den folgenden Befehlen eingerichtet werden. Wird eine andere Netzwerkschnittstelle als der Ethernetadapter "eth0" verwendet, muss der Parameter durch den entsprechenden ersetzt werden.

# Debian Wheezy
sudo sh -c 'echo 1 > /proc/sys/net/ipv4/ip_forward'
sudo iptables -t nat -A POSTROUTING -s 10.8.0.0/24 -o eth0 -j MASQUERADE

# Debian Jessie
sudo iptables -t nat -A POSTROUTING -s 10.8.0.0/24 -o eth0 -j SNAT --to-source $(ifconfig eth0 | grep -i 'inet' | cut -d: -f2 | awk '{ print $1}')

Nach einem Neustart des Systems muss der Eintrag in iptables neu gesetzt werden(, automatisiert erledigt das ein Cronjob).

# Debian Wheezy
crontab -e

# Debian Jessie
sudo apt-get install iptables-persistent
sudo service iptables save

(Am Ende die nachfolgende Zeile einfügen.)

# Debian Whezzy
@reboot sudo iptables -t nat -A POSTROUTING -s 10.8.0.0/24 -o eth0 -j MASQUERADE

In der Datei "sysctl.conf" muss die Zeile "net.ipv4.ip_forward=1" freigegeben werden.

cd ..
sudo nano /etc/sysctl.conf

Das ganze sollte mit einem Neustart überprüft werden!

sudo reboot
sudo iptables -t nat --list-rules

Client Konfiguration

Nun kann die Konfigurationsdatei für Clients angelegt werden:

sudo su
cd /etc/openvpn/easy-rsa/keys
nano raspberrypi.ovpn

(Optional können die Konfigurationsdateien am Ende des Artikels heruntergeladen werden.)

client
# Network
dev tun
# Enable TLS and assume client role during TLS handshake.
tls-client
# UDP operation
proto udp
# Remote host name or IP address
remote sharky.koeln 1194
# If hostname resolve fails for remote, retry resolve for n seconds before failing
resolv-retry infinite
# Do not bind to local address and port. The IP stack will allocate a dynamic port for returning packets.  
nobind
# Don't re-read key files across SIGUSR1 or ping-restart.
persist-key
# Don't close and reopen TUN/TAP device or run up/down scripts across SIGUSR1 or ping-restart restarts.
persist-tun
# Require that peer certificate was signed with an explicit nsCertType designation of "client" or "server".
remote-cert-tls server
# Certificate authority (CA) file in .pem format, also referred to as the root certificate.
ca ca.crt
# Local peer's signed certificate in .pem format -- must be signed by a certificate authority whose certificate is in ca file.
cert client1.crt
# Local peer's private key in .pem format.
key client1.key
# Authenticate packets with HMAC using message digest algorithm
auth SHA384
# Add an additional layer of HMAC authentication on top of the TLS control channel to protect against DoS attacks.
tls-auth ta.key 1
# A list of allowable TLS ciphers delimited by a colon (":"). 
tls-cipher DHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-SHA256:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES128-SHA256:DHE-RSA-CAMELLIA256-SHA:DHE-RSA-AES256-SHA:DHE-RSA-CAMELLIA128-SHA:DHE-RSA-AES128-SHA:CAMELLIA256-SHA:AES256-SHA:CAMELLIA128-SHA:AES128-SHA 
# Encrypt packets with cipher algorithm
cipher AES-256-CBC
# Use fast LZO compression
comp-lzo
# Set output verbosity
verb 3
# Renegotiate data channel key after n seconds
reneg-sec 1800

Im letzten Schritt werden alle für den Client benötigten Dateien gepackt und ins User -Verzeichnis verschoben. Von dort kann es zum Beispiel mit dem Programm WinSCP heruntergeladen werden.

tar czf openvpn-keys.tgz ca.crt client1.crt client1.key ta.key raspberrypi.ovpn
mv openvpn-keys.tgz /home/pi
chown pi:pi /home/pi/openvpn-keys.tgz
exit

Zuletzt starten wir den OpenVPN Server neu.

# Debian Whezzy
sudo service openvpn restart 

 # Debian Jessie / systemd
 # Mit openvpn@ wird die verwendete Konfigurationsdatei (ohne .conf) angegeben, hier openvpn.conf.
 # Unter systemd können demnach mehrere OpenVPN-Server betrieben werden!
sudo systemctl start openvpn@openvpn.service
sudo systemctl enable openvpn@openvpn.service

Zusätzliche Clients einrichten

Neue Clients werden durch weitere Zertifikate "hinzugefügt". Dazu werden die folgenden Befehle ausgeführt und der Name des Clients "clientX" variiert: Zum Beispiel durch fortlaufende Nummern.

cd /etc/openvpn/easy-rsa/
sudo su
source vars
./build-key clientX
cd /etc/openvpn/easy-rsa/keys
tar czf openvpn-keys.tgz ca.crt clientX.crt clientX.key ta.key raspberrypi.ovpn
mv openvpn-keys-clientX.tgz /home/pi
chown pi:pi /home/pi/openvpn-keys-clientX.tgz
exit

Bevor die Dateien mit einem Client-Programm verwendet werden können, muss die Datei "raspberrypi.ovpn" mit einem beliebigen Editor angepasst und "client1" durch "clientX" ersetzt werden.

Zertifikat zurückziehen

Ein Client wird durch das Zurückziehen des Zertifikats entfernt. In den nachfolgenden Befehlen muss clientX durch den entsprechenden Namen ersetzt werden.

sudo su
cd /etc/openvpn/easy-rsa
source vars
openssl ca -config openssl.cnf -revoke keys/clientX.crt -keyfile keys/ca.key -cert keys/ca.crt
openssl crl -in keys/crl.pem -text

Damit der Server dies auch berücksichtigt, muss die Certificate revocation list (CRL) in der Konfigurationsdatei hinzugefügt werden. Dazu wird die nachfolgende Zeile in "/etc/openvpn/openvpn.conf" eingefügt.

crl-verify keys/crl.pem

Danach muss der Server neu gestartet werden.

service openvpn restart
exit

Dateien

openvpn.conf & raspberrypi.ovpn:

OpenVPN_Configs.zip - PGP Signatur

Quellen

OpenVPN Manuals

BetterCrypto

IT Security Blog

Jan Karres

Thomas Krenn