Docker-Image mit StrongSwan

Das Docker-Image mit StrongSwan ist nun funktionsfähig. Damit besteht mittels eines IKEv2-fähigen IPSec-Clients die Möglichkeit, einen VPN-Tunnel direkt in den Docker-Stack hinein zu öffnen und gesichert auf interne Administrationsdienste zuzugreifen. Diese Isolation reduziert stark die Angriffsvektoren, die Hacker nutzen können, um in das System einzudringen, da nur absolut für den öffentlichen Betrieb notwendige Dienste öffentlich zugänglich sind.

Obwohl mit StrongSwan viele IPSec-Spielarten implementierbar sind, habe ich mich doch auf IKEv2 beschränkt, da dies als State-of-the-Art gilt und viele Probleme adressiert, die mit anderen Verfahren schon Kopfschmerzen verursacht haben. Die Ausschlag gebenden Argumente für IKEv2 waren die verbesserte Fähigkeit, mit Clients hinter NAT-Firewalls (NAT-Traversal) und mit mobilen Clients umzugehen (MOBIKE). In der heutigen Welt der mobilen Geräte halte ich insbesondere den letzten Punkt für ein deutliches Plus.

Authentifizierung: Server => Client

Die Authentifizierung des VPN-Servers ggü. dem Client erfolgt mittels Zertifikat. In der aktuellen Ausbaustufe erzeugt der VPN-Server selbst intern eine Stammzertifizierungsstelle (Root Certificate Authority, Root CA) und lässt diese dann ein passendes Server-Zertifikat (RSA, 4096 bit) für StrongSwan erzeugen. Der Container prüft bei jedem Start, ob das Server-Zertifikat noch zu den Einstellungen bezüglich Hostnamen passt und generiert es ggf. neu.

Um Clients die Prüfung dieses Zertifikats zu ermöglichen, muss das Zertifikat der Stammzertifizierungsstelle in den Zertifikatsspeicher des Clients importiert werden. Danach kann der VPN-Client sicherstellen, dass er bei einem Verbindungsaufbau auch wirklich mit dem gewünschten VPN-Server verbunden ist. Die Verwendung von solchen selbst signierten Zertifikaten (Self-Signed Certificates) ist für den Testbetrieb sowie einfache Szenarien mit wenigen Clients im privaten Umfeld meistens ausreichend.

Man sollte sich allerdings im Klaren darüber sein, dass das Importieren eines Root-CA-Zertifikats in einem Client dazu führt, dass dieser dann alle von der Root-CA ausgestellten Zertifikate als gültig ansieht. Sollte einmal der VPN-Server kompromittiert und der private Schlüssel der Root-CA entwendet werden, so könnte ein Angreifer Zertifikate erzeugen, die von den Clients für gültig gehalten werden und damit Sicherheit (Authentizität und Integrität) vorgaukeln. Daher noch einmal der Hinweis: Die Verwendung der internen CA ist nur für Testzwecke und bestenfalls für den privaten Gebrauch zu empfehlen. Für einen gewissen Kompromiss zwischen Komfort und Sicherheit kann man den privaten Schlüssel der Root-CA nach deren Initialisierung aus dem Container entfernen. Solange weder Server- noch Client-Zertifikate (siehe unten) erzeugt werden müssen, wird dieser Schlüssel nicht benötigt.

Für Umgebungen, in denen man aus o.g. Gründen das Ausrollen von eigenen Root-CA-Zertifikaten vermeiden möchte, werde ich daher demnächst das Image so erweitern, dass man von außen auch eigene Zertifikate zuführen kann.

Authentifizierung: Client => Server

Bei der Authentifizierung von Clients ggü. dem Server habe ich mich ebenfalls für einen zertifikatsbasierten Ansatz entschieden, da Zertifikate im allgemeinen sicherer sind als selbstgewählte Passwörter. Außerdem kann man später noch SmartCards hinzunehmen, um den privaten Schlüssel sicher zu speichern. Der VPN-Server unterstützt die Authentifizierung von Clients mittels IKEv2 und EAP-TLS. Damit sollten alle IPSec-VPN-Clients, die Authentifizierung mittels Zertifikaten unterstützen, in der Lage sein, sich beim VPN-Server anzumelden.

Die Erzeugung der Client-Zertifikate übernimmt die interne CA des VPN-Servers. Das Image bietet hierzu einige Befehle zum Hinzufügen, Deaktivieren, Aktivieren und Löschen von Clients an (Details dazu gibt es hier)

Verschlüsselung

Die Auswahl der angebotenen Verschlüsselungs- und Hashalgorithmen steht noch aus. Derzeit werden StrongSwans Default-Einstellungen verwendet.

Zugriff auf andere Docker-Container

Der StrongSwan-Container enthält einen BIND9 DNS-Server, der wahlweise DNS-Requests an Dockers Embedded-DNS-Dienst oder frei wählbare DNS-Server weiterleitet. Dieser DNS-Server wird den VPN-Clients als zu verwendender DNS-Server im Rahmen des IKEv2 Handshakes mitgeteilt. Auf diese Weise sind alle Container erreichbar, die sich mit dem StrongSwan-Container in einem User Defined Network befinden. Der StrongSwan-Container kann sich zeitgleich in mehreren User Defined Networks befinden. Die Namensauflösung (und auch die Kommunikation mit anderen Containern) funktioniert nicht, wenn sich der StrongSwan-Container an Dockers Default-Brücke befindet.

Zugriff auf das Internet

VPN-Clients können auch auf das Internet zugreifen. Dabei unterstützt der VPN-Server für IPv4 Masquerading und für IPv6 Masquerading sowie die Vergabe von global eindeutigen Adressen (GUA, Global Unicast Address) an die VPN-Clients. Masquerading verschleiert die Identität des VPN-Clients, da dessen ursprüngliche IP-Adresse durch die IP-Adresse des VPN-Servers ersetzt wird. Bei der Verwendung von GUAs ist der Vorteil, dass auf dem Weg vom VPN-Client zu einem Host im Internet keine Adressumsetzung im Weg ist, die bei manchen Protokollen Probleme verursacht. Ein Zugriff aus dem Internet auf VPN-Clients ist bei Masquerading nicht möglich und wird bei GUAs – mit Ausnahme von einigen wichtigen ICMP-Paketen – unterbunden.

Kommunikation zwischen VPN-Clients

Die Kommunikation zwischen VPN-Clients kann optional freigeschaltet werden.

Multicast-Support

Der VPN-Server unterstützt kein Multicasting. Es gibt StrongSwan-Module, die Multicast-Support bieten – allerdings nur für IPv4 und nicht für IPv6. Um Irritationen zu vermeiden verzichte ich daher ganz auf Multicast-Support. Vielleicht gibt es irgendwann ja auch noch ein Multicast-Modul, das IPv6 beherrscht…

Schreibe einen Kommentar