Security-Prozesse automatisieren, am Beispiel von Updates

Aktuelles

Security-Prozesse automatisieren

Vor kurzem haben wir im Artikel Umgang mit Software-Updates und Abkündigungen seitens Hersteller thematisiert, dass veraltete Software negative Auswirkungen auf die Sicherheit von Infrastrukturen haben kann, sich diese Aussage jedoch nicht verallgemeinern lässt, da es darauf ankommt, an welcher Stelle die Systeme zum Einsatz kommen und wie sie in der Infrastruktur betrieben werden.

Im heutigen Artikel soll es um ein ähnliches Ziel gehen, jedoch mit einer praktischen Umsetzung in einer Test-Umgebung. Dabei nutzen wir einen automatisierten Weg, um Updates einzuspielen. Eine vergleichsweise einfache Aktion, die sich über verschiedenste Wege realisieren lässt, inkl. direkt über das Betriebssystem. Die exemplarische Umsetzung soll zeigen, dass verschiedenste Maßnahmen, am Beispiel Software-Update, über diesen Weg umgesetzt werden können.

automatisierte Security Prozesse mit Ansible

Ansible ist eine Softwarelösung mit der sich auf Basis von sogenannten Playbooks Kommandos, Aktionen und Programmzeilen auf verschiedenen Systeme gleichzeitig umsetzen lassen. Die Ziel-Systeme, auf denen diese Befehle umgesetzt werden, lassen sich in einer Host Liste pflegen und gruppieren. Die Kommunikation zwischen Ansible und den Zielen basiert auf SSH, sodass kein Agent auf den Ziel-Systemen nötig ist. In unserem folgenden Beispiel nutzen wir das Tool Ansible. Es gibt mit Puppet, Saltstack, Terraform und weiteren, viele Ansätze zur Automatisierung.

Ansible auf einen Blick:

  • Erstellen von Skripten (Playbooks) erzeugen einmaligen Aufwand
  • Das Ausführen der Skripte kann manuell erfolgen oder in Wartungs-Plattformen integriert werden.
  • Die Kommunikation ist im Anschluss an die SSH-Konfiguration bereits möglich.
  • Die Ausführung der Skripte kann gruppenbasiert erfolgen, sodass Unterschiede in der Systemkonfiguration Berücksichtigung finden.

Wartungs-System

Für die SSH Kommunikation ist es sinnvoll, ein Wartungs-System zu erstellen, von dem aus die Ansible Skripts gestartet werden. Das hat den Vorteil, dass einmal erstellte SSH Keys zentral verteilt oder sogar in Images eingebettet werden können, sodass zukünftige Systeme automatisch Teil der Ansible Infrastruktur werden. Nachfolgende Befehle gelten für die aktuelle Ubuntu Server-Version und müssen ggfs. auch in andere Distributionen adaptiert werden.

Mit den folgenden Schritten erstellen und verteilen wir den SSH-Schlüssel:

  • Wir erstellen einen SSH Schlüssel auf unserem Wartungs-System.
    • ssh-keygen -t rsa -b 4096
  • Den Schlüssel schützen wir mit einem Kennwort
  • Den Schlüssel verteilen wir auf alle Systeme, die wir warten möchten.
    • ssh-copy-id -i ~/.ssh/id_rsa user@server
  • Kurzer Test ssh user@server zeigt, ob die Kommunikation funktioniert. Im Anschluss an die Eingabe des Kennworts sind wir auf dem System.

Auf unserem Wartungs-System installieren wir Ansible:

  • Sofern Python noch nicht installiert ist, installieren wir es:
    • sudo apt install python3-pip -y
  • Im Anschluss installieren wir Ansible:
    • sudo apt install ansible -y

Hosts für die Wartung definieren:
Im Anschluss an die Installation editieren wir die Hosts Datei, welche alle Systeme samt Gruppierungen enthält, die wir über Ansible warten möchten.

  • Hosts Datei öffnen und editieren:
    • sudo nano /etc/ansible/hosts

Hier tragen wir unsere Server-Systeme sowie die Gruppen ein. Je nach Namenskonvention kann auch mit Platzhaltern gearbeitet werden.

[Gruppe]
server1
server[2:3]

Ansible Playbooks erstellen:
Ist die Konfiguration abgeschlossen, können Skripte zur Wartung erstellt und angewendet werden. Der Vorteil an einer weit verbreiteten Lösung für die Automatisierung ist unter anderem, dass es viele Skripte und Codebeispiele bereits gibt. So haben wir die Möglichkeit, auf eine bestehende Basis zurückzugreifen und passen diese nur noch an unsere Bedürfnisse an. Für die Anwendungsfälle, die infrastrukturspezifisch sind, erstellen wir diese Skripte selbst.

Für das Update-Beispiel unterstützt uns die Ansible Doku, in der beschrieben wird, wie Updates mit dem Update Modul eingespielt werden. Für unser Beispiel nutzen wir dies und speichern es als update.yml ab.

---
- hosts: all
  become: true
  become_user: root
  tasks:
    - name: Pakete aktualisieren Update
      apt: update_cache=yes force_apt_get=yes cache_valid_time=3600

    - name: Update einspielen Upgrade
      apt: upgrade=dist force_apt_get=yes

    - name: Auf Neustart prüfen
      register: reboot_required_file
      stat: path=/var/run/reboot-required get_md5=no

    - name: Neustart bei Bedarf umsetzen
      reboot:
        msg: "Neustart im Anschluss an Ansible Update"
        connect_timeout: 5
        reboot_timeout: 300
        pre_reboot_delay: 0
        post_reboot_delay: 30
        test_command: uptime
      when: reboot_required_file.stat.exists

Playbook anwenden:
Im nächsten Schritt wenden wir das Skript an. Damit das Update durchgeführt wird, benötigen wir Root-Berechtigungen. Hierfür richten wir auf allen Systemen einen entsprechenden Wartungs-Benutzer ein. Damit wir beim Ausführen des Skripts nach dem Kennwort gefragt werden, ohne das Kennwort im Klartext als Parameter mit anzugeben, nutzen wir den Aufruf “ask-become-pass”.

  • Ansible Playbook ausführen
    • ansible-playbook test.yml --ask-become-pass

Für das Update werden wir bei Ausführung nach dem SSH Passwort sowie nach dem Root Passwort gefragt. Auf allen angegeben Systemen werden im Anschluss die Updates eingespielt und bei Bedarf ein Neustart durchgeführt.

Integration des Ansatzes in unsere Prozesse

Das Wartungs-System mit Ansible dient als Beispiel, wie sich einzelne Schritte in der Administration automatisieren lassen, um auf sicherheitsrelevante Themen zu reagieren. Diese Schritte sind jedoch nur so gut, wie sie in die Gesamtprozesslandschaft passen und anwendbar bleiben. Kennwörter manuell einzugeben ist für unser Beispiel ausreichend, in dem wir die grundsätzliche Funktionsweise testen. In einem automatisierten Prozess ersetzen wir den händischen Weg, jedoch durch definierte und geschützte Variablen. Viele Plattformen unterstützen den Schutz dieser sensiblen Daten durch besonders geschützte Variablen-Felder in der Software. Somit lassen sich die Skripte in einen sicheren Betrieb einbetten, ohne erneute Sicherheits-Schwächen in die Systeme mit einzubauen. Wir haben in der Vergangenheit bereits über DevSecOps berichtet, einem Verfahren, in dem der Entwicklungs- und Security-Prozess zusammenhängend passiert, um flexibel und schnell auf Security-Anforderungen zu reagieren.

Fazit

Am Beispiel Ansible sind wir mit wenigen Handgriffen in der Lage, eine händische Aktivität wie das Aktualisieren verschiedener Server in einen automatisierten Prozess zu überführen. Dieser Prozess wird nun nicht nur in der Umsetzung einfacher, sondern wir haben auch einen Standard-Weg geschaffen, wie alle System-Updates eingespielt werden. Das gibt uns die Möglichkeit, in die Automatisierung entsprechende Protokollierungs-Parameter mit einzubauen. Einen (Wartungs)-Prozess zu automatisieren funktioniert über verschiedenste Software-Frameworks, beispielsweise auch über Puppet, Saltstack und Terraform.

Mit einem geschaffenen Standard sorgen wir dafür, den Aufwand für bestimmte Aktionen zu reduzieren. Ein wichtiger Aspekt dieser Automatisierung ist die Möglichkeit, nach Systemen bzw. -Gruppen zu unterschieden, um auf Besonderheiten Rücksicht zu nehmen. Ein weiterer Aspekt der Gruppierung ist, dass nicht alle Systeme zum gleichen Zeitpunkt aktualisiert werden, sondern man die dauerhafte Verfügbarkeit von IT-Services durch Lastverteilung sicherstellt. In diesem Fall werden zwei oder mehr Gruppen erstellt und beim Update nur ein Teil der Systeme aktualisiert, um zusätzlich für Betriebs-Sicherheit zu sorgen.

Obwohl wir einen automatisierten Prozess erstellt haben, bleibt die komplette Prozesskette manuell steuerbar. Sie findet nur statt, wenn wir dies ausführen möchten. Andernfalls könnten wir in Ubuntu einen Cronjob einrichten, der regelmäßig Updates einspielt. Zum Wartungs-Prozess gehört mehr als nur das Einspielen der Software. Wir testen diese vorher in der Testumgebung, ehe wir damit in die Produktion gehen. Über den manuellen Weg starten wir das Update genau zu dem Zeitpunkt, der für die Wartung vorgesehen ist. Teil des Wartungsfenster ist im Anschluss auch der Funktionstest und weitere Schritte zur Bereinigung, sodass wir am Ende des Wartungsfensters die Gewissheit haben, dass alles wieder reibungsfrei funktioniert.

Vorheriger Beitrag
IT-Sicherheitsbetrachtung skalieren
Nächster Beitrag
Risiko ist Eintrittswahrscheinlichkeit x Schaden – Teil 1 Stabsorganisation

Aktuelles von CYBEResilienz

Hier lesen Sie Aktuelles rund um Themen zu Cyber-Attacken, wie man sich schützen kann und wie CYBEResilienz Ihnen hilft, Ihre Systemlandschaft sicherer zu machen.

Kategorien