4 Minuten Lesezeit (885 Worte)

SSH Key Signing

Wer kennt sie nicht, die Abfrage nach der Vertrauenswürdigkeit bei dem initialen Verbindungsaufbau einer SSH-Verbindung?. Da sie oft ohne weitere Überprüfung bestätigt wird, deaktivieren allerdings keine Lösung ist, soll dieser Artikel mögliche Alternativen aufzeigen. 

me@debian:~$ ssh admin@prod01
The authenticity of host 'prod01 (192.0.2.80)' can't be established.
ED25519 key fingerprint is SHA256:w4NP+4cCeN01TuK/rXVMzCcKBRPoVg++MNpCRZJTRNM.
This key is not known by any other names.
Are you sure you want to continue connecting (yes/no/[fingerprint])? 

Einleitung

Die Authentifizierung von Nutzern und Systemen ist ein elementarer Bestandteil der IT-Security. In unserem Beispiel: Verbinde ich mich gerade mit dem gewünschten System oder bin ich z. B. Opfer eines Man-in-the-Middle-Angriffs geworden? Es muss nicht gleich ein Angriff sein, vielleicht wurde in der Zwischenzeit die IP-Adresse neu vergeben o. Ä.

Für den Verlauf eines Login-Versuch kann bei SSH zwischen drei Möglichkeiten unterschieden werden:

  1. Der SSH-Client kennt den öffentlichen Schlüssel des Zielsystems bereits, kann das System verifizieren und baut eine Verbindung auf.
  2. Der bekannte öffentliche Schlüssel stimmt nicht mit dem privaten Schlüssel des Systems überein. Der Aufbau der Verbindung wird vom SSH-Client abgelehnt und der Nutzer bekommt eine entsprechende Warnung angezeigt.
  3. Der Schlüssel ist noch nicht bekannt und muss dem SSH-Client bekannt gemacht werden. Bei SSH erfolgt dies in der Regel unter dem Prinzip "Trust on first use".

Trust on first use

Bei "Trust on first use" wird bei der ersten Nutzung eines Schlüssels (bzw. beim erstmaligen Verbindungsaufbau) davon ausgegangen, dass dem Zielsystem vertraut werden kann, es sich also um das gewünschte System handelt. Bei SSH wird dem Nutzer hierbei der Fingerprint des öffentlichen Schlüssels angezeigt und um Bestätigung gebeten. Anschließend wird der Schlüssel für zukünftige Verbindungen abgespeichert.

Hier ergibt sich allerdings die Möglichkeit eines Man-in-the-Middle-Angriffs, indem die Verbindung bereits auf das System eines Angreifers umgeleitet wird und der Nutzer den Schlüssel nicht prüft. Und – seien wir mal ehrlich – wer überprüft schon den kryptisch aussehenden öffentlichen Schlüssel oder den Fingerprint, bevor die Abfrage mit „yes" bestätigt wird? Zudem könnte man als Administrator vieler Systeme dazu tendieren, die manuelle Bestätigung zu deaktivieren oder in Test-Umgebungen die Überprüfung ganz abzuschalten, wenn sich die Schlüssel häufig ändern. Dies macht die SSH-Logins zwar bequemer, von Letzterem ist aus Sicherheitsgründen allerdings dringend abzuraten.

Öffentliche Schlüssel für alle

Abhilfe kann man schaffen, wenn man die öffentlichen Schlüssel aller Systeme zentral sammelt und an die möglichen Clients verteilt. Somit entfällt die initiale Bestätigung, da der Schlüssel bereits bekannt ist. Mit Tools wie Ansible oder Puppet lässt sich dies zudem gut automatisieren.

In überschaubaren und klar abgegrenzten Umgebungen ist diese Art der Schlüssel-Verteilung umsetzbar. Bei komplexeren Umgebungen mit Aufteilung in Produktion, Test und Entwicklung oder spätestens bei extern bereitgestellten Systemen kann das anders aussehen. Hier stellen sich dem Administrator Fragen wie: Dürfen die Schlüssel automatisiert aus der Test-Umgebung in die Produktiv-Umgebung übertragen werden, um sie dort auf den Clients abzulegen? Wie bekomme ich die aktualisierten Schlüssel der externen Systeme vom jeweiligen Dienstleister?

Signaturen als Lösung

Die Lösung für das Problem können Signaturen und Zertifikate sein. Beim Surfen im Web sind HTTPS-verschlüsselte Webseiten mit verifizierten TLS/SSL-Zertifikaten heutzutage bereits die Regel. Nur noch selten kommt es zu Meldungen über nicht vertrauenswürdigen Webseiten. Dies ist in ähnlicher Form auch bei SSH möglich. 

Als Basis benötigt man eine CA (Certificate Authority), mit welcher dann die SSH-Host-Keys der Server signiert werden. Das dabei entstandene Zertifikat wird auf dem jeweiligen Server abgelegt und in der Konfiguration des SSH-Daemons eingetragen. Zusätzlich muss die CA noch den SSH-Clients bekannt gemacht werden, da es hier keine zentrale Stelle wie bei TLS gibt. Dies geschieht, ähnlich wie beim Verteilen der öffentlichen Schlüssel, durch einen Eintrag in der Known-Hosts-Datei. Der Vorteil der CA ist allerdings, dass der Eintrag nur einmalig pro CA und nicht pro Host vorgenommen werden muss.

Code-Beispiel

# [CA] CA Key erstellen
ssh-keygen \
    -t rsa -b 4096 \		        	# Schlüssel Typ+Länge
    -f ca_production \		        	# Schlüssel Datei
    –C 'CA Production'		        	# Kommentar

# [Remote->CA] Host-Key auf CA Server kopieren
scp root@prod01:/etc/ssh/ssh_host_rsa_key.pub ./prod01_rsa_key.pub

# [CA] Host Key signieren
ssh-keygen \
    -I host_prod01_rsa \	        	# Identifier
    -s ./ca_production \	        	# CA
    -h \					        	# Signieren von Host-Keys
    -n prod01,prod01.example.com \	    # Host,FQDN,…
    -V +365d \					        # Gültigkeitszeitraum
    [-z 000123] \			        	# Seriennummer
    ./prod01_rsa_key.pub \	        	# Zu signierender Schlüssel

# [CA->Remote] Signatur auf dem Ziel ablegen
scp ./prod01_rsa_key-cert.pub root@prod01:/etc/ssh/ssh_host_rsa_key-cert.pub

# [Remote] SSHD Konfiguration anpassen
root@prod01$ echo 'HostCertificate /etc/ssh/ssh_host_rsa_key-cert.pub' >> /etc/ssh/sshd_config

# [Remote] Dienst neustarten
root@prod01$ systemctl restart sshd

# [Lokal] Known-Hosts Datei anpassen ~/.ssh/known/hosts oder /etc/ssh/ssh_known_hosts
@cert-authority *.example.com ssh-rsa AAAABCD... CA Production

# [Lokal->Remote] Login testen
ssh admin@prod01 

Fazit

Durch die Signatur der SSH Keys entfällt das lästige Überprüfen der SSH-Schlüssel beim initialen Verbindungsaufbau. Zudem wird die Sicherheit erhöht, da die Wahrscheinlichkeit von erfolgreichen Man-in-the-Middle Angriffen auf die SSH-Verbindungen reduziert wird. Einen zusätzlichen Mehrwert kann die Kombination mit Automatisierungstools, wie z. B. Ansible, bieten, die ein manuelles Hantieren mit den Schlüsseln überflüssig macht.

Weiterführende Themen, die in diesem Artikel nicht behandelt wurden, sind das Signieren von User-Keys als Alternative zur Pflege der authorized_keys-Datei so wie das Nutzen einer Revocation-Liste, um bereits ausgestellte Zertifikate für ungültig zu erklären.

Eine alternative zur Verifikation der Host-Keys kann durch SSHFP Einträge im DNS erreicht werden.

Möchten Sie Ihre Server noch weitergehend absichern? Dann sprechen Sie uns an oder besuchen Sie unser Seminar "Linux Serverhärtung und Security Testing"!

Seminarempfehlung

 

Kommentare

Derzeit gibt es keine Kommentare. Schreibe den ersten Kommentar!
Sonntag, 17. November 2024

Sicherheitscode (Captcha)

×
Informiert bleiben!

Bei Updates im Blog, informieren wir per E-Mail.

Weitere Artikel in der Kategorie