Ottieni l'impronta digitale della chiave del server SSH


83

C'è un modo per programmazione ottenere una chiave di impronte digitali server SSH , senza l'autenticazione ad esso?

Sto provando ssh -v user@host false 2>&1 | grep "Server host key", ma questo si blocca in attesa di una password se non è stata impostata l'autent basata su chiave.

Risposte:


71

Puoi farlo combinando ssh-keyscane 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

(purtroppo il molto più semplice ssh-keyscan host | ssh-keygen -l -f /dev/stdinnon funziona)


1
Forse lo ssh-keygen -l -f - <(ssh-keyscan host)fa, però?
un CVn,

21
OpenSSH> = 7.2 ssh-keyscan è in grado di leggere da stdin:ssh-keyscan host | ssh-keygen -lf -
mykhal

1
Fai solo:ssh-keygen -l -f <(ssh-keyscan host)
Christopher,

1
È un'espressione piuttosto negativa per gli script di shell, poiché dipende da una shell che la supporta, cosa che la shell POSIX non ha.
Andreas Wiese,

2
ssh-keygen -l -f -funziona come previsto in ssh-keygen 7.2 e versioni successive. Produce alcune righe di commento a STDERR che possono essere filtrate, come menzionato nella risposta di Anthony Geoghegan ossh-keyscan host 2>/dev/null | ssh-keygen -l -f -
Cedric Knight

56

Di recente ho dovuto farlo da solo, quindi ho pensato di aggiungere una risposta che mostri come farlo (con le versioni di OpenSSH 7.2 o successive ) in una riga usando la sostituzione del processo:

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

Il seguente testo spiega come funzionano questi comandi ed evidenzia alcune delle differenze nel comportamento tra le versioni più vecchie e più recenti delle utility OpenSSH.

Recupera le chiavi dell'host pubblico

Il ssh-keyscancomando è stato sviluppato in modo che gli utenti possano ottenere le chiavi dell'host pubblico senza la necessità di autenticarsi sul server SSH. Dalla sua pagina man:

ssh-keyscanè un'utilità per raccogliere le chiavi dell'host ssh pubbliche di un numero di host. È stato progettato per facilitare la creazione e la verifica dei ssh_known_hostsfile.

Tipo di chiave

Il tipo di chiave da recuperare è specificato mediante l' -topzione.

  • rsa1 (Protocollo SSH obsoleto versione 1)
  • rsa
  • dsa
  • ecdsa (versioni recenti di OpenSSH)
  • ed25519 (versioni recenti di OpenSSH)

Nelle moderne versioni di OpenSSH, i tipi di chiave predefiniti da recuperare sono rsa (dalla versione 5.1), ecdsa(dalla versione 6.0) e ed25519(dalla versione 6.7).

Con le versioni precedenti di ssh-keyscan(prima di OpenSSH versione 5.1), il tipo di chiave predefinito era obsoleto rsa1(SSH Protocol 1), quindi i tipi di chiave avrebbero dovuto essere specificati esplicitamente:

ssh-keyscan -t rsa,dsa hostname

Ottieni hash delle impronte digitali delle chiavi Base64

ssh-keyscanstampa la chiave host del server SSH in formato codificato Base64 . Per convertire questo in un hash dell'impronta digitale, è ssh-keygenpossibile utilizzare l' utilità con la sua -lopzione per stampare l'impronta digitale della chiave pubblica specificata.

Se si utilizza Bash, Zsh (o la shell Korn), la sostituzione del processo può essere utilizzata per un pratico one-liner:

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

Nota : con le versioni di OpenSSH precedenti alla 7.2, le funzioni utilizzate ssh-keygenper leggere i file non gestivano molto bene le named pipe (FIFO), quindi questo metodo non funzionava, richiedendo quindi l'uso di file temporanei.

Algoritmi di hash

Versioni recenti degli hash delle impronte digitali SHA256 di ssh-keygenstampa dei tasti. Per ottenere gli hash MD5 delle impronte digitali della chiave del server (il vecchio comportamento), è possibile utilizzare l' opzione per specificare l'algoritmo hash:-E

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

Utilizzando una pipeline

Se si utilizza una shell POSIX (come dash) che non prevede la sostituzione del processo, le altre soluzioni che utilizzano file temporanei funzioneranno. Tuttavia, con le versioni più recenti di OpenSSH (dalla versione 7.2), è possibile utilizzare una pipeline semplice poiché ssh-keygenaccetterà -come nome file per il flusso di input standard, consentendo un comando di pipeline su una riga.

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

Risposta piacevole e completa, questo è sicuramente meglio che avere un file temporaneo! Posso suggerirti di fornire un TL; DR all'inizio con la versione di sostituzione del processo, per fare in modo che le persone impazienti lo trovino più velocemente? :)
goncalopp

3
Non sembra funzionare su Ubuntu 14.04 LTS; Viene visualizzato l'errore "/ dev / fd / 63 non è un file di chiave pubblica". Il sottoprocesso funziona.
Melle,

@melleb Ho trovato la stessa cosa su un sistema 12.04 a cui ho accesso. Ho il sospetto che ssh-keygendalle versioni precedenti di OpenSSH si sia verificato un problema nella lettura dalla pipe FIFO / named. Esaminerò questo (e aggiornerò la mia risposta) quando avrò del tempo libero.
Anthony G - giustizia per Monica,

3
@melleb Dopo aver trascorso il mio luch-time a scaricare varie versioni del codice sorgente e ad inserire printfistruzioni di debug nella do_fingerprint()funzione, ho scoperto che con le versioni di OpenSSH precedenti alla 7.2, le funzioni utilizzate ssh-keygenper leggere i file non gestivano molto bene le named pipe (FIFO) il metodo di sostituzione del processo non funzionerebbe.
Anthony G - giustizia per Monica,

Funziona, ma se lo si utilizza per verificare un'impronta digitale, gli utenti devono essere consapevoli che esiste una condizione di competizione: l'impronta digitale che si sta verificando con questo comando non è necessariamente quella della chiave che si recupera, a meno che non si scarichi la chiave prima di chiamare ssh- Keygen su di esso.
CodeGnome

20

nmapfornisce questa capacità usando lo ssh-hostkeyscript.

Per restituire l'impronta digitale esadecimale della chiave:

$ nmap [SERVER] --script ssh-hostkey

Per restituire il contenuto della chiave:

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

Per restituire la bolla visiva della chiave

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

Per restituire tutto quanto sopra:

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

Fonte: documenti nmap


3
Questi esempi presuppongono che SSH sia sempre in esecuzione sulla porta 22? Cosa succede se ssh è in ascolto su una porta non standard?
Martin Vegter,

3
@MartinVegter (parafrasando Guarin42, che non ha potuto commentare :) nmap ha l' -popzione che può specificare una porta, ad es -p 22000. È anche possibile utilizzare l' -vvopzione per aumentare la verbosità (quantità di informazioni fornite)
goncalopp

2

filezilla visualizza le chiavi con hash con md5 in formato esadecimale .

per trovarlo sul tuo computer Ubuntu Linux usa questo comando:

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

nota: sostituire "localhost" con l'ip della macchina che si desidera verificare.


1

Ecco uno script di shell (principalmente shell Bourne ma usando la localparola chiave, che è disponibile nella maggior parte dei moderni /bin/sh) che ho scritto per fare questo. Usalo come ssh-hostkey hostname. Mostrerà le impronte digitali in formato sha256 e md5 per tutte le hostkey per il nome host o l'indirizzo IP specificato. Puoi anche specificare manualmente " md5" o " sha256" come secondo argomento per mostrare solo quel particolare formato.

Utilizza un file temporaneo anziché il piping per renderlo compatibile con i vecchi pacchetti OpenSSH (come descritto in altre risposte). Il file temporaneo utilizza /dev/shm(memoria condivisa) se disponibile.

#!/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 "$@"
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.