Mit Boundary und Vault sicher auf Kubernetes zugreifen
Über Grenzen und durch Schleusen
von Dr. Matthias Wübbeling
Veröffentlicht in Ausgabe 10/2024 - SCHWERPUNKT
Um in Kubernetes eine einfache und sichere Authentifikation mit Rolling Keys, zeitbasierten Logins und so weiter zu ermöglichen, bietet Vault von Hashicorp ein ausgereiftes System. Auch die Software Boundary aus demselben Hause ersetzt heute schon viele komplizierte VPN- und Bastionhost-Setups. Unser Workshop zeigt anhand dieser beiden Open-Source-Werkzeuge, wie sich mit ein wenig Aufwand ein Kubernetes-Cluster absichern und Zugriffe darauf steuern lassen.
Der Verlust von Logindaten der Benutzer, sei es durch Phishing direkt beim Anwender oder durch den Zugriff auf die Server von Internet-Dienstanbietern, stellt eine große Bedrohung für die Vertraulichkeit und Integrität der innerhalb eines Unternehmens eingesetzten Software und Plattformen dar. Mitarbeiter nutzen auch heute noch beruflich wie privat dieselben Passwörter für unterschiedliche Services. Aber auch Benutzergruppen teilen sich häufig ein Passwort zum gemeinsamen Zugang zu Ressourcen. Bestenfalls beginnen IT-Verantwortliche also bereits bei der Bereitstellung von Systemen mit einer entsprechenden Absicherung der genutzten Daten und einem kontrollierten Zugang auf die eigene Infrastruktur.
Vault [1] und Boundary [2] sind zwei Werkzeuge, die Ihnen vielleicht aus vorherigen Artikeln im IT-Administrator bereits bekannt sind. Beide bieten gemeinsam eine umfassende Sicherheitsumgebung für die Verwaltung von Geheimnissen und den kontrollierten Zugriff auf Systeme. Vault ist bekannt für seine Fähigkeit, sensible Zugangsdaten sicher zu speichern und dynamisch zu verwalten, während Boundary den sicheren direkten Zugriff auf lokale IT-Infrastruktur ohne den Einsatz traditioneller VPNs ermöglicht.
Dieser Workshop stellt Ihnen beide Werkzeuge kurz vor und zeigt Ihnen anschließend die Schritte zur Integration und gemeinsamen Nutzung von Boundary und Vault am Beispiel eines Kubernetes-Clusters. Sie erhalten Hinweise zur Installation, Konfiguration und Verwendung von Vault und Boundary mit dem Ziel, damit eine sichere und skalierbare Umgebung für die Anwendungen in Ihrem Unternehmen zu schaffen.
Der Verlust von Logindaten der Benutzer, sei es durch Phishing direkt beim Anwender oder durch den Zugriff auf die Server von Internet-Dienstanbietern, stellt eine große Bedrohung für die Vertraulichkeit und Integrität der innerhalb eines Unternehmens eingesetzten Software und Plattformen dar. Mitarbeiter nutzen auch heute noch beruflich wie privat dieselben Passwörter für unterschiedliche Services. Aber auch Benutzergruppen teilen sich häufig ein Passwort zum gemeinsamen Zugang zu Ressourcen. Bestenfalls beginnen IT-Verantwortliche also bereits bei der Bereitstellung von Systemen mit einer entsprechenden Absicherung der genutzten Daten und einem kontrollierten Zugang auf die eigene Infrastruktur.
Vault [1] und Boundary [2] sind zwei Werkzeuge, die Ihnen vielleicht aus vorherigen Artikeln im IT-Administrator bereits bekannt sind. Beide bieten gemeinsam eine umfassende Sicherheitsumgebung für die Verwaltung von Geheimnissen und den kontrollierten Zugriff auf Systeme. Vault ist bekannt für seine Fähigkeit, sensible Zugangsdaten sicher zu speichern und dynamisch zu verwalten, während Boundary den sicheren direkten Zugriff auf lokale IT-Infrastruktur ohne den Einsatz traditioneller VPNs ermöglicht.
Dieser Workshop stellt Ihnen beide Werkzeuge kurz vor und zeigt Ihnen anschließend die Schritte zur Integration und gemeinsamen Nutzung von Boundary und Vault am Beispiel eines Kubernetes-Clusters. Sie erhalten Hinweise zur Installation, Konfiguration und Verwendung von Vault und Boundary mit dem Ziel, damit eine sichere und skalierbare Umgebung für die Anwendungen in Ihrem Unternehmen zu schaffen.
Kubernetes statt Docker Compose
Gerade Entwickler und Administratoren in der Systemintegration schätzen heute die Möglichkeit der Containerisierung. So ist schnell eine Testumgebung aufgesetzt oder das Deployment einer Software realisiert. Für viele von ihnen beginnt der Einstieg in das Management von Containern mit Docker und dem mittlerweile direkt in Docker integrierten Compose.
Der nächstgrößere Schritt ist dann der Betrieb eines Clusters zur allgemeinen Bereitstellung, Skalierung und Verwaltung von vielen containerisierten Anwendungen im Unternehmen. Kubernetes beziehungsweise eine der vielen davon abgeleiteten Umsetzungen wie K3S oder Minikube für die lokale Installation haben sich als Standard für die Orchestrierung von Containern und Ressourcen etabliert und bieten zahlreiche Funktionen wie automatische Selbstheilung von Services, die horizontale Skalierung dieser als Teil von High-Availability-Strategien oder Service Discovery. Kubernetes selbst ist skalierbar und kann große, komplexe Anwendungen verwalten, die über mehrere Nodes oder Rechenzentren verteilt sind.
Was Vault und Boundary leisten
Natürlich richtet sich die Aufmerksamkeit bei dem 2015 veröffentlichten Vault zunächst auf den offensichtlichen Anwendungsfall, die dynamische Bereitstellung von Passwörtern zum Zugang zu Computer- oder Serversystemen. Dahinter steckt die Idee, dass der gemeinsame Zugriff auf ein Benutzerkonto, etwa ein Administratorkonto zur Verwaltung eines Servers, nicht zwingend auch ein geteiltes Passwort der Benutzer zur Folge haben muss. Die Komplexität wird nicht nur bei dem Gedanken an personelle Veränderungen des Teams sofort deutlich, sondern auch bei routinemäßig durchgeführten Passwortwechseln.
Vault ist aber viel mehr als nur ein Tool zur Generierung von Einmalpasswörtern. Es dient der Verwaltung und dem Schutz geheimer Informationen wie API-Schlüsseln, Passwörtern oder Zertifikaten. Das Tool ermöglicht das sichere Speichern und den verteilten Zugriff auf diese Secrets und stellt umfassende Verwaltungsmöglichkeiten bereit. Zu den wesentlichen Funktionen von Vault gehören das zentrale Management von Secrets mit Zugriffskontrollen, die automatische Generierung und Verwaltung von kurzlebigen Secrets sowie die Bereitstellung von Verschlüsselungsdiensten für den Datenverkehr zwischen mehreren Computern. Mit Vault können Sie zudem feingranulare Zugriffskontrollen basierend auf definierbaren Richtlinien oder die Nachvollziehbarkeit von Benutzerlogins ohne großen Aufwand umsetzen.
Das zweite in diesem Artikel vorgestellte Werkzeug ist Boundary. Es ist wohl kein Zufall, dass auch Boundary eine Entwicklung von Hashicorp ist. Es ergänzt Vault im Zusammenspiel unseres Beispielszenarios und bietet eine Lösung für den sicheren netzwerktechnischen Zugang zu Anwendungen und Infrastruktur, die bei gleicher Nutzbarkeit die Komplexität traditioneller VPN-Lösungen vermeidet. Boundary ermöglicht Ihnen, Zugriffskontrollen zu Ihren Diensten fein abzustimmen und Benutzersitzungen effektiv zu verwalten. Wichtige Funktionen von Boundary sind die sichere Authentifizierung und Autorisierung basierend auf Richtlinien, das Sitzungsmanagement sowie granulare Zugriffskontrollen basierend auf Rollen und Richtlinien. Boundary trägt somit ebenso wie Vault zur Verbesserung der Sicherheit und Zugriffsverwaltung im IT-Umfeld bei.
Einsatz mit Kubernetes
Für die Implementierung der gemeinsamen Nutzung von Vault und Boundary in einem Kubernetes-Cluster sind bestimmte Voraussetzungen zu erfüllen. Sie benötigen natürlich zunächst einen Kubernetes-Cluster, mit dem Sie das Setup ausprobieren. Diesen können Sie, wie bereits erwähnt, lokal mit Minikube [3] aufsetzen, einen eigenen Cluster mit Kubernetes.io erstellen oder Dienste in den klassischen Clouds der drei großen Anbieter Google, Microsoft und Amazon (hier in Form der Kubernetes-Services GKE, EKS und AKS) verwenden.
Damit Sie von Ihrem Computer auf diese Dienste zugreifen können, sollten die notwendigen CLI-Tools wie kubectl, helm installiert sein. Für die Nutzung von Vault und Boundary benötigen Sie zum Testen natürlich auch die lokalen Clienttools dieser beiden. Falls möglich, sollten Sie TLS-Zertifikate etwa von Let’s Encrypt für die von Vault und Boundary genutzte Domain beantragen, um die Kommunikation zusätzlich abzusichern. Ein grundlegendes Verständnis von Kubernetes und der Verwaltung von Secrets und Zugriffskontrollen ist ebenfalls erforderlich, ebenso wie entsprechende Administratorrechte in Ihrem Kubernetes-Cluster.
In unserem Beispiel benutzen wir Minikube zum Aufsetzen eines lokalen Kubernetes auf einem Linux-System. Installieren Sie dafür mit Ihrem Paketmanager Minikube oder laden Sie unter [4] das letzte Release herunter. Anschließend sollten Sie es einfach in "minikube" umbenennen und so verschieben, dass Sie es im lokalen Pfad für ausführbare Dateien haben. Nun können Sie Minikube direkt aus der Konsole aufrufen. Prüfen Sie das etwa mit der Anzeige der installierten Version über minikube version.
Wie Sie in Bild 1 erkennen, ist zum Zeitpunkt der Erstellung dieses Artikels ist die Version 1.33.1 aktuell. Die Anzeige des Commits liefert die Prüfsumme des Git-Repositories zu dem Zeitpunkt, als das Binary gebaut wurde. Diese Angabe ist vor allem für die Fehlersuche relevant. Ihren ersten Cluster-Knoten starten Sie nun mit dem folgenden Kommando und prüfen direkt die dann laufenden Knoten:
minikube start
minikube kubectl -- get nodes
Bild 1: Unsere Prüfung zeigt, dass Minikube in Version 1.33.1 aktuell ist.
Wenn Sie nach einiger Zeit die Darstellung wie in Bild 2 sehen – Minikube lädt beim ersten Start noch alle notwendigen Images herunter und konfiguriert einige Dinge im Hintergrund –, ist Kubernetes bei Ihnen fertig eingerichtet. Natürlich können Sie kubectl auch direkt starten, wenn Sie es in ihrem Betriebssystem installiert haben. Als Bestandteil von Minikube passt es aber immer zu der aktuell eingesetzten Version. Möchten Sie in Ihren Tests gern richtiges Cluster-Feeling, können Sie Minikube weitere Knoten hinzufügen:
minikube node add
Bild 2: Kubernetes ist fertig eingerichtet und bereit für die Integration mit Vault.
Anschließend zeigt das "get nodes"-Kommando entsprechend zwei Knoten an, wie in Bild 3 zu sehen.
Bild 3: Der zweite Cluster-Knoten ist erfolgreich angelegt.
Vault installieren
Nachdem Sie das Kubernetes-Cluster mit Minikube eingerichtet haben, beginnen Sie mit der Installation und Konfiguration von Vault. Die Software bietet für Cluster eine sichere Möglichkeit, sensible Informationen wie API-Schlüssel, Passwörter und Zertifikate zu verwalten und darauf zuzugreifen. Sie sollten Vault in einem eigenen Namespace installieren, um die Trennung von anderen laufenden Containern und damit die Integrität der Anwendung sicherzustellen. Legen Sie also einen neuen Namespace mit dem Namen "vault" im Cluster an und ändern Sie für die weitere Benutzung für alle Tools den Namensraum. Auf diese Weise müssen Sie nicht immer den korrekten Namensraum mit angeben:
Die Installation von Vault erfolgt nun mittels Helm. Helm ist im Grunde eine Art Paketmanager für Kubernetes. Haben Sie Helm noch nicht installiert, holen Sie dies nun nach. Anschließend fügen Sie das Hashicorp-Repository hinzu und aktualisieren die Helm-Repositories, um sicherzustellen, dass Sie die jeweils aktuellen Versionen verwenden. Anschließend installieren Sie Vault aus dem Hashicorp-Repository:
Um zu prüfen, ob die Installation von Vault funktioniert hat, fragen Sie zunächst die Übersicht der laufenden Container von Minikube ab:
minikube kubectl -- get pods
Sie sehen nun zwei gestartete Container, einmal die Vault-Anwendung selbst und als zweites einen als "Injector" mit zufälligen Zeichen benannten Container. Letzterer übernimmt die Anpassung der im Cluster laufenden Container, sodass diese auch ohne lokale Vault-Installation Geheimnisse von Vault verwenden können. Sollte sich die Vault-Anwendung in der Spalte "READY" als Wert "0/1" darstellen, kann das unterschiedliche Ursachen haben. In unseren Tests lag das mitunter an einem Problem mit dem Speicher, der aus dem Helmchart angefordert wird. Prüfen Sie mit
minikube kubectl -- get pvc
den Status des Volume-Claims mit dem Namen "data-vault-0". Wenn dieser unter "STATUS" nicht den Wert "Bound" anzeigt, kann das an einem fehlenden persistenten Speicher liegen. Um diesen anzulegen, erstellen Sie zunächst mit der in Listing 1 dargestellten Definition eine Standard-Storageclass und legen anschließend den persistenten Speicher mit der Datei aus Listing 2 an, indem Sie die folgenden Kommandos ausführen:
path: /tmp/pvSchwerpunktBoundary und Vault für Kubernetes
Sollte der Speicher bereits erfolgreich eingebunden sein, gibt es dennoch einen Grund, warum der Container noch nicht auf "READY" steht. Haben Sie Vault lokal installiert, können Sie sich ab hier das Leben etwas erleichtern. Vault muss natürlich erst einmal initialisiert beziehungsweise entsperrt werden:
Läuft das Kommando erfolgreich durch, erhalten Sie eine entsprechende Ausgabe. Sie finden fünf unterschiedliche Schlüssel zum Freischalten Ihres Tresors und das sogenannte Root-Token, das Sie für die weitere Arbeit mit dem Vault-Container verwenden. Erhalten Sie beim Initialisieren den Fehler, dass der Tresor wegen fehlender Schreibrechte nicht angelegt werden kann, ist es möglich, dass beim Erstellen des Containers ein von Vault genutzter Ordner einen falschem Besitzer erhalten hat. Leider können wir diese Berechtigung nicht einfach so ändern, vielmehr müssen Sie mit Root-Rechten im Container arbeiten. Zunächst suchen Sie die ID des laufenden Containers:
minikube ssh docker container ls | grep vault_vault-0
Nutzen Sie die erste ID in der Ausgabe für das nun folgende Kommando:
Anschließend führen Sie noch einmal vault operator init aus und erhalten nun hoffentlich die entsprechende Ausgabe mit den Schlüsseln zum Freischalten. Statt alle Kommandos an Vault über Minikube beziehungsweise kubectl umzuleiten, können Sie Vault direkt von Ihrer Maschine erreichbar machen. Dafür aktivieren Sie das Port-Forwarding von Minikube:
minikube kubectl -n vault portforward $(kubectl get pod -n vault vault-0 -o jsonpath=" {.metadata.name}") 8200:8200
Dann setzen Sie die folgenden Umgebungsvariablen in Ihrer Terminalsitzung:
export VAULT_ADDR=http:// 127.0.0.1:8200
Üblicherweise würden die Unseal-Keys nun an fünf unterschiedliche Personen verteilt, um den Tresor maximal zu schützen. In unserem Fall speichern Sie die Werte einfach erst einmal und entsperren anschließend den Tresor, indem Sie mit drei unterschiedlichen Schlüsseln das folgende Kommando ausführen:
vault operator unseal <Schlüssel>
Jetzt ist Vault also einsatzbereit. Um damit zu arbeiten, müssen Sie sich erst mit dem root-Token wie folgt einloggen:
vault login <token>
Jetzt kümmern Sie sich um die Authentifikation mit Vault auf Ihrem Kubernetes. Dafür aktivieren Sie das entsprechende Authentifikationsmodul und legen einen Serviceaccount an, der die Authentifikation durchführen kann:
Auch wenn das auf den ersten Blick etwas verwirrend aussieht, hinterlegen Sie hier im Grunde nur das Token des Vault-Service-Accounts zur Authentifikation bei Kubernetes – zusammen mit dem Hostnamen des Vault-Services und dem CA-Zertifikat für die verschlüsselte TLS-Verbindung. Damit nun auch die Anwendungen Zugriff auf Vault erhalten, hinterlegen Sie noch eine entsprechende Rolle, die den Zugriff auf den Tresor regelt:
vault write auth/kubernetes/role/ example bound_service_account_names=default bound_service_account_namespaces=default policies=default ttl=24h
Nach diesen durchaus nicht besonders intuitiven Schritten ist Vault nun bereit, um Anwendungen im Kubernetes-Cluster zu dienen. Applikationen können sich nunmehr bei Vault authentifizieren, Secrets abrufen und sicher speichern.
Mit Boundary sicher verbinden
Boundary ist eine von Hashicorps jüngeren Anwendungen, die erste Version stammt aus dem Herbst 2020. Das Tool verspricht eine Kombination aus VPN, Port-Weiterleitungen wie bei Bastion-Hosts und Benutzerauthentifikation und -auditierung. Boundary bietet Administratoren eine übersichtliche Möglichkeit, individuelle Zugriffsrechte zu Services zu konfigurieren und Sitzungen zu verwalten. Auch wenn es im Grunde naheliegt, Boundary genauso wie Vault direkt im Kubernetes-Cluster selbst zu betreiben, bietet Hashicorp dafür aktuell keine fertigen Helmcharts oder vorbereitete Manifest-Dateien an. Es gibt ein Github-Projekt, in dem Sie von der Community erstellte Deployments einsehen und selbst nutzen können [5]. Sollten Sie auch Terraform von Hashicorp einsetzen, können Sie dies in Ihrem Kubernetes-Cluster natürlich als Backend konfigurieren und Boundary damit ausrollen.
Aus Platzgründen gehen wir an dieser Stelle davon aus, dass Sie Boundary bereits erfolgreich auf Ihrem aktuellen Host-System installiert und konfiguriert haben. Als nächstes erstellen Sie eine Vault-Policy, die es Boundary erlaubt, die verschiedenen Leases zu erstellen. Führen Sie dafür das Kommando in Listing 3 aus.
Um den Zugriff auf Ressourcen zu steuern, erstellen Sie Rollen und Policies in Boundary, die definieren, welche Benutzer auf welche Ressourcen zugreifen dürfen. Zuerst authentifizieren Sie sich bei Boundary, dafür brauchen Sie die ID der Authentifikationsmethode und Ihre Logindaten:
Nachdem Sie sich authentifiziert haben, erstellen Sie auf der obersten Boundary-Ebene eine neue Organisation für unser Beispiel mit dem scopes-create-Befehl. Ein Hinweis: Alle ab hier ausgeführten Kommandos geben immer die ID des erstellten Objekts an. Diese benötigen Sie dann für die nachfolgenden Operationen:
Bevor Sie nun die Credential-Library in Boundary anlegen, erstellen Sie mit dem ersten Kommando in Vault noch eine entsprechende Rolle. Für dieses Beispiel sollen einfach die laufenden Pods angezeigt werden können. Die Lebensdauer des Tokens soll zunächst zwei Minuten betragen:
Anschließend können Sie das von Ihnen erstellte Backend für kubectl verwenden.
Fazit
Hashicorp entwickelt Stück für Stück sinnvolle und sichere Werkzeuge, die oft nahtlos ineinandergreifen. Während das Aufsetzen häufig nicht intuitiv ist, macht die Integration von Boundary und die Nutzung von Vault für die Authentifikation beim Kubernetes-Cluster für Administratoren in allen Bereichen das Leben viel einfacher. So ist auch für die üblichen Verfahren für Continuous Integration und Deployment eine Nutzung ohne großen Aufwand möglich.