it-swarm.com.de

Was sind die Vorteile, wenn geheime Werte einer Website als Umgebungsvariablen verwendet werden?

Die Devops-Richtlinien unter https://12factor.net/config schlagen vor, Website-Geheimnisse (Datenbankkennwörter, API-Schlüssel usw.) in Umgebungsvariablen einzufügen. Welche Vorteile hat dies, anstatt Textdateien (JSON, XML, YAML, INI oder ähnliches) zu verwenden, die von der Versionskontrolle ignoriert werden?

Ich finde es viel einfacher, eine Konfigurationsdatei mit Geheimnissen zu kopieren, als Umgebungsvariablen in der Konfiguration .bash_profile und im Webserver zu behandeln. Vermisse ich etwas

24

Der Autor listet ihre Argumentation auf, obwohl es ein bisschen unzusammenhängend ist. Ihr Hauptargument ist, dass es leicht ist, versehentlich eine Konfigurationsdatei einzuchecken, und dass Konfigurationsdateien unterschiedliche Formate haben und über das System verteilt sein können (alle drei sind bestenfalls mittelmäßige Argumente für sicherheitsrelevante Konfigurationen wie Authentifizierungstoken und Anmeldeinformationen).

Nach meiner eigenen Erfahrung haben Sie im Wesentlichen die folgenden drei Optionen mit den damit verbundenen Vor- und Nachteilen:

Speichern Sie die Daten in Konfigurationsdateien.

Wenn Sie diesen Ansatz wählen, sollten Sie sie idealerweise vom Repository selbst isolieren und sicherstellen, dass sie sich außerhalb des Bereichs befinden, in dem die App ihren Inhalt speichert.

Vorteile:

  • Sehr einfach zu isolieren und den Zugriff zu kontrollieren, insbesondere wenn Sie Dinge wie SELinux oder AppArmor verwenden, um die Gesamtsystemsicherheit zu verbessern.
  • Im Allgemeinen leicht zu ändern für nicht technische Benutzer (dies ist ein Vorteil für veröffentlichte Software, aber nicht unbedingt für Software, die für Ihr Unternehmen spezifisch ist).
  • Einfache Verwaltung über große Servergruppen hinweg. Es gibt alle Arten von Tools für die Konfigurationsbereitstellung.
  • Ziemlich einfach zu überprüfen, welche Konfiguration genau verwendet wird.
  • Bei einer gut geschriebenen App können Sie die Konfiguration normalerweise ändern, ohne den Dienst zu unterbrechen, indem Sie die Konfigurationsdatei aktualisieren und dann ein bestimmtes Signal an die App senden (normalerweise SIGHUP).

Nachteile:

  • Eine ordnungsgemäße Planung ist erforderlich, um die Daten sicher zu halten.
  • Möglicherweise müssen Sie unterschiedliche Formate lernen (obwohl es heutzutage nur eine Handvoll gibt, über die Sie sich Sorgen machen müssen, und sie haben im Allgemeinen eine ähnliche Syntax).
  • Genaue Speicherorte sind möglicherweise in der App fest codiert, was die Bereitstellung möglicherweise problematisch macht.
  • Das Parsen der Konfigurationsdateien kann problematisch sein.

Speichern Sie die Daten in Umgebungsvariablen.

Normalerweise erfolgt dies durch Beschaffen einer Liste von Umgebungsvariablen und -werten aus dem Startskript. In einigen Fällen werden diese jedoch möglicherweise nur in der Befehlszeile vor dem Programmnamen angegeben.

Vorteile:

  • Im Vergleich zum Parsen einer Konfigurationsdatei ist das Abrufen eines Werts aus einer Umgebungsvariablen in nahezu jeder Programmiersprache trivial.
  • Sie müssen sich nicht so viele Sorgen machen, wenn Sie die Konfiguration versehentlich veröffentlichen.
  • Sie erhalten ein gewisses Maß an Sicherheit durch Unbekanntheit, da diese Vorgehensweise ungewöhnlich ist und die meisten Leute, die Ihre App hacken, nicht sofort daran denken werden, Umgebungsvariablen zu untersuchen.
  • Der Zugriff kann von der Anwendung selbst gesteuert werden (wenn untergeordnete Prozesse erzeugt werden, kann die Umgebung problemlos gesäubert werden, um vertrauliche Informationen zu entfernen).

Nachteile

  • Auf den meisten UNIX-Systemen ist der Zugriff auf die Umgebungsvariablen eines Prozesses relativ einfach. Einige Systeme bieten Möglichkeiten, dies zu mildern (die Mount-Option hidepid für /proc unter LInux zum Beispiel), aber sie sind nicht standardmäßig aktiviert und schützen nicht vor Angriffen des Benutzers, dem der Prozess gehört.
  • Es ist nicht trivial, die genauen Einstellungen zu sehen, die von etwas verwendet werden, wenn Sie das oben genannte Sicherheitsproblem korrekt behandeln.
  • Sie müssen darauf vertrauen, dass die App die Umgebung bereinigt, wenn untergeordnete Prozesse erzeugt werden. Andernfalls werden Informationen verloren gehen.
  • Sie können die Konfiguration nicht einfach ändern, ohne die App vollständig neu zu starten.

Verwenden Sie Befehlszeilenargumente, um die Daten zu übergeben.

Im Ernst, vermeiden Sie dies um jeden Preis, es ist nicht sicher und es ist ein Schmerz im Arsch zu pflegen.

Vorteile:

  • In den meisten Sprachen ist es sogar einfacher zu analysieren als Umgebungsvariablen.
  • Untergeordnete Prozesse erben die Daten nicht automatisch.
  • Bietet eine einfache Möglichkeit, bestimmte Konfigurationen bei der Entwicklung der Anwendung schnell zu testen.

Nachteile:

  • Genau wie Umgebungsvariablen ist es auf den meisten Systemen einfach, die Befehlszeile eines anderen Prozesses zu lesen.
  • Das Aktualisieren der Konfiguration ist äußerst mühsam.
  • Legt fest, wie lange die Konfiguration dauern kann (manchmal nur 1024 Zeichen).
21

Umgebungsvariablen werden von jedem untergeordneten Prozess des Webservers geerbt. Das ist jede Sitzung, die eine Verbindung zum Server herstellt, und jedes Programm, das von ihnen erzeugt wird. Die Geheimnisse werden automatisch allen diesen Prozessen enthüllt.

Wenn Sie Geheimnisse in Textdateien aufbewahren, müssen diese vom Serverprozess und möglicherweise auch von jedem untergeordneten Prozess gelesen werden können. Aber zumindest müssen die Programme sie suchen; Sie werden nicht automatisch bereitgestellt. Möglicherweise können Sie auch einige untergeordnete Prozesse unter verschiedenen Konten ausführen und die Geheimnisse nur für diese Konten lesbar machen. Zum Beispiel macht suEXEC dies in Apache.

13
Andrew Schulman

Selbst wenn es um sicherheitsrelevante Kompromisse bei Umgebungsvariablen oder -dateien geht, glaube ich nicht, dass Sicherheit die Hauptantriebskraft für diese Empfehlung war. Denken Sie daran, dass die Autoren von 12factor.net auch Entwickler des Heroku PaaS sind (oder waren?). Die Verwendung von Umgebungsvariablen durch alle hat die Entwicklung wahrscheinlich erheblich vereinfacht. Es gibt so viel Abwechslung in verschiedenen Konfigurationsdateiformaten und Speicherorten, und es wäre für sie schwierig gewesen, sie alle zu unterstützen. Umgebungsvariablen sind im Vergleich einfach.

Es braucht nicht viel Fantasie, um einige der Gespräche zu erraten, die geführt wurden.

Entwickler A: "Ah, diese geheime Benutzeroberfläche der Konfigurationsdatei ist zu überladen! Brauchen wir wirklich ein Dropdown-Menü, das zwischen json, xml und csv wechselt?"

Entwickler B: "Oh, das Leben wäre so großartig, wenn nur jeder Umgebungsvariablen für die App-Konfiguration verwenden würde."

Entwickler A: "Tatsächlich gibt es einige plausible sicherheitsrelevante Gründe dafür. Umgebungsvariablen werden wahrscheinlich nicht versehentlich in die Quellcodeverwaltung eingecheckt."

Entwickler B: "Legen Sie die Umgebungsvariablen nicht mit einem Skript fest, mit dem der Dämon gestartet wird, oder mit einer Konfigurationsdatei?"

Entwickler A: "Nicht in Heroku! Wir werden sie dazu bringen, sie in die Benutzeroberfläche einzugeben."

Entwickler B: "Oh, meine Domainnamen-Warnung für 12factor.net ist gerade ausgefallen."1


1: source: erfunden.

2
Segfault

TL; DR

Es gibt eine Reihe von Gründen für die Verwendung von Umgebungsvariablen anstelle von Konfigurationsdateien, aber zwei der am häufigsten zu übersehenden Gründe sind der Nutzwert von Out-of-Band-Konfiguration und erweitert Trennung zwischen Servern, Anwendungen oder Organisationsrollen. Anstatt eine vollständige Liste aller möglichen Gründe vorzulegen, gehe ich in meiner Antwort nur auf diese beiden Themen ein und gehe leichtfertig auf deren Auswirkungen auf die Sicherheit ein.

Out-of-Band-Konfiguration: Trennen von Geheimnissen vom Quellcode

Wenn Sie alle Ihre Geheimnisse in einer Konfigurationsdatei speichern, müssen Sie diese Geheimnisse auf jeden Server verteilen. Dies bedeutet entweder, dass die Geheimnisse neben Ihrem Code in die Revisionskontrolle eingecheckt werden oder dass ein völlig separates Repository oder ein Verteilungsmechanismus für die Geheimnisse vorhanden ist.

Das Verschlüsseln Ihrer Geheimnisse hilft nicht wirklich, dieses Problem zu lösen. Alles, was Sie tun müssen, ist, das Problem auf einmal zu entfernen, denn jetzt müssen Sie sich auch um die Schlüsselverwaltung und -verteilung kümmern!

Kurz gesagt, Umgebungsvariablen sind ein Ansatz zum Verschieben von Daten pro Server oder Anwendung aus dem Quellcode, wenn Sie die Entwicklung von den Vorgängen trennen möchten. Dies ist besonders wichtig, wenn Sie Quellcode veröffentlicht haben!

Verbessern Sie die Trennung: Server, Anwendungen und Rollen

Während Sie sicherlich eine Konfigurationsdatei haben könnten, um Ihre Geheimnisse zu speichern, haben Sie ein Spezifitätsproblem, wenn Sie die Geheimnisse im Quellcode speichern. Haben Sie einen separaten Zweig oder ein Repository für jeden Satz von Geheimnissen? Wie stellen Sie sicher, dass die richtigen Geheimnisse auf die richtigen Server gelangen? Oder reduzieren Sie die Sicherheit, indem Sie "Geheimnisse" haben, die überall gleich sind (oder überall lesbar sind, wenn Sie alle in einer Datei haben) und daher ein größeres Risiko darstellen, wenn die Sicherheitskontrollen eines Systems fehlschlagen?

Wenn Sie eindeutige Geheimnisse auf jedem Server oder für jede Anwendung haben möchten, beseitigen Umgebungsvariablen das Problem, dass eine Vielzahl von Dateien verwaltet werden muss. Wenn Sie einen neuen Server, eine neue Anwendung oder eine neue Rolle hinzufügen, müssen Sie keine neuen oder alten Dateien erstellen. Sie aktualisieren lediglich die Umgebung des betreffenden Systems.

Abschiedsgedanken zur Sicherheit

Eine gründliche Untersuchung der Kernel-/Speicher-/Dateisicherheit ist für diese Antwort nicht möglich. Es ist jedoch darauf hinzuweisen, dass ordnungsgemäß implementierte Umgebungsvariablen pro System nicht weniger sicher sind als "verschlüsselte" Geheimnisse. In beiden Fällen muss das Zielsystem das entschlüsselte Geheimnis noch bei some im Speicher halten, um es verwenden zu können.

Es ist auch erwähnenswert, dass, wenn Werte in einem flüchtigen Speicher auf einem bestimmten Knoten gespeichert sind, keine On-Disk-Datei vorhanden ist, die offline kopiert und angegriffen werden kann. Dies wird im Allgemeinen als Vorteil für In-Memory-Geheimnisse angesehen, ist aber sicherlich nicht schlüssig.

Bei der Frage der Umgebungsvariablen im Vergleich zu anderen Techniken zur Verwaltung von Geheimnissen geht es mehr um Sicherheit und Benutzerfreundlichkeit Kompromisse als um Absolutes. Ihr Kilometerstand kann variieren.

1
CodeGnome

Persönlich würde ich nicht empfehlen, Umgebungsvariablen in .bashrc da diese für alle Prozesse sichtbar werden, die von der Shell gestartet wurden, aber um sie auf Daemon-/Supervisor-Ebene festzulegen (init/rc-Skript, systemd config) so dass ihr Umfang auf den Bedarf beschränkt ist.

Wenn separate Teams Vorgänge verwalten, bieten Umgebungsvariablen eine einfache Schnittstelle für Vorgänge, um die Umgebung für die Anwendung festzulegen, ohne über die Konfigurationsdateien/-formate Bescheid wissen zu müssen und/oder um deren Inhalt zu beschädigen. Dies gilt insbesondere für Einstellungen in mehreren Sprachen/Frameworks, in denen die Betriebsteams das Bereitstellungssystem (Betriebssystem, Supervisor-Prozesse) basierend auf den betrieblichen Anforderungen (einfache Bereitstellung, Skalierbarkeit, Sicherheit usw.) auswählen können.

Eine weitere Überlegung sind CI/CD-Pipelines - da Code verschiedene Umgebungen durchläuft (dh dev, test/qa, Staging, Produktion), werden die Umgebungsdetails (Bereitstellungszonen) angegeben Angaben zur Datenbankverbindung, Anmeldeinformationen, IP-Adressen, Domänennamen usw. usw. werden am besten von dedizierten Konfigurationsmanagement-Tools/Frameworks festgelegt und von den Anwendungsprozessen aus der Umgebung verwendet (DRY, einmal schreiben, überall ausführen). Wenn Entwickler diese betrieblichen Probleme meist verwalten, checken sie normalerweise neben Code auch Konfigurationsdateien oder -vorlagen ein - und fügen dann Problemumgehungen und andere Komplexität hinzu, wenn sich betriebliche Anforderungen ändern (z. B. neue Umgebungen/Bereitstellung/Standorte, Skalierbarkeit/Sicherheit) Wiegen Sie sich ein, mehrere Feature-Zweige - und plötzlich gibt es handgerollte Bereitstellungsskripte zum Verwalten/Verwalten der vielen Konfigurationsprofile) - diese Komplexität ist eine Ablenkung und ein Overhead, der am besten außerhalb des Codes von dedizierten Tools verwaltet wird.

  • Env-vars vereinfachen die Konfiguration/Komplexität im Maßstab.
  • Env-vars ordnet die Betriebskonfiguration direkt dem Team zu, das für die nicht codebezogenen Aspekte der Anwendung verantwortlich ist, und zwar in einer einheitlichen (wenn nicht standardmäßigen) unverbindlichen Form Weg.
  • Env-vars unterstützt das Austauschen der Master-/Supervisor-Prozesse (z. B. God, Monit, Supervisord, Sysvinit, Systemd usw.), die die Anwendung unterstützen - und sicherlich sogar das Bereitstellungssystem (Betriebssysteme, Container-Images usw.) usw. als betriebliche Anforderungen entwickeln/verändern. Während heutzutage jedes Sprachframework eine Art Prozesslaufzeit hat, sind diese in der Regel betrieblich minderwertig, eher für Entwicklungsumgebungen geeignet und/oder erhöhen die Komplexität in Produktionsumgebungen mit mehreren Sprachen und mehreren Frameworks.

Für die Produktion bevorzuge ich das Setzen der Anwendung env-vars in einer EnvironmentFile wie/etc/default/myapplication.conf, das vom Konfigurationsmanagement bereitgestellt und nur von root lesbar gesetzt wird, sodass systemd (oder irgendetwas anderes) die Anwendung unter einem dedizierten Deprivilegierten Systembenutzer erzeugen kann in einer Private Gruppe . Unterstützt mit dedizierten Benutzergruppen für ops und Sudo - diese Dateien sind standardmäßig weltweit nicht lesbar. Dies ist 12-Faktor-konform und unterstützt alle Vorteile von Dev + Ops plus. Es bietet alle Vorteile einer angemessenen Sicherheit und ermöglicht Entwicklern/Testern, ihre eigenen EnvironmentFiles in den dev/qa/test-Umgebungen abzulegen.

1
shalomb

Aus Entwicklersicht vereinfacht das Speichern von Konfigurationsdaten in Umgebungsvariablen die Bereitstellung in verschiedenen Umgebungen - Entwicklung, Qualitätssicherung und Produktion - und befreit Entwickler von der Sorge, die falsche Konfigurationsdatei bereitzustellen.

Azure-Webanwendungen bieten die Möglichkeit, dieses Muster zu verwenden, und es funktioniert sehr gut.

Darüber hinaus werden potenziell sensible Daten von der Quellcodeverwaltung ferngehalten. Das Ignorieren dieser Dateien aus der Quellcodeverwaltung ist nicht wirklich möglich (zumindest in .NET), da in diesen Dateien auch viele erforderliche Boilerplate-Konfigurationen vorhanden sind.

0
Derek Gusoff