Uzyskaj odcisk palca klucza serwera SSH

82

Czy istnieje sposób programowego uzyskania odcisku palca klucza serwera SSH bez uwierzytelniania ?

Próbuję ssh -v user@host false 2>&1 | grep "Server host key", ale zawiesza się oczekiwanie na hasło, jeśli uwierzytelnianie oparte na kluczu nie jest skonfigurowane.

goncalopp
źródło

Odpowiedzi:

71

Możesz to zrobić, łącząc ssh-keyscani 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

(niestety znacznie prostsze ssh-keyscan host | ssh-keygen -l -f /dev/stdinnie działa)

Andreas Wiese
źródło
1
Może ssh-keygen -l -f - <(ssh-keyscan host)jednak?
CVn
21
OpenSSH> = 7.2 ssh-keyscan jest w stanie czytać ze standardowego wejścia:ssh-keyscan host | ssh-keygen -lf -
mykhal
1
Po prostu zrób:ssh-keygen -l -f <(ssh-keyscan host)
Christopher
1
To raczej złe wyrażenie dla skryptów powłoki, ponieważ zależy to od powłoki, która ją obsługuje, czego nie robi powłoka POSIX.
Andreas Wiese
2
ssh-keygen -l -f -działa zgodnie z oczekiwaniami w ssh-keygen 7.2 i nowszych. Tworzy kilka wierszy komentarza do STDERR, które można odfiltrować, jak wspomniano w odpowiedzi Anthony Geoghegan lubssh-keyscan host 2>/dev/null | ssh-keygen -l -f -
Cedric Knight
56

Niedawno musiałem to zrobić sam, więc pomyślałem, że dodam odpowiedź, która pokazuje, jak można to zrobić (z wersjami OpenSSH 7.2 lub nowszą ) w jednym wierszu za pomocą podstawiania procesów:

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

Poniższy tekst wyjaśnia, jak działają te polecenia, i podkreśla niektóre różnice w zachowaniu między starszymi i nowszymi wersjami narzędzi OpenSSH.

Pobierz klucze hosta publicznego

ssh-keyscanKomenda została opracowana tak, że użytkownicy mogą uzyskać klucze hostów publicznych bez konieczności uwierzytelnienia na serwerze SSH. Ze strony podręcznika:

ssh-keyscanto narzędzie do gromadzenia publicznych kluczy hosta ssh wielu hostów. Został zaprojektowany, aby pomóc w budowaniu i weryfikacji ssh_known_hostsplików.

Typ klucza

Typ klucza do pobrania jest określany za pomocą -topcji.

  • rsa1 (przestarzała wersja protokołu SSH 1)
  • rsa
  • dsa
  • ecdsa (ostatnie wersje OpenSSH)
  • ed25519 (ostatnie wersje OpenSSH)

We współczesnych wersjach OpenSSH domyślnymi typami kluczy do pobrania są rsa (od wersji 5.1), ecdsa(od wersji 6.0) i ed25519(od wersji 6.7).

Ze starszymi wersjami w ssh-keyscan(przed) OpenSSH wersji 5.1 The domyślny typ klucz był przestarzały rsa1(SSH Protokół 1) główne typy tak musiałby być wyraźnie określone:

ssh-keyscan -t rsa,dsa hostname

Uzyskaj skróty linii papilarnych kluczy Base64

ssh-keyscanwypisuje klucz hosta serwera SSH w formacie zakodowanym w Base64 . Aby przekonwertować to na skrót linii papilarnych, ssh-keygenmożna użyć narzędzia z jego -lopcją drukowania odcisku palca określonego klucza publicznego.

Jeśli używasz Bash, Zsh (lub powłoki Korna), możesz zastosować podstawienie procesu dla poręcznej jednowarstwowej:

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

Uwaga : W wersjach OpenSSH wcześniejszych niż 7.2 funkcje używane przez ssh-keygendo odczytu plików nie radziły sobie bardzo dobrze z nazwanymi potokami (FIFO), więc ta metoda nie działała, co wymagało użycia plików tymczasowych.

Algorytmy mieszania

Najnowsze wersje ssh-keygenprint SHA256 mieszań papilarnych kluczy. Aby uzyskać skróty MD5 odcisków palców klucza serwera (stare zachowanie), -E można użyć opcji określającej algorytm skrótu:

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

Korzystanie z rurociągu

Jeśli używasz powłoki POSIX (takiej jak dash), która nie obsługuje zastępowania procesów, inne rozwiązania wykorzystujące pliki tymczasowe będą działać. Jednak w nowszych wersjach OpenSSH (od wersji 7.2) można użyć prostego potoku, ponieważ ssh-keygenbędzie on akceptowany -jako nazwa pliku dla standardowego strumienia wejściowego, umożliwiając jednoliniowe polecenie potoku.

ssh-keyscan hostname 2>/dev/null | ssh-keygen -E md5 -lf -
Anthony Geoghegan
źródło
Ładna i dokładna odpowiedź, to z pewnością lepsze niż posiadanie pliku tymczasowego! Czy mogę zasugerować podanie TL; DR na początku wersji zastępowania procesu, aby niecierpliwi ludzie szybciej ją znaleźli? :)
goncalopp,
3
Nie działa na Ubuntu 14.04 LTS; Pojawia się błąd „/ dev / fd / 63 nie jest plikiem klucza publicznego”. Podproces działa.
Melle,
@melleb Znalazłem to samo w systemie 12.04, do którego mam dostęp. Podejrzewam, że ssh-keygenze starszych wersji OpenSSH występuje problem z odczytem z FIFO / nazwanego potoku. Zajmę się tym (i zaktualizuję swoją odpowiedź), kiedy będę miał trochę wolnego czasu.
Anthony Geoghegan
3
@melleb Po spędzeniu długiego czasu na pobieraniu różnych wydań kodu źródłowego i wstawianiu printfinstrukcji debugowania do do_fingerprint()funkcji zauważyłem, że w wersjach OpenSSH wcześniejszych niż 7.2 funkcje używane ssh-keygendo odczytu plików nie radziły sobie bardzo dobrze z nazwanymi potokami (FIFO), więc metoda podstawienia procesu nie zadziałałaby.
Anthony Geoghegan
Działa to, ale jeśli używasz go do weryfikacji odcisku palca, użytkownicy powinni mieć świadomość, że istnieje warunek wyścigu: odcisk palca sprawdzany za pomocą tego polecenia niekoniecznie musi pochodzić od klucza, który pobierasz, chyba że zrzucisz klucz przed wywołaniem ssh- keygen na nim.
CodeGnome
20

nmapzapewnia tę możliwość za pomocą ssh-hostkeyskryptu.

Aby zwrócić szesnastkowy odcisk klucza:

$ nmap [SERVER] --script ssh-hostkey

Aby zwrócić zawartość klucza:

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

Aby zwrócić bańkę wizualną klucza

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

Aby zwrócić wszystkie powyższe:

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

Źródło: dokumenty nmap

zatoczka
źródło
3
Czy te przykłady zakładają, że SSH zawsze działa na porcie 22? Co jeśli ssh nasłuchuje na niestandardowym porcie?
Martin Vegter,
3
@MartinVegter (parafrazując Guarin42, który nie mógł komentować :) nmap ma -popcję określającą port, np -p 22000. Możliwe jest również użycie -vvopcji zwiększenia gadatliwości (ilość podanych informacji)
goncalopp
2

filezilla wyświetla klucze zakodowane przy pomocy md5 w formacie szesnastkowym .

aby znaleźć to na swoim komputerze z systemem Linux Ubuntu , użyj tego polecenia:

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

Uwaga: zamień „localhost” na ip komputera, który chcesz sprawdzić.

Cameron
źródło
1

Oto skrypt powłoki (głównie powłoka Bourne'a, ale za pomocą localsłowa kluczowego, które jest dostępne w najnowocześniejszych /bin/sh), które napisałem, aby to zrobić. Użyj tego jak ssh-hostkey hostname. Wyświetli odciski palców w formacie sha256 i md5 dla wszystkich kluczy hostów dla podanej nazwy hosta lub adresu IP. Możesz także ręcznie określić „ md5” lub „ sha256” jako drugi argument, aby pokazać tylko ten konkretny format.

Używa pliku tymczasowego zamiast potokowania, aby był zgodny ze starszymi pakietami OpenSSH (jak opisano w innych odpowiedziach). Plik tymczasowy wykorzystuje /dev/shm(pamięć współdzieloną), jeśli jest dostępna.

#!/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 "$@"
ejm
źródło