Immutable Infrastructure und Sicherheit, Teil 2

  • Link11-Team
  • April 4, 2024

Inhalt

Immutable Infrastructure und Sicherheit, Teil 2

Immutable Infrastructure bietet viele Sicherheitsvorteile. Im vorigen Artikel haben wir einen Überblick über einige der potenziellen Vorteile für Softwareentwicklungsunternehmen gegeben, die Immutable Infrastructure implementieren. Immutabilität ist ein wichtiges Element zur Verbesserung der Skalierbarkeit, der Geschäftsergebnisse und vor allem der Sicherheitslage.

In Teil 2 werden wir nun einige praktische Aspekte von dieser untersuchen. Als Konzept ist Immutable Infrastructure einfach. In der Praxis ist es manchmal nicht so einfach. Die technische Leitung kann eine Planung auf hoher Ebene durchführen, aber um darüber hinauszugehen, sind in der Regel die Zustimmung der Organisation und eine detailorientierte technische Implementierung erforderlich.

In diesem Artikel werden wir einige konkrete Schritte und Implementierungsmuster besprechen. Wir werden sehen, wie man Immutabilität nutzen und die Sicherheit erheblich verbessern kann, indem man:

  • Verkleinerung der Zugriffsfläche
  • Vereinfachung des Abhängigkeitsmanagements
  • und Verbesserung der operativen Ergebnisse.

Verkleinerung der Zugriffsfläche

Fernzugriffsmechanismen stellen einen der am häufigsten genutzten Angriffsvektoren für Softwareinfrastrukturen dar. Die Suche nach einer Möglichkeit, die Angriffsfläche und den Umfang dieser Mechanismen zu begrenzen, sollte ein wichtiger Schwerpunkt der Software- und Betriebsteams sein. Glücklicherweise steht diesen Teams eine Vielzahl von Tools und Architekturmustern zur Verfügung, um Immutabilität zu implementieren und die Abhängigkeit von veralteten Zugriffsmustern zu verringern.

Herkömmliche Serverflotten erlauben häufig den direkten Fernzugriff über Secure Shell (SSH), Remote Desktop (RDP) oder ältere Protokolle wie Telnet. In älteren, lokalen Netzwerkarchitekturen konnten diese Protokolle mit relativer Sicherheit verwendet werden; der WAN- oder Internetzugang zum Netzwerk wurde über Firewalls und NAT-Gateways streng kontrolliert, und auf keinen Knoten konnte direkt zugegriffen werden, ohne die Firewall zu passieren. In der modernen cloud-basierten Architektur hat jedoch fast jeder Knoten einen direkten Internetzugang oder ist dazu in der Lage, so dass der Fernzugriff auf diesen Knoten ein viel größeres Sicherheitsrisiko darstellt.

In modernen verteilten Systemen greifen interaktive (menschliche) Benutzer oft direkt über Fernzugriffsprotokolle auf Knoten zu, um Out-of-Band-Konfigurationsänderungen vorzunehmen oder Wartungsaufgaben durchzuführen. Herkömmliche Konfigurationsmanagement-Tools wie Chef, Puppet und Ansible können SSH verwenden, um die Verwaltung großer Systeme skalierbarer zu machen, aber sie sind immer noch auf einen breiten Zugang zu jedem Knoten angewiesen. Selbst mit diesen Tools ist eine Konfigurationsabweichung unvermeidlich, und im Zusammenhang mit der Zugriffsverwaltung ist dies besonders gefährlich.

Die Lösung mit einem Immutable Pattern

Anstatt sich auf den dauerhaften Zugriff zu verlassen, den die Tools für die Konfigurationsverwaltung erfordern, sollten Sie die gesamte erforderliche Konfiguration bereits vor dem Start des Servers abgeschlossen haben. Tools wie Packer von HashiCorp machen dies möglich.

Packer verfügt über eine umfangreiche Liste von Funktionen und Möglichkeiten, aber auf einer hohen Ebene wird es verwendet, um vorkonfigurierte Maschinen-Images für eine Vielzahl von Cloud- und Compute-Orchestrierungsplattformen zu erzeugen. Benutzer können zahlreiche Konfigurationsoptionen für die Installation von Betriebssystempaketen, Dateien und Daten festlegen. Packer startet dann einen ephemeren Knoten, führt alle vordefinierten Konfigurationsaufgaben für diesen Knoten aus, als ob es sich um eine Live-Umgebung handeln würde, und erfasst dann den gesamten Zustand der Maschine in einem „Golden Image“-Format, das von der Plattform verwendet wird, wie z. B. ein Amazon Machine Image. Dieses Image kann dann verwendet werden, um vorkonfigurierte Knoten massenweise zu starten.

Packer bietet zahlreiche Vorteile in Bezug auf verbesserte Sicherheit und geringere Komplexität, und das von ihm bereitgestellte Muster ist eine grundlegende Komponente von Immutable Infrastructure. Engineering-Teams können nun weniger auf Konfigurationsmanagement-Tools zurückgreifen, die einen ständigen Fernzugriff erfordern. Stattdessen können sie Konfigurationsänderungen durch den Start völlig neuer Knoten mit neuen Images einführen. Teams können Packer auch in der Automatisierung, wie CI/CD, einsetzen, um den Prozess weiter zu rationalisieren und zusätzliche Testleitplanken zu schaffen.

Für Organisationen, in denen ein direkter Knotenzugriff immer noch erforderlich ist (z. B. Rails- oder PHP-Konsolen), kann ein anderes Muster verwendet werden, das dennoch der Immutabilität folgt. Administrative Verwaltungsfunktionen sollten als einmalige Prozesse von einem dedizierten Proxy-Knoten ausgeführt werden. Die Konfiguration für jeden Knoten muss nur den Zugriff von einem einzigen Proxy erlauben. Teams können dann den Netzwerkzugriff auf den Proxy beschränken, indem sie Tools verwenden, die auf fast allen wichtigen Cloud-Plattformen verfügbar sind.

Vereinfachung des Abhängigkeitsmanagements

Moderne Entwicklungsumgebungen selbst für einfache webbasierte Anwendungen sind überraschend komplex. Die Aufrechterhaltung homogener Umgebungen zwischen lokaler Entwicklung, Tests, Staging und Produktion ist einer der wichtigsten Faktoren für die Geschwindigkeit von Entwicklung und Bereitstellung. Die Verwendung immutabler Prinzipien kann dazu beitragen, diese Homogenität zu fördern, indem die Verwaltung von Abhängigkeiten vereinfacht wird.

Um auf das webbasierte Beispiel zurückzukommen, stellen Sie sich für dieses Szenario eine hypothetische Umgebung vor, in der eine JavaScript-basierte Anwendung auf einem Standard-Rechenknoten wie EC2 oder Google Compute Engine bereitgestellt wird. Das JavaScript-Ökosystem verfügt über eine unglaublich vielfältige Auswahl an Bibliotheken, Build- und Kompilierwerkzeugen und Middleware. Ein Entwickler muss möglicherweise Dutzende oder Hunderte von versionierten Abhängigkeiten sowie eine Vielzahl von Kompilierungs- und Middleware-Tools für eine funktionale Entwicklungsumgebung installieren. Sobald die Arbeit an einer Funktion oder einer Codeänderung abgeschlossen ist, muss der Entwickler diese Änderung in der Zielumgebung (in der Regel der Produktionsumgebung) bereitstellen. Die Änderung hängt von einer Darstellung aller Abhängigkeiten und der verwendeten Tools zu einem festen Zeitpunkt ab.

Was passiert, wenn das sorgfältig ausgearbeitete Changeset eines Entwicklers in der Testumgebung nicht funktioniert? Sie ändern vielleicht ein paar Abhängigkeiten oder eine Build-Tool-Version. Das mag die Tests beheben, aber was passiert, wenn dieselbe Änderung in der Produktionsumgebung nicht funktioniert oder, schlimmer noch, einen Ausfall verursacht? Die Aufgabe, das tatsächliche Problem zu identifizieren, wird durch mehrere übereinander geschichtete Änderungen erheblich erschwert, was die Bereitstellungsgeschwindigkeit messbar verlangsamt.

Die Lösung mit einem Immutable Pattern

Das ultimative Ziel ist die Erstellung eines immutablen Build-Artefakts: eine vollständig gekapselte Einheit, die alle Änderungen und die für eine erfolgreiche Bereitstellung erforderlichen Abhängigkeiten und Tools enthält. Container sind ein ideales Medium für diesen Ansatz.

Ein Container-Build-Artefakt ist mit einem eindeutigen Hash-Wert versehen wie eine Versionsübergabe. Die Build- und Deployment-Phasen sind strikt voneinander getrennt; wenn zusätzliche Änderungen vorgenommen werden müssen, werden sie mit einem neuen Artefakt durchgeführt, das mit einer neuen Build-Phase beginnt. Wenn Tests fehlschlagen oder die Änderung in einer Umgebung nicht funktioniert, wird ein neuer Build erstellt. Durch diese strikte Trennung der Umgebungen wird verhindert, dass Änderungen in frühere Umgebungen zurückgeführt werden, wodurch die im vorherigen Abschnitt beschriebene Komplexität von Änderungen auf mehreren Ebenen vermieden wird.

Am Beispiel von AWS können Teams ECR verwenden, um getaggte Images zu speichern, auf die andere Teams zugreifen können und die dann von der gemeinsamen Build- und Bereitstellungsautomatisierung verwendet werden können. Wenn das Artefakt alle Tests bestanden hat, ist es an der Zeit, es in einer verwalteten Containerumgebung wie ECS oder EKS bereitzustellen. Mit diesem Build- und Deployment-Muster ist es sehr einfach, den Lebenszyklus der Anwendung im Kontext der bereitgestellten und verfügbaren Versionen auf einen Blick zu verstehen.

Verbesserung der operativen Ergebnisse

In herkömmlichen Serverflotten sind die Server in der Regel sehr langlebig und werden wie Haustiere behandelt. Sie haben eine eindeutige und oft inkonsistente Namensgebung, und im Laufe der Zeit sammeln sich mehrere Schichten von Änderungen, Optimierungen und Hacks an, um neue Bereitstellungen, Tools, Sicherheits-Patches und andere Änderungen zu berücksichtigen. Im Laufe der Zeit wird es fast unmöglich, eine gemeinsame Grundlage für das Verständnis der kanonisch korrekten Konfiguration dieser Server zu schaffen.

Solange die Produktionsumgebung technisch „funktioniert“, wird dieses Problem wahrscheinlich nicht angegangen werden. Es kann jedoch der Zeitpunkt kommen, an dem Ingenieure eine kritische Sicherheitsbehebung für eine Anwendungsabhängigkeit oder ein Betriebssystempaket mit einer kritischen Sicherheitslücke bereitstellen müssen. Da es wahrscheinlich überall unterschiedliche Versionen von Paketen und Konfigurationen gibt, gibt es keinen einfachen oder klaren Weg, ein Upgrade zentral zu verwalten und zu überprüfen. Dinge können leicht kaputtgehen, und ein Ausfall ist fast garantiert.

Diese Art von Umgebungen führt dazu, dass die Angst vor Installationen wächst. Weniger Deployments sind ein teuflischer, sich entwickelnder Kreislauf der DevOps- „Missstände “. Weniger Deployments bedeuten auch, dass Updates für Dinge wie Sicherheitslücken vermieden werden, was zu einer gefährlichen Verschlechterung der Sicherheitslage und höchstwahrscheinlich zu einer Kompromittierung führt. Glücklicherweise kann das Prinzip der Immutable Infrastructure wieder eine Lösung bieten.

Die Lösung mit einem Immutable Pattern

Tools wie Packer erweisen sich auch hier als wertvoll. In Kombination mit CI/CD und Infrastrukturtests tragen sie dazu bei, die Ergebnisse von Bereitstellungen und Sicherheitszielen zu verbessern.

Wie jedes Infrastructure-as-Code-Tool können Ingenieure die Konfiguration von Packer in der Versionskontrolle speichern. In Kombination mit CI/CD und automatisiertem Tagging können Teams eine anerkannte, zentral gemeinsam genutzte Konfiguration von Produktionsservern und Workloads erstellen. Wenn ein Ingenieur oder ein anderer Beteiligter wissen möchte, was derzeit in der Produktionsumgebung läuft, muss er lediglich das Tag eines laufenden Servers mit der entsprechenden Codeänderung und dem daraus resultierenden Build- und Deployment-Prozess korrelieren.

Wenn eine Abhängigkeit oder ein Betriebssystempaket aktualisiert werden muss, wird ein neues Server-Image erstellt, mit aktuellen Anwendungsversionen getestet und als Ersatz für die vorhandenen Server bereitgestellt. Infrastructure-as-code-Tools wie Terraform ermöglichen einen „Nuke-and-Pave“-Ansatz, bei dem die bestehende Infrastruktur abgerissen und durch völlig neue Server mit der neuen Konfiguration ersetzt wird. Dank dieses Musters können Entwicklungsteams mehr Vertrauen in die Sicherheit ihrer Implementierungen und Änderungen haben. Mehr Vertrauen führt zu mehr Implementierungen, was einen positiven Kreislauf darstellt, der die Sicherheitslage verbessert und auch eine etablierte Kennzahl für den relativen Erfolg einer Softwareentwicklungsorganisation ist.

Immutable Infrastructure ist ein wichtiger Faktor für die Sicherheit

Die Immutabilität der Infrastruktur und der Softwareentwicklung im Allgemeinen ist ein wichtiges Element zur Verbesserung der Skalierbarkeit, der Geschäftsergebnisse und vor allem der Sicherheitslage.

Entwicklungsteams, die immutable Infrastrukturmuster in ihren Prozessen und ihrer Architektur verwenden, sind eher in der Lage, häufige Änderungen vorzunehmen, kritische Sicherheitskorrekturen bereitzustellen und völlig neue Anwendungsfunktionen zu entwickeln. Softwareunternehmen sollten nach schnellen Erfolgen Ausschau halten, die sie auf den längeren Weg zur vollständigen Immutabilität bringen.

Für viele Unternehmen wird dies auch einen aktualisierten Ansatz für die Web-Sicherheit erfordern. In der heutigen Bedrohungslage benötigen Anwendungen und APIs nicht nur einen umfassenden Schutz, sondern auch eine Sicherheitslösung, die mit II und den anderen oben genannten Verfahren kompatibel ist.

Link11 bietet eine All-in-One-Cloud-Web-Sicherheitslösung. Sie umfasst WAF, DDoS-Schutz, erweiterte Ratenbegrenzung, Bot-Management, Sitzungsflusskontrolle, API-Sicherheit, Echtzeit-Verkehrstransparenz, ATO (Account-Takeover)-Prävention und mehr.

Neuer DDoS-Report für das 1. Halbjahr 2022
DDoS-Mitigation: Warum Zeit eine kritische Rolle spielt
X