Ich befinde mich aktuell öfter mal innerhalb einer Konzern-IT, wo so ziemlich alles abgeschottet ist. Nach außen sind lediglich Ports 80 und 443 TCP und 500 UDP offen (für IPSec VPN). Man hat also nicht mal die Möglichkeit sich per SSH irgendwo einzuloggen.
Als Abhilfe habe ich mir jetzt einen WireGuard VPN-Server in die Cloud gestellt. Als Basis dient ein minimales Ubuntu 20.04. Wenn man von OpenVPN kommt erscheint einem die Einrichtung, wie ein Kinderspiel. Sämtlicher Traffic geht durch das WireGuard VPN. Da es auf UDP-Basis läuft und man das TCP-over-TCP-Problem umgeht ist alles rasend schnell.
Tipp: Oft wird in so geschlossenen Umgebungen mindestens noch IPSec VPN erlaubt, so dass man Port 500 UDP nutzen kann.
Ablauf
- Auf dem Server und allen Clients werden ein public/private Schlüsselpaar erzeugt. Der public key des Servers muss dann auf allen clients hinterlegt werden während sämtliche public keys der clients auf dem Server hinterlegt werden müssen.
- Alle clients bekommen feste IP-Adressen (es gibt kein DHCP)
- Zuerst wird der also Server installiert und konfiguriert.
- Danach installiert man WireGuard auf den Clients und hinterlegt deren public keys auf dem Server
Installation Server
// als root auf dem Ubuntu 20.04 Server
apt install wireguard iptables ufw
// Schlüssel generieren
wg genkey | tee /etc/wireguard/server.key | wg pubkey | tee /etc/wireguard/server.pub
Konfigurationsdatei /etc/wireguard/wg0.conf
mit folgendem Inhalt erstellen (INHALT_SERVER_KEY entspr. anpassen, für INHALT_CLIENT_PUB siehe weiter unten). Allowed-IPs ist hier jeweils die IP die dem Client zugewiesen wird.
[Interface]
Address = 10.10.0.1/24
PostUp = iptables -A FORWARD -i %i -j ACCEPT; iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
PostDown = iptables -D FORWARD -i %i -j ACCEPT; iptables -t nat -D POSTROUTING -o eth0 -j MASQUERADE
ListenPort = 500
PrivateKey = INHALT_SERVER_KEY
[Peer]
PublicKey = INHALT_CLIENT1_PUB
AllowedIPs = 10.10.0.2/32
[Peer]
PublicKey = INHALT_CLIENT2_PUB
AllowedIPs = 10.10.0.3/32
In der Datei /etc/sysctl.conf die Zeile net.ipv4.ip_forward=1
aktivieren und mit sysctl -p einlesen. Zur Absicherung ufw konfigurieren (s. z.B. ubunutuusers wiki).
Installation Client
Die Client-Konfiguration zeige ich hier am Beispiel des Mac-Clients. Unter Ubuntu läuft das analog, aber ohne grafische Oberfläche. Wenn man einen „leeren Tunnel“ erstellt, wird automatisch ein public/private keypair erzeugt. Den public key kopiert man zunächst wie oben gezeigt in die Konfiguration des Servers. Nun die Konfiguration wie folgt ergänzen:
[Interface]
PrivateKey = CLIENT_PRIVATE_KEY
Address = 10.10.0.2/32
DNS = 1.1.1.1, 1.0.0.1
[Peer]
PublicKey = SERVER_PUBLIC_KEY
AllowedIPs = 0.0.0.0/0
Endpoint = 123.123.123.1:500
PersistentKeepalive = 25
Die Adresse sollte analog zu der in der Server-Konfiguration sein. DNS trägt man ein wie gewünscht. Unter Peer trägt man den public key des Servers ein und als EndPoint IP und Port des Servers. Über AllowedIPs wird hier festgelegt welche IPs durch das VPN geschickt werden. 0.0.0.0/0 bedeutet, dass der gesamte Traffic durch das VPN geroutet wird.
Hakt man noch die On Demand Kästchen an, wird dafür gesorgt, dass das VPN immer (auch bei Verbindungswechseln) aktiv ist.
WireGuard auf dem Server automatisch starten
Für einen ersten Test kann man auf dem Server mit wg-quick up wg0
den Server starten und sich nun mit dem Client verbinden.
Läuft das kann man mit systemctl enable wg-quick@wg0
WireGuard automatisch starten lassen.
VPN über 443?
Was ist, wenn Port 500 auch dicht ist? In diesem Fall würde man normalerweise auf 443 ausweichen. WireGuard ist allerdings UDP-only. Wenn 443 nur für TCP freigegeben ist kommt man so also nicht weiter. Eine Möglichkeit ist die Nutzung von Tools wie udptunnel oder udp2raw. Beides hat bei mir aber nicht zuverlässig funktioniert, so dass ich in diesem Fall wohl doch eher zu OpenVPN über TCP greifen würde.