14 KiB
Security & Hardening
Übersicht
Diese Kategorie umfasst Playbooks und Rollen zur Verbesserung der Systemsicherheit, insbesondere SSH-Zugriffsverwaltung und Härtung.
Anwendungsfälle:
- Verwaltung autorisierter SSH-Schlüssel
- Entfernung kompromittierter oder veralteter Schlüssel
- SSH-Zugriffskontrolle über Whitelisting und Blacklisting
- Zentrale SSH-Schlüssel-Verwaltung über mehrere Hosts
Playbooks
hardening/manage-ssh-keys.yaml
Verwaltung von SSH-Schlüsseln für Systemzugriff (Hinzufügen/Entfernen).
Datei: playbooks/hardening/manage-ssh-keys.yaml
Zweck: Zentrale Verwaltung von SSH-Public-Keys mit Whitelisting (erlaubte Schlüssel) und Blacklisting (zu entfernende Schlüssel) auf allen verwalteten Hosts.
Ziel-Hosts: all
Benutzer: tincadmin (mit sudo-Rechten)
Verwendete Rollen:
manage-ssh-keys
Wichtige Variablen:
| Variable | Typ | Beschreibung |
|---|---|---|
good_keys |
Liste | Autorisierte SSH-Public-Keys (werden hinzugefügt) |
bad_keys |
Liste | Zu entfernende SSH-Public-Keys (Blacklist) |
ssh_user |
String | Zielbenutzer für SSH-Schlüssel (Default: root) |
Verwendungsbeispiel:
# Mit Variablen aus Rolle (defaults/main.yml)
ansible-playbook playbooks/hardening/manage-ssh-keys.yaml \
-i inventories/icp-fra-pve1.yml \
-K
# Mit externen Variablen (JSON-Format)
ansible-playbook playbooks/hardening/manage-ssh-keys.yaml \
-i inventories/icp-fra-pve1.yml \
-e '{"good_keys": ["ssh-ed25519 AAAA... user@host"]}' \
-e '{"bad_keys": ["ssh-rsa AAAA... old-key"]}' \
-K
# Nur auf einzelnem Host
ansible-playbook playbooks/hardening/manage-ssh-keys.yaml \
-i inventories/icp-fra-pve1.yml \
--limit critical-server.example.com \
-K
# Für spezifischen User (nicht root)
ansible-playbook playbooks/hardening/manage-ssh-keys.yaml \
-i inventories/icp-fra-pve1.yml \
-e "ssh_user=tincadmin" \
-K
Abhängigkeiten:
manage-ssh-keysRolle- Sudo-Rechte auf Zielhosts
- SSH-Zugriff zu Hosts
Besonderheiten:
- Kommentierte Variablen für externe Übergabe im Playbook
- Validierung von Schlüsseln vor Anwendung
- Idempotent: Mehrfache Ausführung sicher
- Atomare Operationen: Erst Validierung, dann Änderung
- Automatisches Backup: Vor jeder Änderung
Workflow:
- Validiert SSH-Schlüssel-Format (good_keys und bad_keys)
- Überprüft
.ssh-Verzeichnis-Existenz (erstellt falls nötig) - Entfernt Schlüssel aus Blacklist (
bad_keys) - Fügt Schlüssel aus Whitelist (
good_keys) hinzu - Bereinigt Kommentare in authorized_keys
- Fügt Änderungs-Timestamp hinzu
Sicherheitsaspekte:
- ✅ Whitelisting-Ansatz (explizite Erlaubnis)
- ✅ Blacklisting für Revokation kompromittierter Schlüssel
- ✅ Automatische Bereinigung alter Einträge
- ✅ Audit-Trail durch Timestamps
- ✅ Validierung verhindert fehlerhafte Schlüssel
Rollen
Rolle: manage-ssh-keys
Zweck: Verwaltet SSH-Schlüssel mit Whitelisting und Blacklisting-Mechanismen für sicheren Systemzugriff.
Pfad: roles/manage-ssh-keys/
Hauptaufgaben:
1. validate-keys.yml
Stellt sicher, dass .ssh-Verzeichnis existiert und korrekte Berechtigungen hat.
Funktionen:
- Erstellt
.ssh-Verzeichnis (falls nicht vorhanden) - Setzt Berechtigungen:
0700(nur Owner kann lesen/schreiben/ausführen) - Erstellt
authorized_keys-Datei (falls nicht vorhanden) - Setzt Berechtigungen für
authorized_keys:0600
Ausgeführt für User:
ssh_user: "root" # Standard, kann überschrieben werden
2. add-goodkeys.yml
Fügt autorisierte SSH-Public-Keys hinzu.
Funktionen:
- Iteriert über
good_keys-Liste - Fügt jeden Schlüssel zu
authorized_keyshinzu - Verhindert Duplikate (idempotent)
- Verwendet
authorized_key-Modul von Ansible
Beispiel good_keys:
good_keys:
- "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIExampleKey1 admin@workstation"
- "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQC... admin@laptop"
3. remove-badkeys.yml
Entfernt nicht autorisierte oder kompromittierte Schlüssel.
Funktionen:
- Iteriert über
bad_keys-Liste - Entfernt jeden Schlüssel aus
authorized_keys - Verwendet
absent-State inauthorized_key-Modul - Sicher bei nicht vorhandenen Schlüsseln (idempotent)
Beispiel bad_keys:
bad_keys:
- "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC... old-compromised-key"
- "ssh-dss AAAAB3NzaC1kc3MAAACBAP... deprecated-dsa-key"
Standardvariablen (defaults/main.yml):
# User für SSH-Schlüsselverwaltung
ssh_user: "root"
# Pfad zu authorized_keys
authorized_keys_file: "/{{ ssh_user }}/.ssh/authorized_keys"
# Whitelist: Autorisierte SSH-Schlüssel (ca. 20+ Schlüssel)
good_keys:
- "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIExampleKey1"
- "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIExampleKey2"
- "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQC..."
# ... weitere autorisierte Schlüssel
# Blacklist: Zu entfernende Schlüssel (6+ revozierte Schlüssel)
bad_keys:
- "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC... old-key-1"
- "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQD... compromised-key"
# ... weitere zu entfernende Schlüssel
Handler:
| Handler | Funktion |
|---|---|
Cleanup Comments |
Entfernt alte Kommentare aus authorized_keys |
Add Comment |
Fügt Änderungs-Timestamp hinzu |
Verwendung in Playbooks:
# Vollständige Rolle
- name: Manage SSH Keys
hosts: all
become: true
roles:
- manage-ssh-keys
# Mit custom Variablen
- name: Manage SSH Keys for tincadmin user
hosts: all
become: true
roles:
- role: manage-ssh-keys
vars:
ssh_user: tincadmin
good_keys:
- "ssh-ed25519 AAAAC3... new-admin-key"
bad_keys:
- "ssh-rsa AAAAB3... old-admin-key"
# Einzelne Tasks
- name: Add authorized keys only
include_role:
name: manage-ssh-keys
tasks_from: add-goodkeys.yml
SSH-Schlüssel-Typen
Empfohlene Schlüsseltypen (2026)
| Typ | Sicherheit | Empfehlung | Verwendung in Projekt |
|---|---|---|---|
| Ed25519 | ⭐⭐⭐⭐⭐ Höchste | ✅ Bevorzugt | Ja (~15+ Schlüssel) |
| RSA 4096 | ⭐⭐⭐⭐ Hoch | ✅ Akzeptabel | Ja (~5+ Schlüssel) |
| ECDSA | ⭐⭐⭐ Mittel | ⚠️ Mäßig | Nicht im Projekt |
| RSA 2048 | ⭐⭐ Niedrig | ⚠️ Veraltet | Einige Legacy-Keys |
| DSA | ⭐ Sehr niedrig | ❌ Deprecated | Sollte entfernt werden |
Schlüssel-Generierung
Ed25519 (empfohlen):
ssh-keygen -t ed25519 -C "admin@workstation-$(date +%Y%m%d)"
RSA 4096:
ssh-keygen -t rsa -b 4096 -C "admin@workstation-$(date +%Y%m%d)"
Best Practices
1. Regelmäßiges Key-Rotation
Erneuern Sie SSH-Schlüssel regelmäßig:
# Quartalsweise
ansible-playbook playbooks/hardening/manage-ssh-keys.yaml \
-i inventories/icp-fra-pve1.yml \
-e '{"good_keys": [...neue Schlüssel...]}' \
-e '{"bad_keys": [...alte Schlüssel...]}' \
-K
2. Zentrale Schlüsselverwaltung
Pflegen Sie good_keys und bad_keys in:
roles/manage-ssh-keys/defaults/main.yml(Standard)- Externe Variablendateien für verschiedene Umgebungen
- Vault-Datei für sensible Schlüssel
3. Audit-Trail
Dokumentieren Sie Schlüssel-Änderungen:
# Vor Änderung: Backup erstellen
ansible all -i inventories/icp-fra-pve1.yml \
-m fetch \
-a "src=/root/.ssh/authorized_keys dest=/backup/ssh-keys/{{ inventory_hostname }}-{{ ansible_date_time.date }}" \
-b
# Änderung durchführen
ansible-playbook playbooks/hardening/manage-ssh-keys.yaml ...
# Verifizierung
ansible all -i inventories/icp-fra-pve1.yml \
-m shell -a "wc -l /root/.ssh/authorized_keys" \
-b
4. Kompromittierte Schlüssel sofort entfernen
Bei Sicherheitsvorfällen:
# Notfall-Entfernung kompromittierter Schlüssel
ansible-playbook playbooks/hardening/manage-ssh-keys.yaml \
-i inventories/all.yml \
-e '{"bad_keys": ["ssh-rsa AAAA... KOMPROMITTIERT"]}' \
-K
5. Test auf Non-Production zuerst
# Test auf einzelnem Host
ansible-playbook playbooks/hardening/manage-ssh-keys.yaml \
-i inventories/icp-fra-pve1.yml \
--limit test-host.example.com \
-e '{"good_keys": [...]}' \
-K
# Nach Verifizierung: Rollout
ansible-playbook playbooks/hardening/manage-ssh-keys.yaml \
-i inventories/icp-fra-pve1.yml \
-K
6. Mehrfache Admin-Keys
Verwenden Sie mehrere Admin-Schlüssel für Redundanz:
good_keys:
- "ssh-ed25519 ... primary-admin@workstation"
- "ssh-ed25519 ... secondary-admin@laptop"
- "ssh-ed25519 ... emergency-admin@spare"
SSH-Daemon-Härtung
Während dieses Playbook die Schlüssel verwaltet, sollten Sie auch SSH-Daemon-Konfiguration härten.
Empfohlene sshd_config-Einstellungen
# /etc/ssh/sshd_config
# Nur Public-Key-Authentifizierung
PubkeyAuthentication yes
PasswordAuthentication no
ChallengeResponseAuthentication no
# Kein Root-Login mit Passwort
PermitRootLogin prohibit-password
# Moderne Krypto-Algorithmen
KexAlgorithms curve25519-sha256,curve25519-sha256@libssh.org
Ciphers chacha20-poly1305@openssh.com,aes256-gcm@openssh.com,aes128-gcm@openssh.com
MACs hmac-sha2-512-etm@openssh.com,hmac-sha2-256-etm@openssh.com
# Weitere Härtungen
PermitEmptyPasswords no
X11Forwarding no
MaxAuthTries 3
LoginGraceTime 20
Anwendung mit Ansible
Siehe: system Rolle → ssh-hardening.yaml
# SSH-Daemon härten (falls implementiert in system Rolle)
ansible-playbook playbooks/hardening/harden-sshd.yml \
-i inventories/icp-fra-pve1.yml \
-K
Fehlerbehebung
Problem: Aussperrung nach Schlüssel-Entfernung
Symptome: Kein SSH-Zugriff mehr nach Ausführung
Prävention:
- Immer mindestens einen funktionierenden Schlüssel in
good_keysbehalten - Testen Sie auf einzelnem Host zuerst (
--limit) - Halten Sie Console-Zugriff bereit (z.B. Proxmox VNC)
Lösung bei Aussperrung:
- Zugriff über Console (Proxmox, IPMI, etc.)
- Manuelle Wiederherstellung:
# Via Console echo "ssh-ed25519 AAAA... emergency-key" >> /root/.ssh/authorized_keys - Führen Sie Playbook erneut aus mit korrekten Schlüsseln
Problem: Schlüssel werden nicht hinzugefügt
Symptome: good_keys werden nicht in authorized_keys eingetragen
Lösung:
- Überprüfen Sie Schlüssel-Format:
ssh-keygen -l -f /path/to/public_key.pub - Überprüfen Sie Berechtigungen:
ansible all -i inventories/... \ -m shell -a "ls -la /root/.ssh/" \ -b - Führen Sie validate-keys Task manuell aus:
- include_role: name: manage-ssh-keys tasks_from: validate-keys.yml
Problem: Handler werden nicht ausgeführt
Symptome: Timestamps oder Kommentare fehlen
Lösung:
- Handler laufen erst am Ende des Plays
- Erzwingen Sie Handler-Ausführung:
- meta: flush_handlers - Oder führen Sie Playbook mit
--force-handlersaus
Problem: Unterschiedliche Schlüssel pro Umgebung
Symptome: Dev/Prod benötigen verschiedene Schlüssel-Sets
Lösung: Verwenden Sie separate Variablendateien:
# Development
ansible-playbook playbooks/hardening/manage-ssh-keys.yaml \
-i inventories/dev.yml \
-e "@vars/ssh-keys-dev.yml" \
-K
# Production
ansible-playbook playbooks/hardening/manage-ssh-keys.yaml \
-i inventories/prod.yml \
-e "@vars/ssh-keys-prod.yml" \
-K
vars/ssh-keys-prod.yml:
good_keys:
- "ssh-ed25519 ... prod-admin-1"
- "ssh-ed25519 ... prod-admin-2"
bad_keys:
- "ssh-rsa ... old-dev-key"
Compliance und Audit
DSGVO / Datenschutz
SSH-Schlüssel-Management unterstützt Compliance durch:
- ✅ Access Control: Nur autorisierte Personen
- ✅ Audit Trail: Timestamps in authorized_keys
- ✅ Revocation: Schnelle Entfernung kompromittierter Keys
- ✅ Least Privilege: Spezifische User-Zuordnung
Audit-Kommandos
# Liste aller autorisierten Schlüssel
ansible all -i inventories/icp-fra-pve1.yml \
-m shell -a "cat /root/.ssh/authorized_keys" \
-b
# Zähle Schlüssel pro Host
ansible all -i inventories/icp-fra-pve1.yml \
-m shell -a "wc -l /root/.ssh/authorized_keys" \
-b
# Prüfe auf DSA-Schlüssel (veraltet)
ansible all -i inventories/icp-fra-pve1.yml \
-m shell -a "grep 'ssh-dss' /root/.ssh/authorized_keys || echo 'None found'" \
-b
# Letzte Änderung
ansible all -i inventories/icp-fra-pve1.yml \
-m stat -a "path=/root/.ssh/authorized_keys" \
-b
Weitere Sicherheits-Maßnahmen
Neben SSH-Schlüssel-Verwaltung gibt es weitere Härtungs-Maßnahmen im Projekt:
1. Fail2Ban (nicht implementiert)
Schutz vor Brute-Force-Attacken
2. UFW/Firewall (nicht implementiert)
Netzwerk-Level-Zugriffsschutz
3. Sudo-Beschränkungen
Siehe system Rolle für zukünftige Implementierung
4. SELinux/AppArmor
OS-Level Mandatory Access Control
Nützliche Kommandos
SSH-Schlüssel-Informationen abrufen
# Alle Schlüssel auf Hosts anzeigen
ansible all -i inventories/icp-fra-pve1.yml \
-m shell \
-a "cat /root/.ssh/authorized_keys | grep -v '^#' | while read line; do echo \$line | ssh-keygen -l -f - 2>/dev/null || echo 'Invalid: '\$line; done" \
-b
# Schlüssel-Typen zählen
ansible all -i inventories/icp-fra-pve1.yml \
-m shell \
-a "cat /root/.ssh/authorized_keys | grep -v '^#' | awk '{print \$1}' | sort | uniq -c" \
-b
Backup erstellen
# Backup aller authorized_keys Dateien
ansible all -i inventories/icp-fra-pve1.yml \
-m fetch \
-a "src=/root/.ssh/authorized_keys dest=/backup/ssh-keys/{{ inventory_hostname }}-{{ ansible_date_time.date }}/" \
-b
Navigation: ← Zurück: Mail-Server-Verwaltung | Nächstes: Virtualisierung →