Erstellen eines AWS-Client-VPNs mit Terraform
Das Hosten von Infrastrukturen bei Cloud-Anbietern wie AWS kann eine gute Möglichkeit sein, verwaltete Dienste zu nutzen, um Arbeitskräfte und Zeit zu sparen. Für den sicheren Zugriff auf Ihre Infrastruktur scheint VPN eine gute Möglichkeit zu sein.
In diesem kurzen Tutorial sehen wir uns an, wie man einen VPN Client Endpunkt mit terraform in einem "komplexeren" Szenario konfiguriert. In unserem Szenario werden wir mehrere VPN-Endpunkte einrichten (oder zumindest vorbereiten), um verschiedenen Personen den Zugang zu Infrastrukturen zu ermöglichen.
Bevor wir beginnen, haben wir eine Frage an Sie. Wissen Sie, wie viel Zeit Sie für die Erstellung eines AWS-Client-VPN mit Terraform benötigen werden? Wenn nicht, ist es an der Zeit, Ihre Zeit zu erfassen, um ähnliche Aufgaben besser einschätzen zu können.
Schätzen Sie die Dauer einer Aufgabe genau ab.
Verfolgen Sie Ihre Zeit mit Timeular.
Beispiele für solche Infrastrukturen könnten eine Entwicklungs- und eine Produktionsumgebung sein, die vollständig voneinander getrennt sind. Als Authentifizierungsmechanismus haben wir uns für Client-Zertifikate entschieden. Dies ermöglicht es uns, ohne zusätzliche Infrastruktur zu agieren, und jede Person ist nach wie vor eigenständig verwaltbar. So erhält jede Person ihr eigenes Zertifikat, das bei Bedarf individuell widerrufen werden kann.
Aus Sicht der Zertifikate wollen wir also ein TLS-Zertifikat pro VPN-Tunnel und n Client-Zertifikate haben. Zusätzlich wollen wir:
- ein regelmäßig gewechseltes TLS-Zertifikat haben möchten
- das TLS-Zertifikat nicht manuell rotieren wollen
- eine PKI für unser Unternehmen haben wollen und nicht pro VPN-Tunnel
Nach dieser Definition können wir nun alles einrichten.
Bescheinigungen
TLS-Zertifikat
Wenn es um die Arbeit mit Zertifikaten in einer AWS-Umgebung geht, werden Sie um den AWS Certificate Manager (ACM), in dem alle Zertifikate abgelegt sind, nicht herumkommen. Da wir ohnehin rotierende TLS-Zertifikate haben wollen, werden wir diesen Dienst nutzen, um auch diese für uns zu erstellen. In Terraform würde dies wie folgt aussehen:
Mit diesem Snippet erstellen wir ein TLS-Zertifikat, das von AWS verwaltet wird. Da AWS nicht weiß, ob wir der Eigentümer dieser Domäne sind, muss es diese irgendwann validieren. In unserem Fall haben wir eine DNS-Validierung gewählt, bei der wir einen DNS-Eintrag angeben, den AWS zu finden versucht.
Sie fragen sich vielleicht auch, woher die `local.global_tags` kommen. Alle diese Schnipsel sind Teil eines eigenständigen Beispiels zur Einrichtung eines Client-VPN-Endpunkts. Das bedeutet, dass innerhalb dieses Beispiels alle erforderlichen Ressourcen wie eine eigene VPC mit Subnetzen und Tags erstellt werden. Alles ist auf GitHub verfügbar, wo man sich die komplette Einrichtung ansehen kann. Für den Moment legen wir diese grundlegende Einrichtung beiseite und konzentrieren uns auf den VPN-Endpunkt.
Bevor wir das Zertifikat verwenden dürfen, müssen wir warten, bis die Validierung abgeschlossen ist. Dazu verwenden wir den Block `aws_acm_certficiate_validation`. Durch die Verwendung des Validierungsblocks anstelle des Zertifikatsblocks als Abhängigkeit innerhalb anderer Terraform-Ressourcen stellen wir sicher, dass wir nur Zertifikate verwenden, die korrekt erstellt wurden.
Mit diesen beiden Schnipseln haben wir den gesamten TLS-Teil für unseren kommenden VPN-Tunnel erledigt. Was auf der Zertifikatsseite übrig bleibt, sind unsere Client-Zertifikate.
Kunden-Zertifikate
Wenn Sie bereits eine PKI eingerichtet haben, können Sie diese natürlich verwenden. In unserem Beispiel werden wir ein Tool namens XCA verwenden, das ein nettes kleines Tool für die Verwaltung einer PKI ist.
Wir werden die folgende Zertifikatsstruktur erstellen:
Wie Sie auf dem Bild sehen können, haben wir eine Zertifikatskette mit vier Zertifikaten. Drei davon sind Zertifizierungsstellen (CA), was bedeutet, dass sie andere Zertifikate signieren dürfen. Das vierte ist ein Client-Zertifikat, das ein Benutzer zur Authentifizierung über einen VPN-Tunnel verwenden kann.
Alle CAs haben vier X509v3-Erweiterungen eingestellt:
- Basic Constraint: CA:TRUE
- Thema Schlüsselbezeichner
- Autorität Schlüsselbezeichner
- Schlüsselverwendung: Zertifikat signieren, CRL signieren
Das Client-Zertifikat verfügt über einige weitere X509v3-Erweiterungsoptionen:
- Basic Constraint: CA:FALSE
- Thema Schlüsselbezeichner
- Autorität Schlüsselbezeichner
- Schlüsselverwendung: Digitale Signatur
- Erweiterte Schlüsselverwendung: TLS Web Client-Authentifizierung
Wenn wir alle Zertifikate erstellt haben, müssen wir sie exportieren, um sie nutzen zu können. Zum einen wollen wir das VPN-Client-Zertifikat als PKCS#12-Datei exportieren, zum anderen wollen wir die VPN-CA (privater und öffentlicher Schlüssel) und die Zertifikatskette (die öffentlichen Schlüssel) des Stamm- und Zwischenzertifikats exportieren.
Nachdem wir alle Zertifikate exportiert haben, müssen wir die VPN CA auf folgende Weise zum ACM hinzufügen:
Wie Sie in diesem Ausschnitt sehen können, laden wir das VPN-CA-Zertifikat und seine Zertifikatskette in den ACM hoch.
Schließlich haben wir alles vorbereitet, um unseren VPN-Endpunkt zu erstellen.
VPN-Erstellung
Da wir bereits alle Zertifikate vorbereitet und exportiert haben, können wir nun mit der Erstellung unseres Client-VPN-Endpunkts beginnen:
In diesem Block definieren wir den Client-VPN-Endpunkt und welche IP-Adressen für den Aufbau einer VPN-Verbindung verwendet werden sollen. Außerdem haben wir unsere Zertifikate für TLS(server_certificate_arn) und Authentifizierung zugewiesen. Außerdem haben wir split_tunnel aktiviert, was bedeutet, dass Datenverkehr, der nicht innerhalb unseres Tunnels ankommen soll, nicht in unsere VPC geroutet wird.
Was in dem Client-VPN-Snippet nicht angezeigt wird, sind einige Standardwerte, die gut zu wissen sind. Zunächst einmal ist das Standard-Transportprotokoll UDP und der Standard-Port, der geöffnet wird, ist der Port 443. Da wir über unser VPN auf AWS-Ressourcen zugreifen möchten, haben wir auch keinen DNS-Server definiert, sodass der Standard-DNS-Server der VPC verwendet wird.
Wie bei den meisten Ressourcen von AWS ist unser VPN-Endpunkt noch nicht zugänglich. Um ihn verfügbar zu machen, müssen wir eine Sicherheitsregel hinzufügen, die uns den Zugriff auf den VPN-Endpunkt über den definierten Port mit dem definierten Protokoll ermöglicht:
Wir beschränken nur den eingehenden Datenverkehr auf den festgelegten Port und das festgelegte Protokoll, während der ausgehende Datenverkehr erlaubt ist.
Nachdem der Zugriff auf den VPN-Endpunkt gehandhabt wurde, ist der nächste Schritt die Verbindung unseres VPN-Endpunkts mit unserer VPC - genauer gesagt mit einem oder mehreren Subnetzen unserer VPC.
In der Beispieldefinition werden alle definierten Subnetze mit jeweils einer Assoziationsregel verknüpft.
Aufgrund eines Problems innerhalb des terraform AWS-Providers wird bei jeder Aktualisierung die VPN-Netzwerkzuordnung entfernt und von Grund auf neu erstellt (und das dauert eine Weile). Aus diesem Grund ignorieren wir alle Änderungen am Attribut subnet_id.
Zu guter Letzt müssen wir auch eine Autorisierungsregel erstellen, die unseren Clients den Zugriff auf Ressourcen erlaubt. Da wir die zertifikatsbasierte Authentifizierung verwenden, können wir noch keine detaillierteren Regeln erstellen:
Mit diesem letzten Snippet haben wir das gesamte Terraform-Setup abgeschlossen und können es nun mit ausführen:
Das war's! Jetzt sollten Sie einen VPN-Endpunkt innerhalb von AWS erstellt haben.
Der gesamte Code für dieses Beispiel ist hier zu finden.
Verbinden mit unserem VPN-Endpunkt
Um sich mit einem VPN-Endpunkt zu verbinden, müssen Sie einen OpenVPN-kompatiblen VPN-Client - in unserem Fall den OpenVPN CLI Client - und eine entsprechende Konfiguration verwenden, um auf unseren Endpunkt zuzugreifen.
Wir können eine Basisversion der VPN-Client-Konfiguration direkt von AWS herunterladen. Dazu können wir entweder die AWS CLI verwenden oder sie über die Webkonsole herunterladen (VPNC > Client VPN Endpoints > Download Client Configuration).
Nachdem wir die Konfiguration heruntergeladen haben, müssen wir sie anpassen:
- While writing this article the certificate section of the client configuration is out-of-the-box broken, meaning that it is adding an additional certificate that should not be in there. To validate if your client configuration is messed up you have to take a look at the <ca> section and count the available certificates in it. If the counted number is four then you must delete the third certificate.
- Regardless if you have to fix the <ca> section our client ca certificates have to be added. So in our example, we must append the certificates of our exported certificate authorities placed in the files ca-chain.crt and client-vpn-ca.crt.
Jetzt sind wir bereit, unsere VPN-Verbindung zu testen:
Voilà, jetzt sollten Sie mit dem Client-VPN-Endpunkt verbunden sein.
Schlussfolgerung
Dies ist der Abschluss unserer Reise zur Erstellung eines Client-VPN-Endpunkts mit terraform auf AWS. Ich hoffe, diese kurze Anleitung spart Ihnen etwas Zeit und gibt Ihnen eine grobe Vorstellung davon, wie Sie einen Client-VPN-Endpunkt mit terraform einrichten können.