Der sichere Zugriff auf dynamische Cluster- und Cloudressourcen in internen Netzwerken ist immer wieder eine Herausforderung für Administratoren. Mit Hashicorp Boundary lässt sich der Zugang zu statischen Diensten ebenso einfach realisieren wie zu dynamisch provisionierten Services. Dabei überwinden rollenbasierte Authentifikation und ein genau konfigurierbarer Zugriff auf Ressourcen übliche Grenzen.
Vor gut eineinhalb Jahren hat Hashicorp die erste Version von Boundary [1] veröffentlicht, einem Werkzeug zum Steuern des Netzwerkzugangs. Seitdem haben die Entwickler stetig neue Features hinzugefügt und Fehler gefixt. Obwohl Boundary heute mit Version 0.7.4 dem "Semantic Versioning" [2] entsprechend zwar noch nicht stabil ist, haben wir es uns dennoch für Sie angesehen und den Einsatz in einer Cloudumgebung ausprobiert.
Das Universum der Hashicorp-Software sind vor allem Cloud Computing und Containerumgebungen wie Kubernetes. Mit Boundary kommt zusätzlich zu den existierenden Werkzeugen der sichere Re-motezugang auf die Habenseite des Unternehmens. Dabei ist Boundary nicht einfach ein Gateway in ein privates Netzwerk, sondern durch die Integration des rollenbasierten Zugangsmodells ein identitätsbasiertes Zugangsmanagement für dynamische Infrastrukturen.
Grenzen klassischer Fernsteuerung
Der Zugriff auf Ressourcen innerhalb eines Unternehmensnetzwerks oder eines extern betriebenen Clusters erfolgt üblicherweise per VPN oder mittels sogenannter SSH-Bastion-Hosts. VPN-Verbindungen finden auf Netzwerkebene statt. Das bedeutet, die Computer der Mitarbeiter erhalten als Client eine eigene IP-Adresse aus dem privaten Netzwerk. Damit sind diese also recht umfassend in das private Netzwerk eingebunden und können bei einer bestehenden VPN-Verbindung auf alle Dienste des Netzwerks zugreifen – Zugriffsbeschränkungen auf die internen Dienste und der Clients untereinander lassen sich über verschiedene IP-Bereiche der Clients und mit internen Firewalls realisieren.
Vor gut eineinhalb Jahren hat Hashicorp die erste Version von Boundary [1] veröffentlicht, einem Werkzeug zum Steuern des Netzwerkzugangs. Seitdem haben die Entwickler stetig neue Features hinzugefügt und Fehler gefixt. Obwohl Boundary heute mit Version 0.7.4 dem "Semantic Versioning" [2] entsprechend zwar noch nicht stabil ist, haben wir es uns dennoch für Sie angesehen und den Einsatz in einer Cloudumgebung ausprobiert.
Das Universum der Hashicorp-Software sind vor allem Cloud Computing und Containerumgebungen wie Kubernetes. Mit Boundary kommt zusätzlich zu den existierenden Werkzeugen der sichere Re-motezugang auf die Habenseite des Unternehmens. Dabei ist Boundary nicht einfach ein Gateway in ein privates Netzwerk, sondern durch die Integration des rollenbasierten Zugangsmodells ein identitätsbasiertes Zugangsmanagement für dynamische Infrastrukturen.
Grenzen klassischer Fernsteuerung
Der Zugriff auf Ressourcen innerhalb eines Unternehmensnetzwerks oder eines extern betriebenen Clusters erfolgt üblicherweise per VPN oder mittels sogenannter SSH-Bastion-Hosts. VPN-Verbindungen finden auf Netzwerkebene statt. Das bedeutet, die Computer der Mitarbeiter erhalten als Client eine eigene IP-Adresse aus dem privaten Netzwerk. Damit sind diese also recht umfassend in das private Netzwerk eingebunden und können bei einer bestehenden VPN-Verbindung auf alle Dienste des Netzwerks zugreifen – Zugriffsbeschränkungen auf die internen Dienste und der Clients untereinander lassen sich über verschiedene IP-Bereiche der Clients und mit internen Firewalls realisieren.
Im Gegensatz zum VPN finden Tunnel über Bastion-Hosts auf der Verbindungsebene statt. Clients bauen zunächst eine Verbindung zum Bastion-Host auf und weiterführende Verbindungen zu den internen Diensten werden in der Art eines Proxies weitergeleitet. Das bedeutet, dass Clients nicht Teil des privaten Netzwerks werden. Das heißt aber auch, dass Bastion-Hosts im privaten Netzwerk selbst nur wenig isoliert sind, damit unterschiedliche Clients umfangreichen Zugriff auf alle benötigten Dienste erhalten. Umsetzungen mit unterschiedlichen Bastion-Hosts und benutzerspezifischen Firewallregeln auf den Bastion-Hosts sind mit großem Aufwand verbunden und in der Praxis eher unflexibel.
Der Zugriff auf einzelne Server oder Dienste in dynamischen Umgebungen wie Kubernetes, wo diese automatisiert provisioniert und wieder gestoppt werden, lässt sich nicht einfach und zuverlässig statisch konfigurieren. Häufig ist nicht einmal die IP-Adresse im Vorfeld bekannt, zu der Sie eine Verbindung aufbauen müssen. Der Umsetzung mit VPNs oder Bastion-Hosts sind dabei also Grenzen gesetzt.
Benutzer benötigen für den Zugriff auf die internen Dienste meist unterschiedliche Logindaten. Der Zugang zum privaten Netz ist bestenfalls nur mit Zertifikaten möglich, häufig finden sich jedoch auch hier noch Directory-basierte Logins mit Benutzernamen und Passwort. Im nächsten Schritt erfolgt dann noch einmal eine Authentifikation bei den internen Diensten selbst. Hier dominieren Benutzername und Passwort, wenngleich zertifikatbasierte Verfahren immer häufiger zum Einsatz kommen.
Für den gemeinsamen Zugriff auf geteilte Ressourcen, etwa Datenbankserver oder SSH-Dienste, sowie die Nutzung geteilter Passwörter zur Administration bietet Hashicorp mit Vault bereits eine komfortable und etablierte Lösung mit Einmalpassworten an. Vault haben wir Ihnen bereits vor einiger Zeit in einem Artikel vorgestellt [3]. Es erlaubt, geteilte Administrations- oder Root-Zugänge zu verwalten und die damit durchgeführten Aktivitäten auch später noch dem tatsächlichen Benutzer zuzuordnen. Geteilte Passwörter zur Administration sind also nicht mehr bei jedem Personalwechsel neu zu setzen, vielmehr wird einfach der alte Benutzer aus der Liste der erlaubten Zugriffe entfernt.
Wie Boundary beim Zugang hilft
Boundary verbindet die Konzepte von privatem Netzwerkzugang und individueller Zugriffskontrolle auf die verfügbaren Dienste und bedient sich dabei bereits vorhandener Tools. Boundary ist dabei sowohl der Dienst, mit dem sich ein Benutzer verbinden muss, um Zugang zu den internen Diensten zu erhalten, als auch das Clientwerkzeug, mit dem der Anwender die Verbindung aufbaut. Für den Log-in verwenden Sie hier Single Sign-on (SSO). Dafür können Sie einfach ein selbst betriebenes Active Directory mit konfigurierten Federation Services oder einen der externen SSO-Dienstleister nutzen.
Basierend auf dem durchgeführten Login ermöglicht Boundary die Zuweisung von Zugriffsrechten anhand der Rollen, die ein Benutzer innehat. Dabei sind Rollen nicht nur seitens der Benutzer zu finden, sondern auch seitens der Dienste. Hashicorp verwendet hier den Begriff der "logischen Dienste". Das bedeutet, dass etwa die Rolle "Datenbank-Administrator" Zugang zu Datenbankdiensten hat und Weboperatoren entsprechend zu den Servern oder Containern, die Webdienste anbieten. Das Ganze ist unabhängig davon, wo diese Dienste tatsächlich laufen beziehungsweise welche IP-Adressen diese verwenden. Natürlich können Sie hier flexibel unterscheiden, etwa zwischen Admins für MongoDB und für Postgres-Datenbanken. Dafür erstellen Sie in Boundary Ihren Anforderungen entsprechende Richtlinien (Policies), die diese Zuordnung definieren.
Für den Zugriff auf die internen Dienste können Ihre Benutzer dieselben Werkzeuge verwenden wie bei einem direkten Zugriff. Als Host setzen Sie in den Verbindungseinstellungen einfach "localhost". Das bedeutet auch, dass Zugriffe auf Ressourcen in Ihrem privaten Netzwerk, die nicht über diese Policies abgebildet sind, über Boundary auch nicht möglich sind. Damit haben Sie ohne die Nutzung von Firewalls eine umfassende Kontrolle über die Verbindungsmöglichkeiten der Clients.
Wenn Sie zusätzlich zu Boundary im Netzwerk auch Vault betreiben, benötigen Ihre Benutzer nicht einmal die Logindaten zu dem Dienst, auf den sie zugreifen möchten. Boundary erfragt diese Credentials eigenständig bei der Vault-Instanz, die auch innerhalb Ihres privaten Netzwerks liegen kann, und authentifiziert sich als Proxy-Instanz selbst bei dem entsprechenden Dienst. Das funktioniert natürlich nur bei Protokollen, die Boundary unterstützt – also etwa SSH, Postgres, HTTP oder Remotedesktop und bei der Verbindung zu Kubernetes.
Installation und Konfiguration
Damit Sie Ihren Benutzern Boundary als Zugangsmöglichkeit anbieten können, müssen Sie es zunächst vorbereiten. Dabei müssen Sie Ihre bisherigen Zugangswege nicht direkt abschalten, sondern können Boundary ohne Probleme zunächst testen und parallel laufen lassen. Auch wenn Boundary schon relativ stabil wirkt, sollten Sie mit dem Produktiveinsatz auf die Version mit der Nummer eins warten.
Wir demonstrieren Ihnen die Installation von Boundary auf einem Server mit Ubuntu. Hashicorp bietet dafür ein eigenes Repository an, das Sie in Ihr System einbinden sollten. Dafür müssen Sie zunächst den öffentlichen Schlüssel des Repositories importieren. Anschließend führen Sie ein Update durch und installieren Boundary mit den folgenden Kommandos:
Boundary verwendet Postgres als Datenbank. Wenn Sie Boundary in diesem Schritt nur ausprobieren und im Entwicklermodus betreiben möchten, kümmert sich Boundary selbst um die Initialisierung der Datenbank. Allerdings ist dafür zusätzlich Docker auf Ihrem System zu installieren. Das erledigen Sie mit den folgenden Kommandos:
Um Boundary nun im Entwicklungsmodus zu starten, führen Sie folgendes Kommando aus und warten beim ersten Start ein wenig auf die Initialisierung der DB:
boundary dev -login-name="<it-administrator>" -password="<geheim>"
Sobald Sie Logausgaben sehen, können Sie sich bereits mit Ihrem Browser an der Weboberfläche anmelden. Beachten Sie, dass die Software Änderungen beim Beenden des Entwicklungsservers nicht speichert. Öffnen Sie nun die URL "http://localhost:9200" und melden sich mit den gewählten Logindaten an. Denken Sie daran, wenn Sie Boundary auf einem entfernten Server mit SSH installieren, dass Sie eine entsprechende Portweiterleitung einrichten. Mit OpenSSH richten Sie in einer laufenden Verbindung mit ~C in der SSH-Konsole und dort mit -L9200:localhost:9200 das Forwarding auf Ihren lokalen Computer ein.
Beachten Sie ebenfalls, dass Sie den Zugriff von außen auf die Postgres-Datenbank verhindern beziehungsweise diesen nicht versehentlich freigeben. Diese initialisiert Boundary nämlich im Dev-Modus einfach mit dem Login "postgres:password" – eine willkommene Einladung an Angreifer.
Benutzer und Accounts nutzen
Boundary legt im Entwicklermodus bereits eine Reihe von Benutzern und Accounts im globalen Scope des Systems an. Dabei unterscheidet das Tool Benutzer und Accounts. Jedem Benutzer können Sie unterschiedliche Konten zuordnen. Das bedeutet, Sie können sich etwa mit einem Account per Passwort oder per SSO authentifizieren und damit unter demselben Benutzer agieren. Andersherum lässt sich aber jeder Account nur höchstens einem Benutzer zuordnen. Sie können sich also mit demselben Konto nicht als Admin und als einfacher Benutzer gleichzeitig anmelden.
Bevor Sie in der Lage sind, Accounts und Benutzer zu verwalten, müssen Sie zunächst die Authentifikationsmethode erstellen. Das können Sie für jeden Scope getrennt erledigen. Klicken Sie im Webinterface auf den Menüpunkt "Auth Methods" und wählen Sie unter "New" die Methode, die Sie zunächst hinzufügen möchten. Zur Auswahl stehen "Passwort" und "OpenID Connect (OIDC)" als Anbindung an Ihr Single-Sign-on-Backend. Die Konfiguration ist genauso einfach wie bei anderen Tools, die Sie vermutlich bereits einsetzen. Wenn Sie die Werte für Ihr Backend parat haben, probieren Sie es aus. Sie können im Entwicklermodus auch beim vorkonfigurierten OIDC-Backend in die Einstellungen schauen, um eine Idee von der Konfiguration zu erhalten. Hashicorp liefert zum Testen nämlich ein simples OIDC-Backend mit.
Um erst einmal weiterzumachen, bietet sich die "Passwort"-Methode ohne weitere Konfiguration an. Auch diese ist im Dev-Mode eigentlich bereits vorbereitet, Sie können aber einfach eine zweite anlegen. Notieren Sie sich die generierte ID der Methode, diese benötigen Sie später noch einmal. Fügen Sie anschließend noch einen Account hinzu und vergeben ein sicheres Passwort. Anschließend sehen Sie die Kontoeinstellungen und die von Boundary generierte Account-ID. Wenn Sie später zur Administration und Benutzung in den CLI-Modus wechseln, benötigen Sie diese von Boundary generierten IDs zwingend. Der Einfachheit halber bleiben wir aber zunächst im Webinterface. Wenn sie nun unter "Users" einen neuen Benutzer anlegen, können Sie hier direkt den soeben angelegten Account zuweisen. Damit haben Sie bereits die erste Hürde genommen.
Rollen anlegen
Nehmen wir einmal an, der neue Benutzer soll ein klassischer Systemadministrator sein und per SSH Zugang zu der Infrastruktur seiner Organisationseinheit erhalten. Klicken Sie im Menü auf "Roles", um eine entsprechende Rolle anzulegen. Geben Sie dieser einen beliebigen Namen und speichern Sie die Rolle. Anschließend ändern Sie mit einem Klick auf "Edit Form" den Scope auf den "Generated project scope". Wählen Sie in den Einstellungen der Rolle "Principals", können Sie Benutzer und Gruppen zu dieser Rolle zuweisen.
Damit der Benutzer mit seiner Rolle etwas anfangen kann, müssen Sie der Rolle nun Berechtigungen zuweisen. Das machen Sie unter dem Punkt "Grants". Hier lassen sich natürlich nicht einfach vorgefertigte Berechtigungen vergeben. Vielmehr vergeben Sie Rechte anhand einer festgelegten Syntax mit verschiedenen Optionen einfach als Zeichenkette oder als JSON. Dabei gibt es die beiden Optionen "id" und "type", um eine Ressource auszuwählen. Ressourcen bezeichnen in Boundary beispielsweise Benutzer, Accounts, Credentials, Gruppen, Hosts, Scopes oder sogenannte Targets. Bei Targets handelt es sich um Dienste, die Boundary unterstützt und auf die sich über Sessions zugreifen lässt, so etwa die schon erwähnten SSH- oder Postgres-Server. Die Option "id" ist die von Boundary eindeutig zugewiesene ID oder eine Wildcard und "type" ist der Ressourcentyp, also zum Beispiel Target oder User.
Zusätzlich setzen Sie in der Option "actions" die Zugriffsrechte. Die üblichen CRUD-Zugriffsrechte "create", "read", "update" und "delete" stehen dabei zur Verfügung und werden von weiteren wie etwa "list" ergänzt. Sie können für unterschiedliche Ressourcentypen noch weitere Zugriffsrechte definieren, etwa "set-password" für Accounts oder "set-hosts", um einem Host-Set weitere Hosts hinzuzufügen.Um bei unserem Beispiel zu bleiben und den Zugriff auf SSH-Server hinter Boundary zu ermöglichen, soll der Typ "Target" für die Auswahl der Server zum Einsatz kommen. Mit der folgenden Zeichenkette erlauben Sie also Zugriff auf alle Ressourcen, die einem Target zugeordnet sind:
Vermutlich ist Ihnen nun schon aufgefallen, dass damit alle einem Target zugeordneten Ressourcen freigegeben sind. Unabhängig von der tatsächlichen Bedeutung des Targets also auch Datenbank- oder Dateiserver. Das sollten Sie also für den reinen SSH-Zugriff weiter einschränken. Da bisher noch kein Target angelegt ist, fügen Sie die Regel an dieser Stelle erst einmal hinzu und ändern diese später wieder.
Rollenberechtigungen einschränken
Gehen wir davon aus, dass Sie Boundary in einer Cloudumgebung testen. Dort gibt es ein internes Netzwerk, das Sie der Boundary-Instanz zuweisen können. Im internen Netzwerk soll der Zugriff auf die Server per SSH erlaubt sein. Das Target sollte also bestenfalls alle Hosts in dem Subnetz umfassen.
Targets sind in Boundary Teil von Projekten und diese erzeugen Sie in den einzelnen Scopes. Klicken Sie sich durch den im Dev-Mode angelegten Scope zum vorhandenen Projekt durch. Das Menü auf der linken Seite ändert sich nun in den Projektmodus. Unter "Host Catalogs" können Sie nun alle Hosts definieren. Ignorieren Sie den automatisch generierten Katalog des Entwicklermodus und legen Sie mit einem Klick auf "New" einen neuen Katalog an. Dieser benötigt lediglich einen Namen und eine optionale Beschreibung. In den Einstellungen des Katalogs wählen Sie nun "Host Sets" und erstellen dort mit einem Klick auf "Manage" ein neues Host-Set für die SSH-Server.
Anschließend wählen Sie das erzeugte Host-Set aus, indem Sie auf den Namen klicken. In den Einstellungen wählen Sie unter Hosts dann "Create and Add Host" und füllen die entsprechenden Felder mit dem Namen, der Beschreibung und der Adresse beziehungsweise dem Hostnamen aus. Nach dem Speichern haben Sie erfolgreich ein Host-Set mit einem statischen Host angelegt, das Sie nun in einem Target verwenden können.
Damit wechseln Sie im linken Menü zu den Targets und legen ein neues Target mit einem Klick auf "New" an. Vergeben Sie wieder einen sinnvollen Namen sowie eine kurze Beschreibung. Wenn Sie mögen, können Sie die Dauer einer Session ebenso einschränken wie die Anzahl gleichzeitiger Verbindungen. Möchten Sie verhindern, dass sich mehrere Admins, die zeitgleich auf einem Server arbeiten, in die Quere kommen, beschränken Sie die Anzahl der Verbindungen einfach auf "1". In diesem Fall können Sie aber zu Testzwecken mit "-1" einfach keine Einschränkung vornehmen. Als "Default Port" tragen Sie für SSH Port 22 ein.
Nach dem Speichern wählen Sie für das erzeugte Target nun unter "Host Sources" das zuvor angelegte Host-Set aus, indem Sie unter "Manage" auf "Add Host Sources" klicken und dieses entsprechend hinzufügen. Kopieren Sie nun den generierten Namen des Targets, der Ihnen in den Einstellungen angezeigt wird. Dieser sieht ähnlich aus wie etwa "ttcp_GvvuPXSdgF". Gehen Sie nun zurück in die globalen Rolleneinstellungen, indem Sie im linken Menü auf "Orgs" klicken und damit das Hauptmenü zurückerhalten. In den "Grants"-Einstellungen der Rolle ändern Sie nun die Option "id" und entfernen die Einschränkung des Typs (dieser ist implizit mit der ID gegeben), sodass die Zeichenkette in etwa so aussieht:
Anschließend speichern Sie die Rolle ab. Nun haben Sie alles vorbereitet für einen ersten Test der Boundary-Funktionalität.
Boundary im Einsatz
Auf dem Client verwenden Sie dasselbe Binary wie auf dem Server. Installieren Sie also wie oben gezeigt Boundary – auf die Installation von Docker können Sie hier aber verzichten. Achten Sie darauf, dass der Dev-Mode nur auf dem Loopback-Device des Servers Verbindungen annimmt und Sie daher den oben aktivierten SSH-Tunnel auf Port 9200 aufrechterhalten müssen. Erstellen Sie zusätzlich einen Tunnel mit dem Port 9202 zum Worker in Ihrem internen Netzwerk.
Der erste Schritt ist nun die Authentifikation des Benutzers mit dem zuvor angelegten Benutzeraccount. Auf der Kommandozeile können Sie das erreichen, indem Sie folgenden Befehl ausführen: Ersetzen Sie "<method_id>" durch die ID der zuvor zusätzlich angelegten Passwort-Authentifikation und verwenden Sie den entsprechenden Benutzernamen für "<username>" und das zugehörige Passwort für "<password>":
Wie in Bild 2 erhalten Sie das Token, mit dem Sie nun arbeiten können. Bestenfalls exportieren Sie das Token in der Umgebungsvariablen "BOUNDARY_TOKEN". Dann müssen Sie es nicht bei jedem Aufruf explizit mitgeben. Lassen Sie sich nun die Targets auf dem Server anzeigen. Dafür benötigen Sie zunächst einmal die Scope-ID. Für den automatisch generierten Scope "Generated project scope" ist diese bereits festgelegt. Führen Sie also die folgenden Kommandos aus, um die Targets in diesem Scope aufzulisten und entsprechend der angezeigten Target ID weitere Informationen zu Ihrem Target darzustellen:
boundary targets list -scope-id p_1234567890
boundary targets read -id ttcp_KkWPWcjts2
Um sich zu Ihrem SSH-Server zu verbinden, haben Sie jetzt zwei Optionen. Sie können mit dem folgenden Kommando direkt eine Verbindung zum SSH-Server aufbauen, da SSH ein von Boundary unterstütztes Protokoll ist:
boundary connect ssh -target-id ttcp_KkWPWcjts2
Sie müssen noch den Host-Key des Servers akzeptieren und können sich anschließend einloggen.
Die zweite Option ohne Angabe von SSH öffnet auf Ihrem Client einen Proxy-Dienst und erlaubt Ihnen die Verbindung zu diesem Proxy:
boundary connect -target-id ttcp_KkWPWcjts2
Diese Möglichkeit benötigen Sie also für Verbindungen über Protokolle, die Boundary derzeit nicht unterstützt. Den Unterschied können Sie in Bild 3 erkennen, insbesondere die Anzeige des Ports und das Ablaufdatum des Proxys können Sie hier ablesen. Sobald die Verbindung aufgebaut ist, schauen Sie noch einmal in das Webinterface zur Administration. Klicken Sie sich bis zum "Project Scope" durch und lassen sich dann unter "Ses-sions" die aktive Sitzung anzeigen.
Erweiterte Optionen
Beim Anlegen des Targets haben Sie vermutlich schon die Möglichkeit gesehen, "Credential Sources" anzulegen. Damit gemeint ist der Hashicorp-Vault-Server, den Sie in Boundary einbinden können. Einmal konfiguriert, müssen Sie bei der direkten SSH-Nutzung mit Boundary keine Logindaten mehr angeben. Boundary organisiert den Zugang transparent mit dem angegebenen Vault-Server und stellt die Verbindung ohne weitere Abfragen her.
Für das Deployment von Boundary mit Terraform können Sie alle Einstellungen, die Sie gerade per Hand durchgeführt haben, bequem in einer Terraform-Beschreibung darstellen. So können Sie komplexe Konfigurationen erstellen und auch einfach aus dem Dev-Mode in den produktiven Betrieb wechseln.
Fazit
Hashicorp Boundary liefert eine solide Lösung für die Einbindung von und den Zugriff auf Ressourcen in internen Netzen einer Cluster- oder Cloudinfrastruktur. Obwohl die Versionsnummer die "1" noch nicht erreicht hat, läuft Boundary stabil, auch auf unterschiedlichen Betriebssystemen. Als Gateway in das interne Netz übernimmt Boundary die Authentifikation der Benutzer und die Prüfung des rollenbasierten Zugriffsmodells auf die verfügbaren Ressourcen. Die Integration von Vault erlaubt für unterstützte Protokolle einen direkten Login, ohne dass Benutzer das Passwort erhalten müssen.