Im ersten Beitrag dieser Reihe beschreiben wir verschiedene Ansätze, um die Sicherheit Ihrer privaten SSL-Schlüssel zu erhöhen. Der Beitrag endete mit der Demonstration eines entfernten Passwortverteilungspunkts (Password Distribution Point, PDP), über den Verschlüsselungspasswörter sicher mit NGINX-Instanzen geteilt werden können.
Systeme zur Verwaltung von Geheimnissen wie HashiCorp Vault funktionieren ähnlich wie dieses beispielhafte PDP:
- Sie verwenden einen zentralen (oder hochverfügbaren und verteilten) Dienst zur Verwaltung von Geheimnissen, auf den über HTTPS oder eine andere API zugegriffen wird.
- Clients werden mithilfe von Authentifizierungstoken oder anderen Verfahren authentifiziert
- Token können bei Bedarf widerrufen werden, um den Zugriff auf das Geheimnis zu kontrollieren
In diesem Beitrag zeigen wir, wie Sie HashiCorp Vault für die Verteilung von SSL-Passwörtern einrichten. Für noch mehr Sicherheit können Sie ein externes Hardware-Sicherheitsmodul einrichten (HSM).
Wie Sie die Speicherung von SSL-Zertifikat-Schlüssel-Paaren auf der Festplatte vollständig vermeiden, erfahren Sie im dritten Beitrag dieser Reihe: „Ephemere SSL-Schlüssel aus HashiCorp Vault mit dem Schlüssel-Wert-Speicher von NGINX Plus schützen“. Darin wird erläutert, wie Sie ephemere SSL-Schlüssel aus HashiCorp Vault generieren und im Arbeitsspeicher im Schlüssel-Wert-Speicher von NGINX Plus ablegen.
Dieser Beitrag gilt sowohl für NGINX Open Source als auch für NGINX Plus. Der besseren Lesbarkeit halber verwenden wir im Folgenden die Bezeichnung „NGINX“.
HashiCorp Vault zum Schutz privater SSL-Schlüssel verwenden
Mit den Anweisungen in diesem Abschnitt wird ein zentraler PDP-Server eingerichtet, der Vault zur Verteilung von SSL-Passwörtern verwendet. Sie basieren auf der Anleitung von DigitalOcean; passen Sie sie bei Bedarf an Ihre eigenen Vault-Richtlinien an.
In unserem Beispiel verfügt jeder Remote-Webserver über ein eindeutiges Authentifizierungstoken. Mit diesen Token kann auf Geheimnisse im Vault-Pfad secret/webservers/ zugegriffen werden. Die SSL-Passwörter speichern wir unter secret/webservers/ssl_passwords.
Wir werden sehen, wie sich die Token schützen und einzelne Authentifizierungs-Token bei Bedarf widerrufen lassen.
HashiCorp Vault auf dem PDP-Server herunterladen, installieren und initialisieren
- Befolgen Sie die Anweisungen von DigitalOcean, um Vault auf Ihren PDP-Server herunterzuladen und dort zu entpacken. Wir verwenden die folgende Beispieldatei /etc/vault.hcl, um den Remotezugriff auf Vault zu ermöglichen und TLS zu deaktivieren (zur einfacheren Verwendung bei Tests):
backend "file" { path = "/var/lib/vault"
}
listener "tcp" {
address = "0.0.0.0:8200"
tls_disable = 1
}- Starten Sie Vault mithilfe der Startskripte (sofern Sie diese erstellt haben) oder manuell:
user@pdp:~$ sudo /usr/local/bin/vault server -config=/etc/vault.hcl- Initialisieren Sie Vault und rufen Sie das initiale Root-Token ab:
user@pdp:~$ export VAULT_ADDR=http://localhost:8200
user@pdp:~$ vault init -key-shares=3 -key-threshold=2
user@pdp:~$ vault operator unseal
Initial Root Token: 86c5c2a4-8ab2-24dd-1816-48449c83114e- In vielen der folgenden Befehle müssen wir das anfängliche Root-Token angeben. Der Einfachheit halber weisen wir es der Shell-Variablen
root_tokenzu:
user@pdp:~$ root_token=86c5c2a4-8ab2-24dd-1816-48449c83114eGeheimnisse speichern
- Erstellen Sie weiterhin auf dem PDP-Server eine temporäre Datei namens /tmp/ssl_passwords.txt und speichern Sie darin die Passwörter.
- Speichern Sie diese Datei als Secret in Vault und überprüfen Sie, ob Sie sie abrufen können:
user@pdp:~$ VAULT_TOKEN=$root_token vault kv put secret/webservers/ssl_passwords value=@/tmp/ssl_passwords.txt
user@pdp:~$ VAULT_TOKEN=$root_token vault kv get -field=value secret/webservers/ssl_passwords
password1
password2
...- Löschen Sie aus Sicherheitsgründen „/tmp/ssl_passwords.txt“.
- Erstellen Sie eine Richtlinienspezifikation in einer Datei namens web.hcl mit folgendem Inhalt:
path "secret/webservers/*" {
capabilities = ["read"]
}- Laden Sie die Richtlinie in Vault und nennen Sie sie „
web“:
user@pdp:~$ VAULT_TOKEN=$root_token vault policy write web web.hcl- Erstellen Sie ein neues Authentifizierungstoken und verknüpfen Sie es mit der Richtlinie
web. Optional können Sie den Parameterdisplay-nameangeben, um dem Token einen benutzerfreundlichen Namen zu geben. Notieren Sie sich die Werte fürtokenundtoken_accessor; Sie benötigen sie für die nachfolgenden Befehle:
user@pdp:~$ VAULT_TOKEN=$root_token vault token create -policy=web -display-name=webserver1
Key Value
--- -----
token dcf75ffd-a245-860f-6960-dc9e834d3385
token_accessor 0c1d6181-7adf-7b42-27be-b70cfa264048- Der NGINX-Webserver verwendet dieses Token, um die SSL-Passwörter abzurufen. Die Richtlinie „
web“ verhindert, dass der Webserver Geheimnisse außerhalb des Pfads „secret/webservers/*“ abruft.
Überprüfen, ob der Webserver das Token abrufen kann
- Installieren Sie auf dem NGINX-Webserver die Vault-Binärdatei.
- Geben Sie den Speicherort des entfernten Vault-Servers an (hier: http://pdp:8200) und überprüfen Sie anschließend, ob der Webserver die SSL-Passwörter mithilfe des Tokens abrufen kann:
user@web1:~$ export VAULT_ADDR=http://pdp:8200user@web1:~$ VAULT_TOKEN=dcf75ffd-a245-860f-6960-dc9e834d3385 vault kv get -field=value secret/webservers/ssl_passwords
password1
password2
...NGINX Vault Connector auf dem Webserver konfigurieren
- Im Rahmen der Einrichtung des Beispiel-PDP im ersten Beitrag haben wir auf dem NGINX-Host (Webserver) ein Shell-Skript namens connector.sh erstellt. Hier passen wir es für die Verwendung von Vault an:
#!/bin/sh
# Usage: connector_v.sh
CONNECTOR=$1
CREDS=$2
[ -e $CONNECTOR ] && /bin/rm -f $CONNECTOR
mkfifo $CONNECTOR; chmod 600 $CONNECTOR
export VAULT_ADDR=http://pdp:8200
export VAULT_TOKEN=$CREDS
while true; do
vault kv get -field=value secret/webservers/ssl_passwords > $CONNECTOR
sleep 0.1 # race condition, ensures EOF
done- Führen Sie das Skript wie folgt als Hintergrundprozess aus:
root@web1:~# ./connector_v.sh /var/run/nginx/ssl_passwords \dcf75ffd-a245-860f-6960-dc9e834d3385 &- Testen Sie den Konnektor, indem Sie aus dem Konnektorpfad lesen:
root@web1:~$ cat /var/run/nginx/ssl_passwordspassword1
password2
...- Konfigurieren Sie NGINX so, dass beim Start die Datei ssl_passwords gelesen und deren Inhalt als Passwörter zum Entschlüsseln verschlüsselter privater Schlüssel verwendet wird. Sie können die Direktive
ssl_password_fileentweder in einenserver-Block (wie den für die Standardkonfiguration im ersten Beitrag erstellten) oder in denhttp-Kontext einfügen, um sie auf mehrere virtuelle Server anzuwenden:
ssl_password_file /var/run/nginx/ssl_passwords;- Überprüfen Sie, ob NGINX das Passwort lesen und die SSL-Schlüssel entschlüsseln kann:
root@web1:~# nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successfulAuthentifizierungstoken eines Webservers widerrufen
Sie können den Zugriff problemlos widerrufen, wenn der Webserver kompromittiert oder außer Betrieb genommen wird. Dazu können Sie das vom Webserver verwendete Authentifizierungstoken direkt widerrufen:
user@pdp:~$ VAULT_TOKEN=$root_token vault token revoke dcf75ffd-a245-860f-6960-dc9e834d3385Vault-Token sind sensible Daten, und bei vielen Vault-Workflows werden keine Kopien der Token gespeichert, die an einen authentifizierten Client ausgegeben werden. Wenn die Kopie eines Tokens in falsche Hände gerät, kann sich ein Angreifer als der Client ausgeben.
Stattdessen wird ein aktives Token üblicherweise über seinen Accessor verwaltet. Dieser gewährt eingeschränkte Rechte für das Token und kann nicht zum Abrufen des Token-Werts verwendet werden. Speichern Sie daher bei der Ausgabe eines Tokens nicht das Token selbst, sondern den zugehörigen Accessor.
Wenn Sie den Accessor für das Authentifizierungstoken eines Webservers ermitteln müssen, führen Sie den Befehl „vault list“ aus, um die Liste der Accessors abzurufen. Führen Sie anschließend für jeden Accessor den Befehl „vault token lookup“ aus, um den Accessor mit dem entsprechenden Anzeigenamen und der entsprechenden Richtlinie zu finden:
user@pdp:~$ VAULT_TOKEN=$root_token vault list /auth/token/accessors
Keys
----
83be5a73-9025-1221-cb70-4b0e8a3ba8df
0c1d6181-7adf-7b42-27be-b70cfa264048
f043b145-7a63-01db-ea85-9f22f413c55e
user@pdp:~$ VAULT_TOKEN=$root_token vault token lookup -accessor 0c1d6181-7adf-7b42-27be-b70cfa264048
Key Value
--- -----
...
display-name webserver1
...
policy web
...Anschließend können Sie das Token mithilfe seines Accessors widerrufen:
user@pdp:~$ VAULT_TOKEN=$root_token vault token revoke -accessor 0c1d6181-7adf-7b42-27be-b70cfa264048Sicherheitsauswirkungen
Die Verwendung von Vault weist ein ähnliches Sicherheitsprofil auf wie der im ersten Beitrag beschriebene Beispiel-PDP. Private SSL-Schlüssel können nur abgerufen werden, wenn das zugehörige Passwort bekannt ist. Dazu muss ein Angreifer den Wert eines aktuellen Authentifizierungstokens kennen.
Der Hauptvorteil der Verwendung von Vault besteht darin, die Verwaltung des Secret Stores zu automatisieren und zu skalieren.
Verwendung eines externen HSM zur Verwaltung privater Schlüssel
Keine der Lösungen, die wir bisher in dieser Reihe behandelt haben, schützt den privaten Schlüssel, wenn ein Angreifer root-Zugriff auf den NGINX-Server erlangt. Wenn ein Angreifer auf den Laufzeitspeicher von NGINX zugreifen oder einen Core-Dump erstellen kann, gibt es bekannte Verfahren, um den Prozessspeicher zu durchsuchen und die Daten des privaten Schlüssels ausfindig zu machen.
Externe Hardware-Sicherheitsmodule (HSMs) lösen dieses Problem, indem sie die privaten SSL-Schlüssel in externer, manipulationssicherer Hardware speichern. Sie bieten die Entschlüsselung als Dienst an, auf den NGINX immer dann zugreift, wenn eine SSL-Operation ausgeführt werden muss, für die der Schlüssel erforderlich ist.
Der NGINX-Server erhält zu keinem Zeitpunkt Einblick in die Daten des privaten SSL-Schlüssels. Ein Angreifer, der root-Zugriff auf den Server erlangt, kann den privaten SSL-Schlüssel nicht auslesen, aber bei Bedarf Daten entschlüsseln, indem er mit den NGINX-Anmeldedaten auf den HSM-Entschlüsselungsdienst zugreift.
NGINX für den Zugriff auf ein HSM konfigurieren
NGINX delegiert alle Operationen mit privaten SSL-Schlüsseln an eine Kryptobibliothek namens OpenSSL. HSM-Geräte von Drittanbietern können NGINX über die OpenSSL-Engine des jeweiligen HSM-Anbieters zur Verfügung gestellt werden.
Die NGINX-Konfiguration ist für das HSM jedes Anbieters spezifisch, folgt jedoch im Allgemeinen einem einfachen Schema:
- Konfigurieren Sie NGINX so, dass die OpenSSL-Engine des Anbieters anstelle der standardmäßigen Software-Engine verwendet wird:
ssl_certificate_key engine:vendor-hsm-engine:...;- Konfigurieren Sie NGINX so, dass anstelle des echten privaten Schlüssels der vom Anbieter bereitgestellte „Fake“-Schlüssel verwendet wird. Dieser Schlüssel enthält ein Handle, das den echten Schlüssel auf dem HSM-Gerät identifiziert:
ssl_certificate_key ssl/vendor.private.key;- Der Schlüssel kann auch die Anmeldedaten für den Zugriff auf das HSM-Gerät enthalten. Alternativ können die Anmeldedaten über eine zusätzliche herstellerspezifische Konfiguration bereitgestellt werden.
- (Optional) Nehmen Sie die gewünschten Optimierungen vor, z. B. indem Sie die Anzahl der NGINX-Worker-Prozesse erhöhen, um die Leistung von NGINX und dem HSM zu maximieren.
Ein Beispiel für die Einrichtung eines HSM finden Sie in der CloudHSM-Dokumentation von Amazon.
Sicherheitsrelevante Auswirkungen
Externe HSMs sind eine äußerst sichere Methode zur Speicherung privater SSL-Schlüssel. Ein Angreifer mit root-Zugriff auf den NGINX-Server kann die NGINX-Anmeldedaten nutzen, um mithilfe des HSM beliebige Daten zu entschlüsseln, ist jedoch nicht in der Lage, den unverschlüsselten privaten Schlüssel zu erlangen. Ein HSM erschwert es einem Angreifer erheblich, sich als eine Website auszugeben oder beliebige Daten offline zu entschlüsseln.
Fazit
Es muss unbedingt sichergestellt werden, dass vertrauliche Daten wie der private SSL-Schlüssel umfassend geschützt sind, da eine Offenlegung schwerwiegende Folgen hätte.
Für viele Organisationen mit geeigneten Sicherheitsprozessen reicht es aus, den privaten Schlüssel auf den Frontend-Load-Balancern zu speichern und anschließend sämtliche Zugriffe auf diese Server zu beschränken und zu protokollieren (die im ersten Beitrag beschriebene Standardkonfiguration).
Für Organisationen, die häufig NGINX-Konfigurationen bereitstellen müssen, können die in diesem Beitrag und im ersten Beitrag beschriebenen Maßnahmen dazu dienen, den Kreis der Benutzer oder Entitäten einzuschränken, die die Daten des privaten Schlüssels einsehen können.
Im dritten Beitrag dieser Reihe, „Using the NGINX Plus Key-Value Store to Secure Ephemeral SSL Keys from HashiCorp Vault“, erläutern wir, wie sich die Bereitstellung von Schlüsseln und Zertifikaten aus Vault für den Schlüssel-Wert-Speicher von NGINX Plus mithilfe der NGINX Plus API automatisieren lässt.
Beachten Sie auch hier, dass keine dieser Methoden die Notwendigkeit verringert, die laufenden NGINX-Instanzen umfassend vor Remotezugriffen oder Konfigurationsmanipulationen zu schützen.
Testen Sie NGINX Plus selbst – starten Sie noch heute Ihre kostenlose 30-Tage-Testversion oder kontaktieren Sie uns, um Ihre Anwendungsfälle zu besprechen.
Über den Autor

Ähnliche Blogbeiträge
Die Zukunft von NGINX: Zurück zu unseren Open-Source-Wurzeln
Beim NGINX Sprint 2022 besinnen wir uns auf unsere Open-Source-Wurzeln. Erfahren Sie mehr über die Initiativen, die wir im kommenden Jahr verfolgen, und teilen Sie uns mit, was Sie sich wünschen.

Ein Leitfaden zur Auswahl eines Ingress-Controllers, Teil 1: Ermitteln Sie Ihre Anforderungen
Ein Ingress-Controller kann eines der leistungsstärksten Tools in Ihrem Kubernetes-Stack sein. Erfahren Sie, wie Sie Ihre Ingress-Anforderungen ermitteln, um die beste Option auszuwählen.
Bereitstellung des NGINX Ingress Controllers auf Amazon EKS: So haben wir getestet
Wir haben kürzlich den Lösungsleitfaden zum NGINX Ingress Controller um Empfehlungen zur Dimensionierung für Amazon Elastic Kubernetes Service (EKS) ergänzt. In diesem Blogbeitrag erläutern wir, wie wir diese Empfehlungen erarbeitet haben, und stellen Ihnen alle Informationen zur Verfügung, die Sie benötigen, um selbst ähnliche Tests durchzuführen.

Protokollierung des Datenverkehrs zwischen NGINX und Upstream-Servern bei CDN77
Bei der Fehlersuche bei Datenverkehrsproblemen zwischen NGINX und Upstream-Servern konnte CDN77 die benötigten Daten nur aus dem Fehlerprotokoll mit aktivierter Debug-Ausgabe beziehen, was die Leistung beeinträchtigt und riesige Dateien erzeugt. Daher entwickelte das Team ein neues benutzerdefiniertes Modul, das ausschließlich die benötigten Daten protokolliert.
Ankündigung von NGINX Plus R16
NGINX Plus R16 ist eine einheitliche, elastische Ingress- und Egress-Schicht für Anwendungen, die die Funktionen eines Load Balancers, API-Gateways und einer WAF vereint und neue Features wie clusterfähige Ratenbegrenzung, Schlüssel-Wert-Speicher, „Random with Two Choices“, verbessertes UDP-Load-Balancing und vieles mehr bietet.
5 Gründe für den Umstieg auf softwarebasiertes Load Balancing
Entdecken Sie fünf Gründe für den Wechsel zu einem softwarebasierten Load Balancer wie NGINX Plus, darunter Kosteneinsparungen, die Einführung von DevOps und eine einheitliche Lösung für alle Umgebungen.