RaspberryPi als OpenVPN-Gateway


Der Einplatinen-Computer RaspberryPi eignet sch für vieles, aber nicht als VPN-Router. Ein VPN bezeichnet ein VirtualPrivateNetwork, d.h. eine verschlüsselte Verbindung zu einem entfernten Netzwerk, so können dort alle Ressourcen genutzt werden, als wäre man direkt vor Ort.
Mit dem 900MHz quad-core ARM Cortex-A7 Prozessor des RaspberryPi2 und OpenVPN sind nur Geschwindigkeiten bis ca. 20 Mbit/s möglich, zudem ist die maximale Datenrate durch die lediglich mit 100 Mbit/s angebundene Netzwerkbuchse auf maximal 50 Mbit/s (beide Richtungen) begrenzt.

Wer also schon einen RaspberryPi(2) besitzt, kann ihn auch als VPN-Router im eigenen Netzwerk verwenden, jedoch extra einen Pi dafür anzuschaffen, würde zumindest ich aufgrund der schlechten Performance nicht mehr tun. Der BananaPi M3, wenn er denn mal mit stärkerer CPU released wird, wäre dank seiner 1 Gbit/s Netzwerkschnittstelle besser geeignet.

Schon so viel Text, doch was bringt es überhaupt, den RaspberryPi als VPN-Gateway zu nutzen?
Bei Nutzung des RaspberryPi als VPN-Gateway muss das VPN nur einmal eingerichtet werden und steht danach allen Clients im Netzwerk zur Verfügung. Mit dieser Hardwarelösung können die Clients dann auch kompromittiert konfiguriert sein, wie sie wollen, es geht alles durchs VPN. Auch der WebRTC Leak gehört damit der Vergangenheit an.

Auf der auf Debian basierenden Raspbian Distrubution kann die Einrichtung folgendermaßen vorgenommen werden:

In der /etc/sysctl.conf muss zwingend net.ipv4.ip_forward = 1 aktiviert werden, d.h. # (auskommentiert) muss von der Zeile entfernt werden. Zum Inkrafttreten dieser Änderung ist ein Systemneustart erforderlich, der aber auch zum Schluss gemacht werden kann.
apt-get install openvpn -y
OpenVPN ist durch die Standard-Paketquellen beziehbar.

Nun wird das Interface bearbeitet:
nano /etc/network/interfaces

auto lo
iface lo inet loopback

iface eth0 inet static
address 192.168.178.2
network 192.168.178.0
netmask 255.255.255.0
broadcast 192.168.178.255
gateway 192.168.178.1
dns-nameservers 8.8.8.8 8.8.4.4

eth0 ist hier der LAN-Port des PIs, static für statische IP-Adresse.
In meinem Setup benutze ich keinen DHCP-Server.
network, netmask, broadcast hängen vom eigenen Subnet ab, diese Werte können z.B. einfach hier berechnet werden.
gateway wäre die Adresse des Modems, welches die Internetverbindung aufbaut. Pi und Modem müssen sich demzufolge im selben Subnet befinden, hier im 192.168.178.0/24 Subnet.

Bei den Clients müsste dann entsprechend 192.168.178.2 als Standardgateway eingetragen werden, hängt man z.B. noch einen WLAN-Router (oder WLAN-Stick für den PI) mit eigenem Subnet ans Netzwerk und setzt dort das Standardgateway auf den PI, fällt die Einrichtung bei den Clients weg.

Jetzt das wichtigste, die iptables-Regeln:
#!/bin/bash

iptables -F

# VPN Gateway
iptables -A FORWARD -i eth0 -o tun0 -j ACCEPT
iptables -A FORWARD -i tun0 -o eth0 -m state --state RELATED,ESTABLISHED -j ACCEPT

# Drop everything else. "Killswitch"
iptables -A FORWARD -j DROP

# NAT the VPN client traffic to the internet
iptables -t nat -A POSTROUTING -o tun0 -j MASQUERADE

# Start OpenVPN Connection
/etc/init.d/openvpn start
cd /etc/openvpn/
openvpn client.ovpn

Dieses Skript irgendwo speichern, mit chmod +x ausführbar machen und dem Crontab hinzufügen, somit wird die VPN-Verbindung bei jedem Neustart gestartet.
Man könnte die Regeln alternativ auch mit iptables-save speichern, aber für OpenVPN wird ja ohnehin ein Startup-Skript benötigt.

FORWARD ist hier die Kette, in der Daten von den Clients weitergeleitet werden. Die erste Zeile akzeptiert sämtlichen Datenverkehr von den Clients am LAN-Anschluss eth0, falls diese durch tun0, die OpenVPN-Verbindung, geleitet werden. Die Regel in der zweiten Zeile erlaubt vorher genehmigte, aufgebaute Verbindungen aus dem Tunnel wieder mit den Clients zu kommunizieren. In der dritten Zeile wird sämtlicher anderer Datenverkehr verworfen, was zur Folge hat, dass wenn die OpenVPN-Verbindung abbricht, kein Internetzugriff mehr möglich ist. Zuletzt wird der Verkehr zu tun0 "maskiert", mittels NetworkAddressTranslation.
crontab -e
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games
@reboot /path/to/iptables/script.sh


Die PATH variable im Crontab zu setzen ist vonnöten, da im Script nicht der direkte Pfad zur iptables-Binary gesetzt ist.

In /etc/openvpn muss die client.ovpn Datei, welche für den Client bestimmt ist, abgelegt werden. Wird für den Aufbau der VPN-Verbindung zusätzlich Benutzername und Passwort benötigt, kann die Authentifizierung hiermit automatisiert werden.

Nach einem Systemneustart sollte der VPN aktiv sein. Zur Bestätigung kann man sich seine eigene, externe (IPv4) direkt auf dem RaspberryPi anzeigen:
wget -qO- icanhazip.com