Einleitung
Eine zusätzliche Funktion während der Erstellung eines Cloud Servers (CX11 oder höher) ist User data. Damit lässt sich eine cloud-init-Konfiguration zur Ausführung an den neu erstellten Server senden.
Am Ende dieses Tutorials wirst du in der Lage sein, die Einrichtung neuer Cloud Server mit eigener Konfiguration anzupassen.
Teile dieser Konfiguration basieren auf dem Tutorial Absicherung des SSH Dienstes.
Schritt 1 - Erste Zeile Einfügen
Die cloud-init-Konfig nutzt YAML ("YAML Ain't Markup Language") als Auszeichnungssprache.
Die Datei sollte mit einem Kommentar in der ersten Zeile starten, damit der Code vom Server als cloud-config interpretiert wird:
#cloud-config
Schritt 2 - Benutzer erstellen
Fangen wir nach dem einleitenden Kommentar mit dem Erstellen eines neuen Benutzers mit sudo
-Privilegien und vorkonfiguriertem SSH-Schlüssel an.
Wie wird ein SSH Schlüsselpaar erstellt?
users:
- name: holu
groups: users, admin
sudo: ALL=(ALL) NOPASSWD:ALL
shell: /bin/bash
ssh_authorized_keys:
- <public_ssh_key>
Schritt 3 - Pakete Aktualisieren
Als erstes werden die Paketlisten und installierten Pakete aktualisiert. Eine frische Installation von Linux kann veraltete Pakete mit kritischen Sicherheitslücken beinhalten.
In diesem Schritt kannst du auch alle notwendigen Pakete für deine Projekte installieren.
Wenn Pakete installiert oder aktualisiert werden sollen, wird cloud-init die Paketlisten vorher aktualisieren.
packages:
- fail2ban
- ufw
package_update: true
package_upgrade: true
Schritt 4 – Befehle ausführen
cloud-init erlaubt das Ausführen von Kommandozeilen-Befehlen direkt nachdem der Server erstellt wurde.
Starte das Prozedere durch runcmd:
in einer neuen Zeile.
Schritt 4.1 – fail2ban konfigurieren
Jeder der folgenden Befehle wird in eine neue Zeile geschrieben, vorangestellt mit einem Bindestrich.
Um das Netzwerk-Protokoll SSH etwas abzusichern, wird fail2ban gegen Brute-Force-Angriffe eingesetzt.
Standardmäßig werden Angreifer für 10 Minuten gesperrt – nachdem 5 Anmeldeversuche innerhalb von 10 Minuten fehlgeschlagen sind.
- printf "[sshd]\nenabled = true\nbanaction = iptables-multiport" > /etc/fail2ban/jail.local
- systemctl enable fail2ban
Step 4.2 – ufw aktivieren
Uncomplicated Firewall (ufw) wird verwendet, um das System abzusperren und nur benötigte Dienste zu erlauben.
Später wirst du von Applikationen gebrauchte Dienste oder Ports (zum Beispiel 80/443) öffnen müssen.
- ufw allow OpenSSH
- ufw enable
Schritt 4.3 – SSH abhärten
Die letzte Kette von Befehlen ist darauf ausgelegt, SSH stärker abzusichern.
Der Befehl sed
wird verwendet, um Teile der sshd_config
-Datei anzupassen.
Durchgeführte Änderungen:
- Deaktivieren des Root Logins
- Benutzer für SSH freischalten
- Deaktivieren der Passwort-Authentifizierung
- Automatischer Verbindungsabbruch bei fehlerhaftem Login
- Deaktivieren nicht genutzter Funktionen
- sed -i -e '/^\(#\|\)PermitRootLogin/s/^.*$/PermitRootLogin no/' /etc/ssh/sshd_config
- sed -i -e '/^\(#\|\)PasswordAuthentication/s/^.*$/PasswordAuthentication no/' /etc/ssh/sshd_config
- sed -i -e '/^\(#\|\)KbdInteractiveAuthentication/s/^.*$/KbdInteractiveAuthentication no/' /etc/ssh/sshd_config
- sed -i -e '/^\(#\|\)ChallengeResponseAuthentication/s/^.*$/ChallengeResponseAuthentication no/' /etc/ssh/sshd_config
- sed -i -e '/^\(#\|\)MaxAuthTries/s/^.*$/MaxAuthTries 2/' /etc/ssh/sshd_config
- sed -i -e '/^\(#\|\)AllowTcpForwarding/s/^.*$/AllowTcpForwarding no/' /etc/ssh/sshd_config
- sed -i -e '/^\(#\|\)X11Forwarding/s/^.*$/X11Forwarding no/' /etc/ssh/sshd_config
- sed -i -e '/^\(#\|\)AllowAgentForwarding/s/^.*$/AllowAgentForwarding no/' /etc/ssh/sshd_config
- sed -i -e '/^\(#\|\)AuthorizedKeysFile/s/^.*$/AuthorizedKeysFile .ssh\/authorized_keys/' /etc/ssh/sshd_config
- sed -i '$a AllowUsers holu' /etc/ssh/sshd_config
"ChallengeResponseAuthentication" ist veraltet und wurde abgelöst von "KbdInteractiveAuthentication". Die obenstehende Konfiguration enthält beide Optionen, da mit den Befehlen ohnehin nur die Optionen angepasst werden, die in der Datei auch tatsächlich vorkommen. Was nicht gefunden wird, wird übersprungen.
Schritt 4.4 - Neustart
Ein letzter Befehl ist noch auszuführen: reboot
Warum? Drei Fliegen mit einer Klappe:
- Nach Paket-Updates kann ein Neustart erforderlich sein, damit die Änderungen wirksam werden.
- fail2ban muss neu gestartet werden, um den aktivierten SSH-Schutz auszuführen.
- Die geänderten Einstellungen von SSH sind ebenfalls erst nach einem Neustart aktiv.
Schritt 5 – Erstelle den Server
Öffne die Cloud Console, wähle ein Projekt aus und erstelle einen Server. Füge nun im Textfeld unter "Cloud config" deine Konfiguration ein. Ganz unten von diesem Tutorial ist eine Zusammenfassung der kompletten Konfiguration.
Auf ein externes cloud-init-Skript verweisen
Anstatt die gesamte Konfiguration beim Erstellen des Servers anzugeben, kann diese auch extern in einer Datei gespeichert werden. Beim Erstellen des Servers muss dann nur noch der Link angegeben werden. Das kann beispielsweise sinnvoll sein, wenn man dieselbe Konfiguration für mehrere Server verwendet oder den Server per curl-Befehl erstellt.
Speicher die Datei mit deiner Konfiguration und kopiere den Link, z.B. https://URLtoCode/config.yaml
.
-
Cloud Console
Öffne die Cloud Console, wähle ein Projekt aus und erstelle einen Server. Füge nun im Textfeld unter "Cloud config" deinen Link ein:
#include https://URLtoCode/config.yaml
-
Curl-Befehl
Bearbeite die Server-Eigenschaften nach deinen Anforderungen. Für
user_data
muss#include
angegeben werden, gefolgt von einem Textumbruch und dem Link zur Konfiguration, z.B.#include\nhttps://URLtoCode/config.yaml
.curl \ -X POST \ -H "Authorization: Bearer $API_TOKEN" \ -H "Content-Type: application/json" \ -d '{"image":"ubuntu-22.04","location":"nbg1","name":"my-server","server_type":"cx11","user_data":"#include\nhttps://URLtoCode/config.yaml"}' \ 'https://api.hetzner.cloud/v1/servers'
Fahre nun deinen automatisch abgesicherten Cloud Server hoch.
Nachdem der Server erstellt wurde, gehe in der Cloud Console zu Graphen und warte, bis die Auslastung der CPU auf Null sinkt. Alle Befehle wurden nun ausgeführt und der Server ist neu gestartet. Du kannst dich nun mit dem erstellten Benutzer über SSH anmelden.
Ergebnis
Viele Worte für 21 Zeilen Code, was?
Ich hoffe du konntest viel lernen! Zum Beispiel:
- Eine Konfiguration für cloud-init von Grund auf bauen.
- Benutzer mit
sudo
und anderen Eigenschaften erstellen. - Befehle während dem ersten Serverstart ausführen.
sed
zum Manipulieren von Dateien nutzen.
Jetzt leg los und baue etwas großartiges!
Die komplette Konfiguration:
#cloud-config
users:
- name: holu
groups: users, admin
sudo: ALL=(ALL) NOPASSWD:ALL
shell: /bin/bash
ssh_authorized_keys:
- <public_ssh_key>
packages:
- fail2ban
- ufw
package_update: true
package_upgrade: true
runcmd:
- printf "[sshd]\nenabled = true\nbanaction = iptables-multiport" > /etc/fail2ban/jail.local
- systemctl enable fail2ban
- ufw allow OpenSSH
- ufw enable
- sed -i -e '/^\(#\|\)PermitRootLogin/s/^.*$/PermitRootLogin no/' /etc/ssh/sshd_config
- sed -i -e '/^\(#\|\)PasswordAuthentication/s/^.*$/PasswordAuthentication no/' /etc/ssh/sshd_config
- sed -i -e '/^\(#\|\)KbdInteractiveAuthentication/s/^.*$/KbdInteractiveAuthentication no/' /etc/ssh/sshd_config
- sed -i -e '/^\(#\|\)ChallengeResponseAuthentication/s/^.*$/ChallengeResponseAuthentication no/' /etc/ssh/sshd_config
- sed -i -e '/^\(#\|\)MaxAuthTries/s/^.*$/MaxAuthTries 2/' /etc/ssh/sshd_config
- sed -i -e '/^\(#\|\)AllowTcpForwarding/s/^.*$/AllowTcpForwarding no/' /etc/ssh/sshd_config
- sed -i -e '/^\(#\|\)X11Forwarding/s/^.*$/X11Forwarding no/' /etc/ssh/sshd_config
- sed -i -e '/^\(#\|\)AllowAgentForwarding/s/^.*$/AllowAgentForwarding no/' /etc/ssh/sshd_config
- sed -i -e '/^\(#\|\)AuthorizedKeysFile/s/^.*$/AuthorizedKeysFile .ssh\/authorized_keys/' /etc/ssh/sshd_config
- sed -i '$a AllowUsers holu' /etc/ssh/sshd_config
- reboot