Zum Inhalt springen

SSH/Hostkey: Unterschied zwischen den Versionen

Aus Foxwiki
K Textersetzung - „wikitable“ durch „table table-striped table-hover“
 
(53 dazwischenliegende Versionen desselben Benutzers werden nicht angezeigt)
Zeile 1: Zeile 1:
== SSH Host Keys ==
'''SSH/Hostkey''' - Identifikation eines SSH-Servers
; SSH Host Keys - nervig oder sinnvoll?
 
== Beschreibung ==
; SSH-Host-Keys identifizieren einen SSH-Server eindeutig
Bei der ersten Verbindung zu einem Server per SSH bekommt man eine Meldung wie diese:
Bei der ersten Verbindung zu einem Server per SSH bekommt man eine Meldung wie diese:
  The authenticity of host ‚www.example.com (192.168.12.34)‘ can’t be established.
  The authenticity of host ‚www.example.com (192.168.12.34)‘ can’t be established.
  ECDSA key fingerprint is SHA256:86RDANuVFu5w3OF4RuFW04jqMfVbahR/sk4Yr/ElLI0.
  ECDSA key fingerprint is SHA256:86RDANuVFu5w3OF4RuFW04jqMfVbahR/sk4Yr/ElLI0.
  Are you sure you want to continue connecting (yes/no)?
  Are you sure you want to continue connecting (yes/no)?


Die man dann nach dem klassischen Schema Ja/Nein/Weiss nicht/Hab Angst beantworten kann.
; Server identifizieren
* Was genau ist der Sinn dieser SSH Host Keys und der oben gestellten Frage?
Beim ersten Verbindungsaufbau Fingerprint des Host-Keys überprüfen
 
; Fingerprint vergleichen
Sicherstellen, dass man mit dem richtigen Server verbunden ist
* und nicht (von einem Angreifer) auf eine andere Maschine umgeleitet wurde


=== Server identifizieren ===
Hat man den Key verglichen oder ist man sich zumindest sehr sicher, dass man sich mit dem richtigen Server verbunden hat, kann man die oben stehende Frage mit "yes" beantworten
; SSH Host Keys sind dafür da um den Host auf dem der SSH Server läuft eindeutig zu identifizieren
Im Idealfall würde man beim ersten Verbindungsaufbau den Fingerprint des Host Keys überprüfen, also beispielsweise: mit dem Administrator des Servers den Fingerprint per Telefon vergleichen.
* Dadurch wäre dann sichergestellt dass man sich mit dem richtigen Server verbunden hat und man nicht von einem Angreifer auf eine andere Maschine umgeleitet wurde.
* Hat man den Key verglichen oder ist man sich zumindest sehr sicher dass man sich mit dem richtigen Server verbunden hat kann man oben stehende Frage mit "yes" beantworten.
* Der Key wird dann vom Client gespeichert und bei weiteren Verbindungen nur noch verglichen und nicht mehr gefragt.
* Der Key wird dann vom Client gespeichert und bei weiteren Verbindungen nur noch verglichen und nicht mehr gefragt.


Sollte im laufenden Betrieb dann doch mal eine Meldung wie die folgende kommen, gibt es Handlungsbedarf.
; Handlungsbedarf
 
Sollte im laufenden Betrieb dann doch mal eine Meldung wie die folgende kommen, gibt es Handlungsbedarf
<syntaxhighlight lang="bash" highlight="">
  @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
  @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
  @ WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED! @
  @ WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED! @
Zeile 25: Zeile 27:
  Someone could be eavesdropping on you right now (man-in-the-middle attack)!
  Someone could be eavesdropping on you right now (man-in-the-middle attack)!
  It is also possible that a host key has just been changed.
  It is also possible that a host key has just been changed.
</syntaxhighlight>


==== Variante 1 ====
<blockquote>
Der Server wurde neu aufgesetzt (oder zumindest der SSH-Key neu generiert), in diesem Fall den Key aus der Datei ~/.ssh/known_hosts entfernen und wie bei einem erstmaligen Verbindungsaufbau verfahren.
; Variante 1
 
* Der Server wurde neu aufgesetzt (oder zumindest der SSH-Key neu generiert)
==== Variante 2 ====
* in diesem Fall den Key aus der Datei ~/.ssh/known_hosts entfernen und wie bei einem erstmaligen Verbindungsaufbau verfahren
Man hat sich auf einen Namen oder eine IP verbunden die nicht eindeutig einem Server zuzuordnen ist, und durch Cluster-Failover, Load Balancing oder ähnliches landet man jetzt auf einem anderen Server.
* Hier in Zukunft wenn möglich auf eindeutige Namen bzw.&nbsp;IPs verbinden.
 
==== Variante 3 ====
Man ist gerade Opfer einer Man-in-the-middle Attacke geworden und ein Angreifer versucht den SSH-Verkehr auf einen anderen Server umzuleiten.
 
SSH Keys mögen zwar nervig erscheinen aber wenn man nicht selbst grob fahrlässig agiert können sie einen vor Angriffen auf die Verbindung bewahren.
 
== SSH Host Key Signing - ein unterschätztes Feature ==
Da wir eine größere Menge an Linux Servern betreiben, ist SSH unser tägliches Brot.
* Sei es nun für den Login mit dem eigenen Benutzer oder für auf SSH aufsetzende Automatisierungen, wie zum Beispiel Ansible.
* Was nun jeder SSH Anwender aber kennt: der ewige "Kampf" mit der ''known_hosts'' Datei, in der alle dem Clients bereits bekannten Public SSH Host Keys abgelegt werden.
* Wenn sie noch nicht dort liegen, stolpert man über eine interaktive Nachfrage (der Feind jeglicher Automatisierung) und wenn das Ziel zum Beispiel neu aufgesetzt wurde, gibt es sogar einen Konflikt, der eher umständlich aufgelöst werden muss.
* Im Falle von Ansible Playbooks oder Git Operationen kann das bedeuten, dass Befehle unerwartet abbrechen, mit Rückfragen stehen bleiben oder aber einfach in einen Timeout laufen, weil die Rückfrage gar nicht bis zum Benutzer durchkommt.
* Dann ist da auch noch die Frage, in welcher Form ein "conflicting" Public Host Key in der ''known_hosts'' hinterlegt ist: mit einer IP Adresse, einem Hostnamen oder einem Hash davon als Identifier? Für einfache Aufräumarbeiten gibt die entsprechende Fehlermeldung des ssh Clients immerhin direkt das passende, copy/paste-bare Kommando (''ssh-keygen -R […]'') mit aus.
 
Für das Problem gibt es verschiedene Lösungen, die sich grob in "The Good" (zum Beispiel SSH Host Key Signing), "The Bad" (''known_hosts'' Management) und "The Ugly" (Host Key Checking abschalten?!) einteilen lassen.
* Die letzte Variante ignorieren wir hier einmal, weil das für uns schlicht keine Option ist.
 
==== "managed" known_hosts ====
Bevor wir SSH Host Key Signing entdeckt haben, hat Ansible uns in Teilen geholfen.
* Beim initialen Setup eines Servers haben wir über ''delegate_to'' Tasks dafür gesorgt, dass auf bestimmten, für Configuration Management/Deployment relevanten Systemen, die ''known_hosts'' Dateien einiger Benutzer um die Public Host Keys des neuen Servers erweitert wurden.
* Das funktioniert allerdings immer nur so lange automatisch, bis ein Server mal neu aufgesetzt wird und dann am Ende zwei Keys für das gleiche Ziel in der ''known_hosts'' landen - schon musste wieder händisch eingegriffen wird.
* Bevor wir die vorhandene Lösung noch komplizierter machen mussten, sind wir zum Glück über das folgende Thema gestolpert:
 
==== SSH Host Key Signing ====
OpenSSH beherrscht seit ca. 2010 ein Verfahren, um SSH Host Keys mit einer CA zu signieren.
* Es handelt sich dabei aber nicht um eine x509 CA, sondern um eine eigene Implementierung - sämtliche Interaktionen erfolgen über das Tool ''ssh-keygen''.
 
Insgesamt sind folgende Schritte nötig, um an das Ziel zu gelangen:# SSH CA erzeugen
# Neuen Server aufsetzen, Public Host Key(s) zur CA transferieren und signieren
# Signierte Public Key(s) auf neues System legen, in SSHD Konfiguration aktivieren
# Public Key der SSH CA in allen ''known_host'' Dateien (beispielsweise systemweit) hinterlegen
 
Die Schritte 2.&nbsp;und 3.&nbsp;sind für jeden neuen Server zu wiederholen und lassen sich relativ leicht mit Ansible automatisieren.
 
==== SSH CA erzeugen ====
Die CA kann auf einem beliebigen aktuellen Linux System erzeugt/betrieben werden - spezielle Anforderungen gibt es nicht.
* Da auf diesem System allerdings der Private Key der CA liegt, sollte es natürlich nicht gerade der öffentlich erreichbare Webserver sein, sondern schon ein dedizierter und entsprechend abgeschotteter Server.
* Seit OpenSSH 5.5 kann eine CA allerdings auch über PKCS#11 abgerufen werden - und damit zum Beispiel in einem Hardware Security Module (HSM) liegen.
* Dieser Blogpost beleuchtet aber die einfache Variante mit einer CA im Dateisystem.
 
Hier erzeugen wir nun unsere CA:
 
mkdir /etc/ssh-ca && cd /etc/ssh-ca
ssh-keygen -f server_ca


Jetzt signen wir damit zuerst mal den Public Host Key unseres CA Servers, dazu benötigen wir den Fully Qualified Domain Name des Servers in unserer ''$FQDN'' Variable und den Hostnamen (ohne Domain) in der Variable ''$HOSTNAME'':
; Variante 2
* Man hat sich auf einen Namen oder eine IP verbunden, die nicht eindeutig einem Server zuzuordnen ist, und durch Cluster-Failover, Load Balancing oder Ähnliches landet man jetzt auf einem anderen Server.
* Hier in Zukunft, wenn möglich, auf eindeutigen Namen bzw.&nbsp;IPs verbinden.


ssh-keygen -s server_ca -I ${FQDN}-host-key -h -n ${FQDN},${HOSTNAME} -V +52w /etc/ssh/ssh_host_ecdsa_key.pub
; Variante 3
* Man ist gerade Opfer einer Man-in-the-middle-Attacke geworden und ein Angreifer versucht, den SSH-Verkehr auf einen anderen Server umzuleiten.
* SSH Keys mögen zwar nervig erscheinen, aber wenn man nicht selbst grob fahrlässig agiert, können sie einen vor Angriffen auf die Verbindung bewahren.
</blockquote>


Durch den Parameter ''-V +150w'' geben wir an, dass das Zertifikat für 52 Wochen gültig sein soll, über ''-n'' wird mitgegeben, für welche(n) Hostnamen das Zertifikat gelten soll (hier nehmen wir mal den Fully Qualified Domain Namen sowie den kurzen Hostnamen an).
== SSH-Fingerprint prüfen ==
Prüfung der Authentizität eines [[SSH/Server]]


Der Vorgang erzeugt ein Host Zertifikat (oder auch genannt: ein signierter Public Key) in ''/etc/ssh/ssh_host_ecdsa_key-cert.pub''.
<blockquote>
* Dieses Zertifikat müssen wir jetzt noch dem SSHD in der ''/etc/ssh/sshd_config'' beibringen und ihn danach neustarten:
Wichtig, bei Erstverbindungen!
</blockquote>


HostCertificate /etc/ssh/ssh_host_ecdsa_key-cert.pub
; SSH-Verbindungen sind bei der ersten Verbindung am meisten verwundbar
Nachdem Sie zum ersten Mal eine Verbindung zu einem Server hergestellt haben, speichert der SSH-Client seinen Fingerabdruck


Wer neben ECDSA auch noch andere Host Key Varianten aktiviert hat, muss den Vorgang für diese Keys auch wiederholen (oder sie deaktivieren).
Wenn Sie sich zum ersten Mal mit einem Server verbinden
war Ihr Client nicht in der Lage, seinen Fingerabdruck zu protokollieren und zu überprüfen, ob er korrekt ist
* Daher kann ein Angreifer erfolgreich einen Man-in-the-Middle-Angriff durchführen
* Die einzige Möglichkeit, um sicherzustellen, dass Sie sich von Anfang an mit dem richtigen Server verbinden, besteht darin, den Fingerabdruck Ihres SSH-Schlüssels manuell zu überprüfen


==== Public Keys eines neuen Servers signieren ====
Wenn sich dieser Fingerabdruck ändert
Um nun die Host Keys eines neuen Servers zu signieren, greifen wir auf einige Schritte von weiter oben zurück.
* weil jemand versucht, Sie mit einem bösartigen Server zu verbinden,  
* Wir kopieren den Public ECDSA Host Key (''/etc/ssh/ssh_host_ecdsa_key.pub'') auf unser SSH CA System, zum Beispiel nach ''/etc/ssh-ca/ssh_host_ecsd_key.pub''.
* wird Ihr SSH-Client Sie warnen, dass sich der Fingerabdruck geändert hat
* Anschließend führen wir den Sign-Befehl aus (auch hier benötigen wir wieder die beiden Variablen ''$FQDN'' und'' $HOSTNAME'', nur dieses Mal bezogen auf das System, von dem der Key stammt):


ssh-keygen -s server_ca -I ${FQDN}-host-key -h -n ${FQDN},${HOSTNAME}
; Fingerabdruck eines SSH-Schlüssels überprüfen
-V +52w /etc/ssh-ca/ssh_host_ecdsa_key.pub
Bevor Sie Ihren Fingerabdruck überprüfen können, müssen Sie den dafür verwendeten Algorithmus kennen


Das Ergebnis wird in ''/etc/ssh-ca/ssh_host_ecdsa_key-cert.pub'' liegen und kann zum Server zurück transferiert werden.
Dieser sollte aus dem Inhalt Ihrer Nachricht hervorgehen
* Dort müssen wir es noch in der ''/etc/ssh/sshd_config'' aktivieren und den Dienst neustarten:
<syntaxhighlight lang="bash" highlight="">
Die Authentizität des Hosts '172.86.75.163 (172.86.75.163)' kann nicht festgestellt werden. ED25519 key fingerprint is SHA256:NTw36MQjDxsHlxC/Xso5yKMlKJu93uYknRx2LEaqk7I. This key is not known by any other names. Sind Sie sicher, dass Sie die Verbindung fortsetzen möchten (ja/nein/[fingerprint])?
</syntaxhighlight>


HostCertificate /etc/ssh/ssh_host_ecdsa_key-cert.pub
Sie können sehen, dass unser Schlüssel den Algorithmus '''ED25519''' verwendet und mit '''SHA256''' gehasht wird
* Sie sollten sich dies notieren, ebenso wie den Fingerabdruck selbst, in diesem Fall
<code>NTw36MQjDxsHlxC/Xso5yKMlKJu93uYknRx2LEaqk7I</code>


Auch hier gilt: wenn mehr als eine Art von SSH Host Key benutzt wird (beispielsweise RSA), sollte man die Schritte für alle Keys wiederholen oder sie deaktivieren.
Ihr Schlüsselalgorithmus könnte auch ECDSA, RSA und DSA sein, und Ihr Hashing-Algorithmus könnte MD5 statt SHA sein


==== Und die Clients? ====
; Überprüfen des Fingerabdrucks auf dem Server
Jedes System, welches nun als SSH Client agieren soll, benötigt Zugriff auf die SSH-CA - dies geschieht auch über die known_hosts.
Loggen Sie sich über eine vertrauenswürdige Methode in Ihren Server ein
* Um das Deployment zu vereinfachen, kann man einfach eine systemweite ''known_hosts'' in ''/etc/ssh/ssh_known_hosts'' pflegen.
* Der Inhalt setzt sich aus zwei Teilen zusammen:# Dem Prefix ''@cert-authority'' und einem Matcher auf einen Hostnamen (Wildcards sind möglich, wie in der ssh_config) - ein einzelnes "*" tuts auch, um die CA für sämtliche Clients anzuwenden
# Der Public Key unserer CA, der im SSH-CA Ordner unter dem Namen ''server_ca.pub'' erzeugt wurde


Das fertige Ergebnis könnte dann so aussehen:
Führen Sie den Befehl ssh-keygen aus, um den Fingerabdruck Ihres Schlüssels auszulesen
; SHA256
<syntaxhighlight lang="bash" highlight="1" line copy>
ssh-keygen -lf [Datei]]
</syntaxhighlight>


@cert-authority * ssh-rsa AAAADje9fnekjsld[...]
; MD5
<syntaxhighlight lang="bash" highlight="1" line copy>
ssh-keygen -E md5 -lf [Datei]
</syntaxhighlight>


==== Das wars schon? ====
{| class="table table-striped table-hover options big"
Tatsächlich ist das schon im großen und ganzen alles, was für eine SSH CA/SSH Host Key Signing notwendig ist.
|-
* Es gibt natürlich auch andere Wege (beispielsweise über ein zentrales LDAP System).
! Algorithmus !! Datei
* Wenn man diese Komplexität allerdings scheut, kommt man über die SSH CA sicherlich schneller zum Ziel - und alles ist besser, als Host Key Checking einfach zu deaktivieren, weil es an der Automatisierung hindert.
|-
| [[ED25519]] || /etc/ssh/ssh_host_ed25519_key.pub
|-
| [[ECDSA]] || /etc/ssh/ssh_host_ecdsa_key.pub
|-
| [[RSA]] || /etc/ssh/ssh_host_rsa_key.pub
|-
| [[DSA]] || /etc/ssh/ssh_host_dsa_key.pub
|}


==== Gültigkeit von Zertifikaten ====
; Beispiel
Wie bei allen Dingen mit einer endlichen Gültigkeit: man möchte natürlich seine SSH Zertifikate regelmäßig erneuern und/oder auf ihre Gültigkeit überwachen.
<syntaxhighlight lang="bash" highlight="1" line copy>
* Wenn man das nicht tut, resultiert das zwar unseren Tests nach per Default nur in einer Warnung beim Login, sauber ist das allerdings nicht.
ssh-keygen -lf /etc/ssh/ssh_host_ed25519_key.pub
256 SHA256:NTw36MQjDxsHlxC/Xso5yKMlKJu93uYknRx2LEaqk7I root@6311ad8b487e6f00018c5cd1 (ED25519)
</syntaxhighlight>


==== Kann ich ein Zertifikat zurückziehen? ====
<blockquote>
Wer Keys signed bzw.&nbsp;Zertifikate ausstellt, möchte diese eventuell auch wieder zurückziehen.
'''Stellen Sie keine Verbindung zum Server her!'''</br>
* Die bei OpenSSH KRL genannte "Key Revocation List" muss auf der SSH-CA gepflegt (mehr Details dazu in der Manpage von ''ssh-keygen'') und auf alle Clients verteilt werden.
Wenn die Ausgabe nicht mit dem Fingerabdruck übereinstimmt, den Sie zuvor notiert haben
* Auf den Clients kann man sie über die Direktive RevokedHostKeys in der ''/etc/ssh/ssh_config'' systemweit aktivieren.
</blockquote>


==== Wird jetzt alles gut? ====
<noinclude>
Insgesamt kann man mit diesem Schritt Deployments/Config Management via SSH (lies: Ansible) deutlich stabiler machen.
* Das gleicht allerdings nicht zwingend andere Schwächen aus, die Mika Prokop hier jüngst mal zusammengestellt hat.


== ssh-Host-Keys erneuern ==
== Host-Keys erneuern ==
ssh-Server verfügen über einen Satz von Host-Keys, mit denen sich der Server gegenüber den Clients identifizieren kann.
ssh-Server verfügen über einen Satz von Host-Keys, mit denen sich der Server gegenüber den Clients identifizieren kann.
* Nach dem ersten erfolgreichen Verbindungsaufbau legt der ssh-Client den Host-Key des Servers in der Datei <tt>~/.ssh/knownhosts</tt> ab.
* Nach dem ersten erfolgreichen Verbindungsaufbau legt der ssh-Client den Host-Key des Servers in der Datei <tt>~/.ssh/knownhosts</tt> ab.
Zeile 148: Zeile 131:
* Sofern man einen neuen, zusätzlichen Server aufbaut, dann sollte dieser Server einen neuen Satz mit eigenen einmaligen ssh-Host-Key erhalten.
* Sofern man einen neuen, zusätzlichen Server aufbaut, dann sollte dieser Server einen neuen Satz mit eigenen einmaligen ssh-Host-Key erhalten.


=== Keys ersetzen ===
; How to change a SSH host key?
# In manchen Quellen wird für das Generieren der neuen Keys der Befehl <tt>dpkg-reconfigure openssh-server</tt> verwendet, der das Software-Paket für den ''OpenSSH''-Server neu konfiguriert.
#* Es sollte jedoch ein <tt>ssh-keygen -A</tt> ausreichen, der den Satz ssh-Host-Keys um die fehlenden Typen ergänzt.
Die erste Variante setzt voraus, dass ein ''OpenSSH''-Server verwendet wird, während die zweite Variante allgemeingültig sein sollte.
# Der ssh-Client gibt in den Warnungen die entsprechende Zeilennummer aus.
 
== Keys ersetzen ==
Zum Erneuern der ssh-Host-Keys löscht man auf dem Server zunächst die bestehenden Host-Keys und generiert einen Satz neue Keys1):
Zum Erneuern der ssh-Host-Keys löscht man auf dem Server zunächst die bestehenden Host-Keys und generiert einen Satz neue Keys1):
<syntaxhighlight lang="bash" highlight="1" line copy>
cd /etc/ssh
sudo rm ssh_host_*
sudo ssh-keygen -A
</syntaxhighlight>


cd /etc/ssh
== Änderungen auf den Clients ==
sudo rm ssh_host_*
sudo ssh-keygen -A
 
=== Änderungen auf die Clients ===
Sofern für den ssh-Server bereits der alte ssh-Host-Key auf einem Client gespeichert ist, kann die <tt>~/.ssh/knownhosts</tt> mit dem folgenden Befehl bereinigt werden:
Sofern für den ssh-Server bereits der alte ssh-Host-Key auf einem Client gespeichert ist, kann die <tt>~/.ssh/knownhosts</tt> mit dem folgenden Befehl bereinigt werden:
 
<syntaxhighlight lang="bash" highlight="1" line copy>
  ssh-keygen -R remote-server-name
  ssh-keygen -R remote-server-name
</syntaxhighlight>


Alternativ kann in der <tt>~/.ssh/knownhosts</tt> der Eintrag auch mit einem Texteditor entfernt werden2).
Alternativ kann in der <tt>~/.ssh/knownhosts</tt> der Eintrag auch mit einem Texteditor entfernt werden2).


Beim ssh-Client ''Blink'' (iOS) funktionieren die obigen beiden Lösungen nicht.
Beim ssh-Client ''Blink'' (iOS) funktionieren die obigen beiden Lösungen nicht
* Hier ist der folgende Workaround notwendig:
 
In das Verzeichnis <tt>.ssh</tt> wechseln:


Hier ist der folgende Workaround notwendig
: In das Verzeichnis <tt>.ssh</tt> wechseln
<syntaxhighlight lang="bash" highlight="1" line copy>
  cd ~/.ssh
  cd ~/.ssh
</syntaxhighlight>


Inhalt der Datei <tt>known_hosts</tt> mit Zeilennummern anzeigen:
Inhalt der Datei <tt>known_hosts</tt> mit Zeilennummern anzeigen
 
<syntaxhighlight lang="bash" highlight="1" line copy>
  cat -n known_hosts
  cat -n known_hosts
</syntaxhighlight>


Entsprechende Zeile merken und mit <tt>sed</tt> löschen (im Beispiel Zeile 99):
Entsprechende Zeile merken und mit <tt>sed</tt> löschen (im Beispiel Zeile 99)
 
<syntaxhighlight lang="bash" highlight="1" line copy>
  sed -i.bak '99d' known_hosts
  sed -i.bak '99d' known_hosts
</syntaxhighlight>


=== Quellen ===
== Konfiguration ==
* cyberciti.biz: How To: Ubuntu / Debian Linux Regenerate OpenSSH Host Keys
=== Dateien ===
* serverfault: How to change a SSH host key?
{| class="table table-striped table-hover options big"
|-
! Datei !! Beschreibung
|-
| ||
|-
| ||
|}


1)
<noinclude>


In manchen Quellen wird für das Generieren der neuen Keys der Befehl <tt>dpkg-reconfigure openssh-server</tt> verwendet, der das Software-Paket für den ''OpenSSH''-Server neu konfiguriert.
== Anhang ==
* Es sollte jedoch ein <tt>ssh-keygen -A</tt> ausreichen, der den Satz ssh-Host-Keys um die fehlenden Typen ergänzt.Die erste Variante setzt voraus, dass ein ''OpenSSH''-Server verwendet wird, während die zweite Variante allgemeingültig sein sollte.
=== Siehe auch ===
<div style="column-count:2">
<categorytree hideroot=on mode="pages">{{BASEPAGENAME}}</categorytree>
</div>
----
{{Special:PrefixIndex/{{BASEPAGENAME}}/}}


2)
=== Dokumentation ===
 
<!--
Der ssh-Client gibt in den Warnungen die entsprechende Zeilennummer aus.
; Man-Page
# [https://manpages.debian.org/stable/procps/pgrep.1.de.html prep(1)]
; Info-Pages
-->


=== Links ===
==== Projekt ====
==== Weblinks ====


[[Kategorie:SSH]]
[[Kategorie:SSH]]
[[Kategorie:Kryptologie]]
[[Kategorie:Kryptologie]]
</noinclude>

Aktuelle Version vom 29. Juli 2026, 11:02 Uhr

SSH/Hostkey - Identifikation eines SSH-Servers

Beschreibung

SSH-Host-Keys identifizieren einen SSH-Server eindeutig

Bei der ersten Verbindung zu einem Server per SSH bekommt man eine Meldung wie diese:

The authenticity of host ‚www.example.com (192.168.12.34)‘ can’t be established.
ECDSA key fingerprint is SHA256:86RDANuVFu5w3OF4RuFW04jqMfVbahR/sk4Yr/ElLI0.
Are you sure you want to continue connecting (yes/no)?
Server identifizieren

Beim ersten Verbindungsaufbau Fingerprint des Host-Keys überprüfen

Fingerprint vergleichen

Sicherstellen, dass man mit dem richtigen Server verbunden ist

  • und nicht (von einem Angreifer) auf eine andere Maschine umgeleitet wurde

Hat man den Key verglichen oder ist man sich zumindest sehr sicher, dass man sich mit dem richtigen Server verbunden hat, kann man die oben stehende Frage mit "yes" beantworten

  • Der Key wird dann vom Client gespeichert und bei weiteren Verbindungen nur noch verglichen und nicht mehr gefragt.
Handlungsbedarf

Sollte im laufenden Betrieb dann doch mal eine Meldung wie die folgende kommen, gibt es Handlungsbedarf

 @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
 @ WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED! @
 @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
 IT IS POSSIBLE THAT SOMEONE IS DOING SOMETHING NASTY!
 Someone could be eavesdropping on you right now (man-in-the-middle attack)!
 It is also possible that a host key has just been changed.
Variante 1
  • Der Server wurde neu aufgesetzt (oder zumindest der SSH-Key neu generiert)
  • in diesem Fall den Key aus der Datei ~/.ssh/known_hosts entfernen und wie bei einem erstmaligen Verbindungsaufbau verfahren
Variante 2
  • Man hat sich auf einen Namen oder eine IP verbunden, die nicht eindeutig einem Server zuzuordnen ist, und durch Cluster-Failover, Load Balancing oder Ähnliches landet man jetzt auf einem anderen Server.
  • Hier in Zukunft, wenn möglich, auf eindeutigen Namen bzw. IPs verbinden.
Variante 3
  • Man ist gerade Opfer einer Man-in-the-middle-Attacke geworden und ein Angreifer versucht, den SSH-Verkehr auf einen anderen Server umzuleiten.
  • SSH Keys mögen zwar nervig erscheinen, aber wenn man nicht selbst grob fahrlässig agiert, können sie einen vor Angriffen auf die Verbindung bewahren.

SSH-Fingerprint prüfen

Prüfung der Authentizität eines SSH/Server

Wichtig, bei Erstverbindungen!

SSH-Verbindungen sind bei der ersten Verbindung am meisten verwundbar

Nachdem Sie zum ersten Mal eine Verbindung zu einem Server hergestellt haben, speichert der SSH-Client seinen Fingerabdruck

Wenn Sie sich zum ersten Mal mit einem Server verbinden war Ihr Client nicht in der Lage, seinen Fingerabdruck zu protokollieren und zu überprüfen, ob er korrekt ist

  • Daher kann ein Angreifer erfolgreich einen Man-in-the-Middle-Angriff durchführen
  • Die einzige Möglichkeit, um sicherzustellen, dass Sie sich von Anfang an mit dem richtigen Server verbinden, besteht darin, den Fingerabdruck Ihres SSH-Schlüssels manuell zu überprüfen

Wenn sich dieser Fingerabdruck ändert

  • weil jemand versucht, Sie mit einem bösartigen Server zu verbinden,
  • wird Ihr SSH-Client Sie warnen, dass sich der Fingerabdruck geändert hat
Fingerabdruck eines SSH-Schlüssels überprüfen

Bevor Sie Ihren Fingerabdruck überprüfen können, müssen Sie den dafür verwendeten Algorithmus kennen

Dieser sollte aus dem Inhalt Ihrer Nachricht hervorgehen

Die Authentizität des Hosts '172.86.75.163 (172.86.75.163)' kann nicht festgestellt werden. ED25519 key fingerprint is SHA256:NTw36MQjDxsHlxC/Xso5yKMlKJu93uYknRx2LEaqk7I. This key is not known by any other names. Sind Sie sicher, dass Sie die Verbindung fortsetzen möchten (ja/nein/[fingerprint])?

Sie können sehen, dass unser Schlüssel den Algorithmus ED25519 verwendet und mit SHA256 gehasht wird

  • Sie sollten sich dies notieren, ebenso wie den Fingerabdruck selbst, in diesem Fall

NTw36MQjDxsHlxC/Xso5yKMlKJu93uYknRx2LEaqk7I

Ihr Schlüsselalgorithmus könnte auch ECDSA, RSA und DSA sein, und Ihr Hashing-Algorithmus könnte MD5 statt SHA sein

Überprüfen des Fingerabdrucks auf dem Server

Loggen Sie sich über eine vertrauenswürdige Methode in Ihren Server ein

Führen Sie den Befehl ssh-keygen aus, um den Fingerabdruck Ihres Schlüssels auszulesen

SHA256
ssh-keygen -lf [Datei]]
MD5
ssh-keygen -E md5 -lf [Datei]
Algorithmus Datei
ED25519 /etc/ssh/ssh_host_ed25519_key.pub
ECDSA /etc/ssh/ssh_host_ecdsa_key.pub
RSA /etc/ssh/ssh_host_rsa_key.pub
DSA /etc/ssh/ssh_host_dsa_key.pub
Beispiel
ssh-keygen -lf /etc/ssh/ssh_host_ed25519_key.pub
 256 SHA256:NTw36MQjDxsHlxC/Xso5yKMlKJu93uYknRx2LEaqk7I root@6311ad8b487e6f00018c5cd1 (ED25519)

Stellen Sie keine Verbindung zum Server her!
Wenn die Ausgabe nicht mit dem Fingerabdruck übereinstimmt, den Sie zuvor notiert haben


Host-Keys erneuern

ssh-Server verfügen über einen Satz von Host-Keys, mit denen sich der Server gegenüber den Clients identifizieren kann.

  • Nach dem ersten erfolgreichen Verbindungsaufbau legt der ssh-Client den Host-Key des Servers in der Datei ~/.ssh/knownhosts ab.
  • Bei einem erneuten Verbindungsaufbau vergleicht der ssh-Client den vom ssh-Server aktuell übermittelten ssh-Host-Key mit dem zugehörigen gespeicherten ssh-Host-Key und gibt bei einem abweichenden Key - je nach Konfiguration des ssh-Clients - eine Warnung aus oder bricht sogar den Verbindungsaufbau ab.
  • Durch diese Prüfung können Man-in-the-Middle-Angriffe verbindet werden.

Damit dieser Mechanismus zuverlässig funktionieren kann, benötigt jeder ssh-Server einen eigenen Satz mit einmaligen ssh-Host-Keys.

Bei der Installation des Softwarepaketes mit dem ssh-Server wird üblicherweise ein neuer Satz mit einmaligen ssh-Host-Keys generiert.

Klont man hingegen einen bestehenden Server (beispielsweise

  • Aufsetzen eines neuen Servers aus einem Backup oder Disk-Images eines bestehenden Servers, Kopieren einer virtuellen Maschine), dann "erbt" der neue Server den Satz an ssh-Host-Keys.
  • Sofern der neue Server den bisherigen Server ersetzt, ist dies unproblematisch.
  • Sofern man einen neuen, zusätzlichen Server aufbaut, dann sollte dieser Server einen neuen Satz mit eigenen einmaligen ssh-Host-Key erhalten.
How to change a SSH host key?
  1. In manchen Quellen wird für das Generieren der neuen Keys der Befehl dpkg-reconfigure openssh-server verwendet, der das Software-Paket für den OpenSSH-Server neu konfiguriert.
    • Es sollte jedoch ein ssh-keygen -A ausreichen, der den Satz ssh-Host-Keys um die fehlenden Typen ergänzt.

Die erste Variante setzt voraus, dass ein OpenSSH-Server verwendet wird, während die zweite Variante allgemeingültig sein sollte.

  1. Der ssh-Client gibt in den Warnungen die entsprechende Zeilennummer aus.

Keys ersetzen

Zum Erneuern der ssh-Host-Keys löscht man auf dem Server zunächst die bestehenden Host-Keys und generiert einen Satz neue Keys1):

cd /etc/ssh
sudo rm ssh_host_*
sudo ssh-keygen -A

Änderungen auf den Clients

Sofern für den ssh-Server bereits der alte ssh-Host-Key auf einem Client gespeichert ist, kann die ~/.ssh/knownhosts mit dem folgenden Befehl bereinigt werden:

 ssh-keygen -R remote-server-name

Alternativ kann in der ~/.ssh/knownhosts der Eintrag auch mit einem Texteditor entfernt werden2).

Beim ssh-Client Blink (iOS) funktionieren die obigen beiden Lösungen nicht

Hier ist der folgende Workaround notwendig

In das Verzeichnis .ssh wechseln
 cd ~/.ssh

Inhalt der Datei known_hosts mit Zeilennummern anzeigen

 cat -n known_hosts

Entsprechende Zeile merken und mit sed löschen (im Beispiel Zeile 99)

 sed -i.bak '99d' known_hosts

Konfiguration

Dateien

Datei Beschreibung


Anhang

Siehe auch


Dokumentation

Projekt