Frage Was sind die Vorteile, wenn man geheime Werte einer Website als Umgebungsvariablen angibt?


Die Devops Richtlinien bei https://12factor.net/config schlagen vor, Webseitengeheimnisse (Datenbankpasswörter, API-Schlüssel, etc.) in Umgebungsvariablen zu setzen. Welche Vorteile hat das anstelle der Verwendung von Textdateien (JSON, XML, YAML, INI oder ähnlich), die von der Versionskontrolle ignoriert werden?

Ich finde es viel einfacher, eine Konfigurationsdatei mit Secrets zu kopieren, als mit Umgebungsvariablen in der .bash_profile- und Webserver-Konfiguration umzugehen. Vermisse ich etwas?


20
2018-01-16 16:30


Ursprung


Theoretisch ist es einfacher, eine Datei als den Speicher zu lesen, sodass Sie die Angriffsfläche größer und komplexer betrachten können. - Florin Asăvoaie
Die Faustregel meines Entwicklers lautet, dass das Speichern von Einstellungen in Umgebungsvariablen am besten nur in dockerähnlichen Umgebungen erfolgt. Außerhalb von Container-VMs genehmigt / bevorzugt er alle anderen Punkte von 12factor.net und die Verwendung von Konfigurationsdateien. Niemand von uns mochte die Unsicherheit von Umgebungsvariablen bei regulären Serverbereitstellungen. - Corey Ogburn


Antworten:


Der Autor führt ihre Argumentation auf, obwohl sie ein wenig unzusammenhängend ist. Ihr Hauptargument ist, dass es leicht ist, versehentlich eine Konfigurationsdatei einzuchecken, und dass Konfigurationsdateien unterschiedliche Formate haben und über das System verstreut sein können (alle drei sind bestenfalls mittelmäßige Argumente für sicherheitsbezogene Konfigurationen wie Authentifizierungs-Token und Anmeldeinformationen).

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

Speichern Sie die Daten in den Konfigurationsdateien.

Bei dieser Vorgehensweise sollten Sie sie idealerweise vom Repository isolieren und sicherstellen, dass sie sich außerhalb des Bereichs befinden, in dem die App Inhalte speichert.

Vorteile:

  • Sehr einfach zu isolieren und zu kontrollieren, vor allem wenn Sie Dinge wie SELinux oder AppArmor verwenden, um die Gesamtsicherheit des Systems zu verbessern.
  • Im Allgemeinen einfach für nicht-technische Benutzer zu ändern (dies ist ein Vorteil für veröffentlichte Software, aber nicht unbedingt für spezifische Software für Ihre Organisation).
  • Einfache Verwaltung über große Gruppen von Servern. Es gibt alle Arten von Tools für die Konfiguration Bereitstellung da draußen.
  • Ziemlich einfach zu überprüfen, was die genaue Konfiguration ist.
  • Für eine gut geschriebene App können Sie normalerweise die Konfiguration ändern, ohne den Dienst zu unterbrechen, indem Sie die Konfigurationsdatei aktualisieren und dann ein bestimmtes Signal an die App senden (normalerweise SIGHUP).

Nachteile:

  • Um die Daten sicher zu halten, ist eine gute Planung erforderlich.
  • Möglicherweise müssen Sie unterschiedliche Formate lernen (obwohl es heutzutage nur eine Handvoll gibt, über die Sie sich Gedanken machen müssen, und sie haben im Allgemeinen eine ähnliche Syntax).
  • Genaue Speicherorte können in der App fest codiert sein, wodurch die Bereitstellung möglicherweise problematisch wird.
  • Das Parsen der Konfigurationsdateien kann problematisch sein.

Speichern Sie die Daten in Umgebungsvariablen.

Gewöhnlich geschieht dies, indem eine Liste von Umgebungsvariablen und -werten aus dem Startskript bezogen wird. In manchen Fällen werden sie jedoch nur in der Befehlszeile vor dem Programmnamen angegeben.

Vorteile:

  • Verglichen mit dem Parsen einer Konfigurationsdatei ist das Ziehen eines Wertes aus einer Umgebungsvariablen in so gut wie jeder Programmiersprache trivial.
  • Sie müssen sich nicht so viele Gedanken über das versehentliche Veröffentlichen der Konfiguration machen.
  • Sie erhalten ein gewisses Maß an Sicherheit durch Unklarheit, weil diese Praxis ungewöhnlich ist, und die meisten Leute, die Ihre App hacken, werden nicht sofort daran denken, Umgebungsvariablen zu betrachten.
  • Der Zugriff kann von der Anwendung selbst gesteuert werden (wenn sie untergeordnete Prozesse hervorbringt, kann sie die Umgebung leicht bereinigen, um vertrauliche Informationen zu entfernen).

Nachteile

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

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 in den Arsch zu pflegen.

Vorteile:

  • Noch einfacher zu parsen als Umgebungsvariablen in den meisten Sprachen.
  • Untergeordnete Prozesse erben die Daten nicht automatisch.
  • Bietet eine einfache Möglichkeit zum schnellen Testen bestimmter Konfigurationen beim Entwickeln der Anwendung.

Nachteile:

  • Genau wie Umgebungsvariablen ist es einfach, die Befehlszeile eines anderen Prozesses auf den meisten Systemen zu lesen.
  • Extrem mühselig, um die Konfiguration zu aktualisieren.
  • Legt fest, wie lange die Konfiguration dauern darf (manchmal so niedrig wie 1024 Zeichen).

20
2018-01-16 18:10



Ein nicht unwichtiger Punkt ist das unbeaufsichtigte (Wieder-) Booten eines Servers, ohne dass manuell Passwörter vergeben werden müssen, am Ende befinden sie sich irgendwo auf der Festplatte - PlasmaHH
Auf den meisten UNIX-Systemen können Sie praktisch alle Prozessumgebungsvariablen lesen, ohne dass Sie wesentliche Berechtigungen benötigen.  - Können Sie das weiter ausführen? Die Datei / proc / #### / environ ist nur für den Besitzer lesbar, also müssen Sie root sein oder sudo haben. - rrauenza
Ich denke, dass einige dieser "env config" -Trends auch von Dingen wie docker stammen, bei denen Sie einen Standardcontainer verwenden und ihn konfigurieren, indem Sie env-Variablen an den Container übergeben. - rrauenza
@rrauenza Der Besitz eines Prozesses ist kein bedeutendes Privileg, es sei denn, Sie erledigen die Dinge sehr gut nach Konto, und Sie benötigen tatsächlich nur die CAP_SYS_ADMIN-Fähigkeit (die root implizit hat), wenn Sie nicht der Eigentümer sind. Auch in Bezug auf die Variable der Umgebungsvariablen hast du wahrscheinlich recht, aber es ist sogar mit Docker ein marginales Design. - Austin Hemmelgarn
Ich stimme dem Punkt zu, den @rrauenza macht. Die Antwort ist überall ziemlich gut, aber ich würde gerne klarstellen, wie genau Sie können so ziemlich alle Prozessumgebungsvariablen lesen, ohne dass Sie wesentliche Privilegien benötigen. Bezüglich "und Sie brauchen eigentlich nur die Fähigkeit CAP_SYS_ADMIN (welche Wurzel hat implizit)... "Nun, wenn ein böswilliger Agent Root-Rechte hat, ist eine weitere Diskussion überflüssig, und CAP_SYS_ADMIN könnte auch Root-Berechtigung sein (siehe man7.org/linux/man-pages/man7/capabilities.7.html, CAP_SYS_ADMIN und Hinweise für Kernel-Entwickler) - Nubarke


Umgebungsvariablen werden von jedem untergeordneten Prozess des Webservers geerbt. Das ist jede Sitzung, die mit dem Server und jedem von ihnen erstellten Programm verbunden ist. Die Geheimnisse werden automatisch allen diesen Prozessen offenbart.

Wenn Sie Geheimnisse in Textdateien aufbewahren, müssen sie vom Serverprozess und möglicherweise auch von jedem untergeordneten Prozess lesbar sein. Aber zumindest müssen die Programme gehen und sie finden; 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, suEXEC Tut dies in Apache.


11
2018-01-16 16:44



"Das ist jede Sitzung, die mit dem Server verbindet" ist eine irreführende Aussage. Sie können keine HTTP-Sitzung für den Server öffnen und Zugriff auf seine Umgebungsvariablen erhalten. Sie können sich auch nicht in einer Shell auf diesem Server anmelden und sie abrufen, wenn Sie keinen Root-Zugriff haben oder den Web-Server-Prozess besitzen. - Segfault
Jeder Prozess, der vom Webserver erzeugt wird, erbt seine Umgebung, sofern Sie keine anderen aktiven Schritte ausführen. Eine HTML-Seite kann diese Informationen nicht verwenden, ein Skript jedoch. - Andrew Schulman
Diese Antwort könnte zwar mit einigen Korrekturen / Zugeständnissen, insbesondere in Bezug auf den Begriff, richtig sein Sitzungen. Beim ersten Lesen scheint es die Verwendung von Umgebungsvariablen in einem schlechten Licht zu malen, fast um Möglichkeiten der Informationsweitergabe an einen externen Kunden vorzuschlagen. Auch kann eine Konzession, die mit suexec vergleichbar ist, für eine beschränkte Einstellung von Umgebungen, z. pro-process env-vars setzen (a la MYVAR=foo /path/to/some/executable) begrenzt die Verbreitung auf einen Prozess und es sind nur Kinder - und wo erforderlich, können Master-Daemons die Umgebung von Kind-Prozessen bereinigen / zurücksetzen / modifizieren. - shalomb


Selbst wenn es einige sicherheitsrelevante Kompromisse bei Umgebungsvariablen oder -dateien gibt, glaube ich nicht, dass Sicherheit die Hauptantriebskraft für diese Empfehlung war. Denken Sie daran, dass die Autoren von 12factor.net auch Entwickler der Heroku PaaS sind (oder auch waren?). Jeder zu benutzen, um Umgebungsvariablen zu benutzen, vereinfachte wahrscheinlich ihre Entwicklung ziemlich ein bisschen. Es gibt so viele verschiedene Konfigurationsdateien und -orte, und es wäre schwierig gewesen, sie alle zu unterstützen. Umgebungsvariablen sind im Vergleich einfach.

Es braucht nicht viel Vorstellungskraft, um einige der Gespräche zu erraten.

Entwickler A: "Ah, diese geheime Konfigurationsdatei-Benutzeroberfläche ist zu voll!   wirklich müssen ein Dropdown haben, das zwischen json, xml und wechselt   CSV? "

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

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

Entwickler B: "Setzen Sie die Umgebungsvariablen nicht mit einem Skript   das startet den Daemon oder eine Konfigurationsdatei? "

Entwickler A: "Nicht in Heroku! Wir werden sie in die Benutzeroberfläche eintippen."

Entwickler B: "Oh, mein Domain-Name-Alert für 12factor.net ist einfach gegangen   aus."1


1: Quelle: erfunden.


1
2018-01-17 06:59





TL; DR

Es gibt eine Reihe von Gründen für die Verwendung von Umgebungsvariablen anstelle von Konfigurationsdateien. Zwei der am häufigsten zu übersehenden Elemente sind jedoch der Nutzen von Out-of-Band-Konfiguration und verbesserte Trennung zwischen Servern, Anwendungen oder Organisationsrollen. Anstatt eine erschöpfende Liste aller möglichen Gründe vorzulegen, adressiere ich nur diese zwei Themen in meiner Antwort und berühre leicht ihre Sicherheitsimplikationen.

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

Wenn Sie alle Ihre Geheimnisse in einer Konfigurationsdatei speichern, müssen Sie diese Geheimnisse an jeden Server verteilen. Das bedeutet entweder, dass Sie die Geheimnisse neben dem Code in die Versionskontrolle einchecken, oder dass Sie ein völlig separates Repository oder einen separaten Verteilungsmechanismus für die Geheimnisse haben.

Verschlüsseln Sie Ihre Geheimnisse nicht wirklich helfen, dies zu lösen. Das einzige Problem besteht darin, das Problem auf einen Streich zu bringen, da Sie sich jetzt auch um die Schlüsselverwaltung und -verteilung kümmern müssen!

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

Separation verbessern: Server, Anwendungen und Rollen

Während Sie sicher eine Konfigurationsdatei haben könnten, um Ihre Geheimnisse zu bewahren, haben Sie ein Spezifitätsproblem, wenn Sie die Geheimnisse im Quellcode speichern. Haben Sie einen separaten Zweig oder ein separates Repository für jede Gruppe von Geheimnissen? Wie stellen Sie sicher, dass die richtigen Geheimnisse an 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 auf jedem Server oder für jede Anwendung eindeutige Secrets haben möchten, entfällt bei Umgebungsvariablen das Problem, eine Vielzahl von Dateien verwalten zu müssen. Wenn Sie einen neuen Server, eine neue Anwendung oder eine neue Rolle hinzufügen, müssen Sie keine neuen Dateien erstellen oder alte aktualisieren: Sie aktualisieren lediglich die Umgebung des betreffenden Systems.

Abschiedsgedanken zur Sicherheit

Während eine gründliche Untersuchung der Kernel / Speicher / Datei-Sicherheit für diese Antwort nicht möglich ist, sollte darauf hingewiesen werden, dass ordnungsgemäß implementierte Umgebungsvariablen pro System nicht weniger sicher sind als "verschlüsselte" Geheimnisse. In jedem Fall muss das Zielsystem das entschlüsselte Geheimnis im Speicher behalten etwas zeigen Sie, um es zu benutzen.

Es sollte auch darauf hingewiesen werden, dass, wenn Werte im flüchtigen Speicher eines bestimmten Knotens gespeichert sind, keine Datei auf der Festplatte vorhanden ist, die offline kopiert und angegriffen werden kann. Dies wird allgemein als ein Vorteil für In-Memory-Geheimnisse angesehen, aber es ist sicherlich nicht schlüssig.

Das Problem der Umgebungsvariablen im Vergleich zu anderen Techniken zum Management von Geheimnissen ist mehr über Sicherheit und Benutzerfreundlichkeit Kompromisse als es um absolutes geht. Ihre Laufleistung kann variieren.


1
2018-01-17 16:43



Dies ist nicht überzeugend, da alle von Ihnen genannten Nachteile für Konfigurationsdateien auch für Umgebungsvariablen gelten. Umgebungsvariablen sind Konfigurationsdaten. Sie stellen sich nicht magisch auf. Sie müssen auf jedes System verteilt werden, und eine Art von Aufbau Mechanismus muss verwendet werden, um sie einzustellen. - jpaugh
@jpaugh Du machst einen Strohmann-Streit und greifst etwas an, was ich nie gesagt habe. Die Probleme, die ich adressiere, sind Out-of-Band-Konfiguration und Datentrennung. Wie klar erklärt, können Sie diese Dinge tun, wie Sie möchten. Wenn Sie möchten, können Sie Ihre Geheimnisse zusammen mit Ihrem Code öffentlich auf GitHub veröffentlichen, aber das scheint im allgemeinen Fall unklug. Jedoch nur Sie kann die notwendigen Kompromisse für Ihre System, um innerhalb eines bestimmten Bedrohungsmodells ordnungsgemäß zu funktionieren. - CodeGnome
Alle Ihre Punkte sind korrekt, außer dass sie für Umgebungsvariablen ebenso wie für andere Konfigurationsdaten gelten. Wenn Sie Umgebungsvariablen in Dateien speichern, können Sie sie übernehmen. und wenn Sie sie out-of-band senden, ist es einfacher, in einer Datei zu tun, als sie zu tippen. Aber wenn Sie es vorziehen, sie zu tippen, geben Sie stattdessen ein JSON-Objekt ein und lesen Sie es auf der Standardeingabe. Das ist tatsächlich sicherer als die Befehlszeile. - jpaugh


Persönlich würde ich nicht empfehlen, Umweltvariablen zu setzen .bashrc wie diese sichtbar werden alles Prozesse, die von der Shell gestartet wurden, aber auf Daemon / Supervisor-Ebene (init / rc script, systemd config) gesetzt werden, so dass ihr Umfang auf den benötigten Bereich beschränkt ist.

Wenn einzelne Teams Operationen verwalten, stellen Umgebungsvariablen eine einfache Schnittstelle für Vorgänge bereit, um die Umgebung für die Anwendung festzulegen, ohne dass sie sich mit den Konfigurationsdateien / -formaten auskennen müssen und / oder auf die Verfälschung ihres Inhalts zurückgreifen müssen. Dies gilt insbesondere in mehrsprachigen / Multi-Framework-Umgebungen, 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 - wie Code anders durchläuft Umgebungen (z. B. dev, test / qa, staging, production) Die Umgebungsdaten (Einsatzbereiche, Datenbankverbindungsmerkmale, Anmeldeinformationen, IP-Adressen, Domänennamen usw.) werden am besten durch dedizierte Konfigurationsverwaltungstools / -frameworks festgelegt und von der Anwendung konsumiert Prozesse aus der Umgebung (in einem DRY, einmal schreiben, irgendwo laufen Mode). Üblicherweise neigen Entwickler dazu, diese betrieblichen Probleme zu lösen, sie tendieren dazu, Konfigurationsdateien oder Vorlagen neben Code einzuchecken - und fügen dann Workarounds und andere Komplexität hinzu, wenn sich die betrieblichen Anforderungen ändern (z. B. neue Umgebungen / Deployment / Sites, Skalierbarkeit / Sicherheit) eingewogen, mehrere Feature-Zweige - und plötzlich gibt es handgerollte Deployment-Skripte, um die vielen Konfigurationsprofile zu verwalten / zu zerlegen - diese Komplexität ist eine Ablenkung und ein Overhead, der außerhalb des Codes durch spezielle Tools am besten bewältigt werden kann.

  • Env-Vars vereinfachen die Konfiguration / Komplexität im Maßstab.
  • Env-vars setzt die operationale Konfiguration direkt mit dem für die Nicht-Code bezogenen Aspekte der Anwendung in einer einheitlichen (wenn nicht Standard) unverbindlichen Art und Weise.
  • Env-vars unterstützt den Austausch der Master- / Supervisor-Prozesse (z. B. god, monit, supervisord, sysvinit, systemd usw.), die die Anwendung - und sicherlich sogar das Bereitstellungssystem (Betriebssysteme, Container-Images usw.) - als betriebliche Anforderungen unterstützen entwickeln / ändern. Während jedes Sprachframework heutzutage einige Prozesslaufzeiten aufweist, sind diese tendenziell betrieblich minderwertig, eher für Entwicklungsumgebungen geeignet und / oder erhöhen die Komplexität in Produktionsumgebungen mit mehreren Sprachen / mehreren Frameworks.

Für die Produktion bevorzuge ich die Einstellung der Anwendung env-vars in einem Umgebungsdatei sowie/etc/default/myapplication.conf Diese wird vom Konfigurationsmanagement bereitgestellt und nur für lesbar eingestellt root so dass systemd (oder irgendetwas anderes für die Angelegenheit) kann die Anwendung unter einem dedizierten erzeugen Deprivilegierter Systembenutzer in einem Private Gruppe. Unterstützt mit dedizierten Benutzergruppen für ops und sudo - Diese Dateien sind von der Welt standardmäßig nicht lesbar. Dies ist 12-fach kompatibel und unterstützt alle Vorteile von Dev + Ops. Außerdem bietet es alle Vorteile einer anständigen Sicherheit und erlaubt Entwicklern / Testern, ihre eigenen EnvironmentFiles in den dev / qa / test-Umgebungen abzusetzen.


1
2018-01-17 23:38





Aus der Sicht von Entwicklern vereinfacht das Speichern von Konfigurationsdaten in Umgebungsvariablen die Bereitstellung in verschiedenen Umgebungen - Entwicklung, Qualitätssicherung und Produktion - und befreit Entwickler davon, sich über die Bereitstellung der falschen Konfigurationsdatei Gedanken machen zu müssen.

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

Darüber hinaus werden potenziell vertrauliche Daten außerhalb der Quellcodeverwaltung aufbewahrt. Das Ignorieren dieser Dateien aus der Quellcodeverwaltung ist (zumindest in .NET) nicht wirklich machbar, da in diesen Dateien auch eine Menge notwendiger Standardkonfigurationen vorhanden sind.


0
2018-01-17 02:16