Holen Sie sich den Fingerabdruck des SSH-Server-Schlüssels


82

Gibt es eine Möglichkeit , einen SSH-Serverschlüssel-Fingerabdruck programmgesteuert abzurufen, ohne sich bei ihm zu authentifizieren ?

Ich versuche es ssh -v user@host false 2>&1 | grep "Server host key", aber dies hängt und wartet auf ein Passwort, wenn keine schlüsselbasierte Authentifizierung eingerichtet ist.

Antworten:


71

Sie können dies tun durch die Kombination ssh-keyscanund ssh-keygen:

$ file=$(mktemp)
$ ssh-keyscan host > $file 2> /dev/null
$ ssh-keygen -l -f $file
521 de:ad:be:ef:de:ad:be:ef:de:ad:be:ef:de:ad:be:ef host (ECDSA)
4096 8b:ad:f0:0d:8b:ad:f0:0d:8b:ad:f0:0d:8b:ad:f0:0d host (RSA)
$ rm $file

(leider geht das viel einfacher ssh-keyscan host | ssh-keygen -l -f /dev/stdinnicht)


1
Aber vielleicht ssh-keygen -l -f - <(ssh-keyscan host)doch?
— ein Lebenslauf

21
OpenSSH> = 7.2 ssh-keyscan kann von stdin lesen:ssh-keyscan host | ssh-keygen -lf -
— mykhal

1
Tun Sie einfach:ssh-keygen -l -f <(ssh-keyscan host)
— Christopher

1
Das ist ein ziemlich schlechter Ausdruck für Shell-Skripte, da es von einer Shell abhängt, die dies unterstützt, was die POSIX-Shell nicht tut.
— Andreas Wiese

2
ssh-keygen -l -f -funktioniert wie erwartet in ssh-keygen 7.2 und höher. Es werden einige Kommentarzeilen zu STDERR erstellt, die herausgefiltert werden können, wie in der Antwort von Anthony Geoghegan oderssh-keyscan host 2>/dev/null | ssh-keygen -l -f -
— Cedric Knight vom

56

Ich musste dies vor kurzem selbst tun, daher dachte ich, ich würde eine Antwort hinzufügen, die zeigt, wie dies (mit Versionen von OpenSSH 7.2 oder neuer ) in einer Zeile unter Verwendung der Prozessersetzung getan werden kann:

ssh-keygen -lf <(ssh-keyscan hostname 2>/dev/null)

Der folgende Text erläutert die Funktionsweise dieser Befehle und hebt einige Unterschiede im Verhalten älterer und neuerer Versionen der OpenSSH-Dienstprogramme hervor.

Holen Sie sich öffentliche Host-Schlüssel

Der ssh-keyscanBefehl wurde entwickelt, damit Benutzer öffentliche Hostschlüssel erhalten können, ohne sich beim SSH-Server authentifizieren zu müssen. Von seiner Manpage:

ssh-keyscanist ein Dienstprogramm zum Erfassen der öffentlichen SSH-Hostschlüssel einer Reihe von Hosts. Es wurde entwickelt, um beim Erstellen und Überprüfen von ssh_known_hostsDateien zu helfen .

Schlüsselart

Die Art des abzurufenden Schlüssels wird mit der -tOption festgelegt.

  • rsa1 (veraltetes SSH-Protokoll Version 1)
  • rsa
  • dsa
  • ecdsa (neueste Versionen von OpenSSH)
  • ed25519 (neueste Versionen von OpenSSH)

In modernen OpenSSH-Releases müssen standardmäßig die Schlüsseltypen rsa (seit Version 5.1), ecdsa(seit Version 6.0) und ed25519(seit Version 6.7) abgerufen werden .

In älteren Versionen von ssh-keyscan(vor OpenSSH Version 5.1) war der Standardschlüsseltyp veraltet rsa1(SSH-Protokoll 1), sodass die Schlüsseltypen explizit angegeben werden müssten:

ssh-keyscan -t rsa,dsa hostname

Holen Sie sich Fingerabdruck-Hashes von Base64-Schlüsseln

ssh-keyscandruckt den Host-Schlüssel des SSH-Servers im Base64-codierten Format. Um dies in einen Fingerabdruck-Hash umzuwandeln, kann das ssh-keygenDienstprogramm mit seiner -lOption verwendet werden, um den Fingerabdruck des angegebenen öffentlichen Schlüssels zu drucken.

Bei Verwendung von Bash, Zsh (oder der Korn-Shell) kann die Prozessersetzung für einen praktischen Einzeiler verwendet werden:

ssh-keygen -lf <(ssh-keyscan hostname 2>/dev/null)

Hinweis : In OpenSSH-Versionen vor 7.2 haben die ssh-keygenzum Lesen von Dateien verwendeten Funktionen Named Pipes (FIFOs) nicht sehr gut verarbeitet, sodass diese Methode nicht funktioniert und die Verwendung temporärer Dateien erforderlich ist.

Hashing-Algorithmen

Aktuelle Versionen von SHA256 Fingerabdruck-Hashes der Tasten ssh-keygendrucken . Um MD5- Hashes der Serverschlüssel-Fingerabdrücke abzurufen (das alte Verhalten), kann die Option verwendet werden, um den Hash-Algorithmus anzugeben:-E

ssh-keygen -E md5 -lf <(ssh-keyscan hostname 2>/dev/null)

Pipeline verwenden

Wenn Sie eine POSIX-Shell (z. B. dash) ohne Prozessersetzung verwenden, funktionieren die anderen Lösungen mit temporären Dateien. In neueren Versionen von OpenSSH (seit 7.2) kann jedoch eine einfache Pipeline verwendet werden, da ssh-keygensie -als Dateinamen für den Standardeingabestream akzeptiert und einen einzeiligen Pipelinebefehl zulässt.

ssh-keyscan hostname 2>/dev/null | ssh-keygen -E md5 -lf -

Schöne und gründliche Antwort, das ist sicherlich besser als eine temporäre Datei zu haben! Darf ich vorschlagen, dass Sie zu Beginn der Prozessersetzungsversion einen TL; DR angeben, damit ungeduldige Leute ihn schneller finden? :)
— Goncalopp

3
Scheint auf Ubuntu 14.04 LTS nicht zu funktionieren; Ich erhalte die Fehlermeldung "/ dev / fd / 63 ist keine öffentliche Schlüsseldatei". Der Unterprozess funktioniert.
— Melle

@melleb Ich habe dasselbe auf einem 12.04-System gefunden, auf das ich Zugriff habe. Ich vermute, dass ssh-keygenvon älteren Versionen von OpenSSH ein Problem beim Lesen aus dem FIFO / Named Pipe vorliegt. Ich werde das untersuchen (und meine Antwort aktualisieren), wenn ich etwas Freizeit habe.
— Anthony Geoghegan

3
@melleb Nachdem ich viel Zeit mit dem Herunterladen verschiedener Quellcode-Releases und dem Einfügen von Debugging- printfAnweisungen in die do_fingerprint()Funktion verbracht hatte, stellte ich fest, dass mit OpenSSH-Versionen vor 7.2 die ssh-keygenzum Lesen von Dateien verwendeten Funktionen Named Pipes (FIFOs) nicht so gut handhabten Die Prozessersetzungsmethode würde nicht funktionieren.
— Anthony Geoghegan

Dies funktioniert. Wenn Sie es jedoch zur Überprüfung eines Fingerabdrucks verwenden, sollten Sie sich darüber im Klaren sein, dass eine Race-Bedingung vorliegt: Der Fingerabdruck, den Sie mit diesem Befehl überprüfen, entspricht nicht unbedingt dem des Schlüssels, den Sie abrufen, es sei denn, Sie geben den Schlüssel ab, bevor Sie ssh- aufrufen. keygen drauf.
— CodeGnome

20

nmapBietet diese Möglichkeit mithilfe des ssh-hostkeySkripts.

So geben Sie den hexadezimalen Fingerabdruck des Schlüssels zurück:

$ nmap [SERVER] --script ssh-hostkey

So geben Sie den Inhalt des Schlüssels zurück:

$ nmap [SERVER] --script ssh-hostkey --script-args ssh_hostkey=full

Zum Zurückkehren der visuellen Blase des Schlüssels

$ nmap [SERVER] --script ssh-hostkey --script-args ssh_hostkey='visual bubble'

So geben Sie alle oben genannten Informationen zurück:

$ nmap [SERVER] --script ssh-hostkey --script-args ssh_hostkey=all

Quelle: nmap docs


3
Gehen diese Beispiele davon aus, dass SSH immer auf Port 22 ausgeführt wird? Was ist, wenn ssh auf einem nicht standardmäßigen Port lauscht?
— Martin Vegter

3
@MartinVegter (paraphrasiert Guarin42, der nicht kommentieren konnte :) nmap hat die -pOption, einen Port anzugeben, z -p 22000. Es ist auch möglich, die -vvOption zu verwenden, um die Ausführlichkeit (Menge der angegebenen Informationen) zu erhöhen
— goncalopp

2

filezilla zeigt mit md5 gehashte Schlüssel im Hexadezimalformat an .

Verwenden Sie diesen Befehl , um dies auf Ihrem Ubuntu-Linux- Computer zu finden :

ssh-keygen -l -E md5 -f <(ssh-keyscan localhost 2>/dev/null)

Hinweis: Ersetzen Sie "localhost" durch die IP-Adresse des Computers, den Sie überprüfen möchten.


1

Hier ist ein Shell-Skript (hauptsächlich Bourne-Shell, aber mit localSchlüsselwörtern, die in den meisten modernen /bin/shVersionen verfügbar sind ), das ich dazu geschrieben habe. Benutze es wie ssh-hostkey hostname. Es werden sowohl die Fingerabdrücke im sha256- als auch im md5-Format für alle Hostschlüssel für den angegebenen Hostnamen oder die angegebene IP-Adresse angezeigt. Sie können auch manuell " md5" oder " sha256" als zweites Argument angeben, um nur dieses bestimmte Format anzuzeigen.

Anstelle von Piping wird eine temporäre Datei verwendet, um die Kompatibilität mit älteren OpenSSH-Paketen zu gewährleisten (wie in anderen Antworten beschrieben). Die temporäre Datei verwendet /dev/shm(Shared Memory), falls verfügbar.

#!/bin/sh
usage () {
  printf '%s\n' "Usage: ssh-hostkey HOSTNAME [FPRINTHASH]"
}

ssh_hostkey () {
  local host="$1"
  local fprinthash="$2"
  local tmp=

  case "$host" in
    -h|--help|'')
      usage >&2
      return 1
      ;;
  esac

  case "$fprinthash" in
    md5|sha256|'') true;;
    *)
      usage >&2
      printf '%s\n' "Fingerprint hash may be 'md5' or 'sha256'" >&2
      return 2
      ;;
  esac

  if test -d /dev/shm
  then tmp="$(mktemp -d -p /dev/shm)"
  else tmp="$(mktemp -d)"
  fi

  trap 'trap - INT TERM EXIT; rm -rf "$tmp"' INT TERM EXIT
  ssh-keyscan "$host" > "$tmp/f" 2> /dev/null
  case "$fprinthash" in
    sha256|'') ssh-keygen -l -f "$tmp/f" 2> /dev/null;;
  esac
  case "$fprinthash" in
    md5|'') ssh-keygen -l -E md5 -f "$tmp/f" 2> /dev/null;;
  esac

  trap - INT TERM EXIT
  rm -rf "$tmp" > /dev/null 2>&1
}

ssh_hostkey "$@"
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.