Отримайте відбиток ключа сервера SSH


82

Чи є спосіб програмно отримати відбиток ключа сервера SSH без автентифікації на нього?

Я намагаюся ssh -v user@host false 2>&1 | grep "Server host key", але це висить, чекаючи пароля, якщо авторизований ключ не встановлений.

Відповіді:


71

Ви можете зробити це, комбінуючи ssh-keyscanта 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

(на жаль, набагато простіше ssh-keyscan host | ssh-keygen -l -f /dev/stdinне працює)


1
Можливо ssh-keygen -l -f - <(ssh-keyscan host), правда?
CVn

21
OpenSSH> = 7,2 ssh-keyscan може читати з stdin:ssh-keyscan host | ssh-keygen -lf -
mykhal

1
Просто зробіть:ssh-keygen -l -f <(ssh-keyscan host)
Крістофер

1
Це досить поганий вираз для скриптів оболонки, оскільки це залежить від оболонки, яка його підтримує, а котрий оболонки POSIX не має.
Андреас Візе

2
ssh-keygen -l -f -працює так, як очікувалося в ssh-keygen 7.2 і вище. Він видає рядки коментарів до STDERR, які можна відфільтрувати, про що згадується у відповіді Ентоні Геоґеґана абоssh-keyscan host 2>/dev/null | ssh-keygen -l -f -
лицаря Седрика

56

Нещодавно мені довелося це зробити самостійно, тому я подумав додати відповідь, яка показує, як це можна зробити (з версіями OpenSSH 7.2 або новішими ) в одному рядку, використовуючи підстановку процесу:

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

Наступний текст пояснює, як ці команди працюють, та висвітлює деякі відмінності в поведінці між старими та новішими версіями утилітів OpenSSH.

Отримати відкриті хост-ключі

ssh-keyscanКоманда була розроблена таким чином , що користувачі можуть отримати ключі громадського хоста без необхідності перевірки справжності на сервер SSH. З його чоловічої сторінки:

ssh-keyscanце утиліта для збору відкритих хостів ключів ssh ряду хостів. Він був розроблений, щоб допомогти у створенні та верифікації ssh_known_hostsфайлів.

Тип ключа

Тип ключа, який потрібно отримати, задається за допомогою -tпараметра.

  • rsa1 (застарілий протокол SSH, версія 1)
  • rsa
  • dsa
  • ecdsa (останні версії OpenSSH)
  • ed25519 (останні версії OpenSSH)

У сучасних випусках OpenSSH типовими ключовими типами, які слід отримати rsa (починаючи з версії 5.1), ecdsa(з версії 6.0) та ed25519(з версії 6.7).

З більш старими версіями з ssh-keyscan(до OpenSSH версії 5.1), то по замовчуванням тип ключ був застарівають rsa1(SSH протокол 1) , так що основні типи повинні бути чітко зазначених у них:

ssh-keyscan -t rsa,dsa hostname

Отримайте відбитки пальців ключів Base64

ssh-keyscanдрукує хост-ключ сервера SSH у форматі, кодованому Base64 . Щоб перетворити це в хеш-відбиток, ssh-keygenутиліта може бути використана з його -lопцією для друку відбитка пальця зазначеного відкритого ключа.

Якщо ви використовуєте Bash, Zsh (або оболонку Korn), підміна процесу може бути використана для зручного однолінійного:

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

Примітка . У версіях OpenSSH до 7.2 функції, які використовуються ssh-keygenдля читання файлів, не дуже добре обробляють названі труби (FIFO), тому цей метод не працюватиме, тому вимагає використання тимчасових файлів.

Алгоритми хешування

Останні версії ssh-keygenдруку SHA256 відбитків пальців хешей ключів. Щоб отримати хеші MD5 відбитків пальців ключа сервера (стара поведінка), -E параметр можна використовувати для визначення алгоритму хешу:

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

Використання трубопроводу

Якщо використовується оболонка POSIX (наприклад, dash), яка не передбачає підстановки процесу, інші рішення, що використовують тимчасові файли, працюватимуть. Однак з новішими версіями OpenSSH (починаючи з 7.2) може бути використаний простий конвеєр, оскільки він ssh-keygenбуде приймати -як ім'я файлу для стандартного вхідного потоку, дозволяючи однолінійну команду конвеєра.

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

Гарна і ретельна відповідь, це, звичайно, краще, ніж мати тимчасовий файл! Чи можу я запропонувати вам надати TL; DR на початку з версією процесу заміни, щоб нетерплячі люди швидше знаходили його? :)
goncalopp

3
Схоже, це не працює на Ubuntu 14.04 LTS; Я отримую помилку "/ dev / fd / 63 - не файл відкритого ключа". Підпроцес справді працює.
Мелле

@melleb Я знайшов те саме в системі 12.04, до якої я маю доступ. Я підозрюю, що ssh-keygenу старих версій OpenSSH виникають проблеми з читанням з FIFO / названої труби. Я вивчу це (і оновлю свою відповідь), коли отримаю трохи вільного часу.
Ентоні Геоґеган

3
@melleb Після витраченого часу на завантаження різних випусків вихідного коду та вставлення printfу програму операторів налагодження do_fingerprint()я виявив, що з версіями OpenSSH до 7.2 функції, які використовуються ssh-keygenдля читання файлів, не дуже добре обробляють названі труби (FIFO). метод заміщення процесу не працює.
Ентоні Геоґеган

Це працює, але якщо ви використовуєте його для перевірки відбитка пальців, користувачі повинні знати, що існує гоночна умова: відбиток пальця, який ви перевіряєте за допомогою цієї команди, не обов’язково є тим ключем, який ви отримуєте, якщо ви не скидаєте ключ перед тим, як викликати ssh- кейген на ньому.
CodeGnome

20

nmapнадає цю можливість за допомогою ssh-hostkeyсценарію.

Щоб повернути шістнадцятковий відбиток ключа:

$ nmap [SERVER] --script ssh-hostkey

Щоб повернути вміст ключа:

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

Щоб повернути візуальний міхур ключа

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

Щоб повернути все вищезазначене:

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

Джерело: nmap docs


3
Чи припускають ці приклади, що SSH завжди працює на порту 22? Що робити, якщо ssh слухає на нестандартному порту?
Мартін Вегтер

3
@MartinVegter (перефразовуючи Guarin42, який не міг коментувати :) nmap має -pопцію, яка може вказати порт, наприклад -p 22000. Також можливо скористатися -vvопцією для збільшення багатослівності (кількість наданої інформації)
goncalopp

2

filezilla відображає хешовані ключі з md5 у шістнадцятковому форматі.

щоб знайти це на вашій машині Linux ubuntu, використовуйте цю команду:

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

Примітка: замініть "localhost" на ip машини, яку ви хочете перевірити.


1

Ось сценарій оболонки (в основному оболонка Борна, але за допомогою localключового слова, яке доступне в більшості сучасних /bin/sh) я написав для цього. Використовуйте його як ssh-hostkey hostname. Він буде показувати як відбитки пальців формату sha256 та md5 для всіх ключів хостів для заданого імені хоста чи IP-адреси. Ви також можете вручну вказати " md5" або " sha256" як другий аргумент, щоб показати лише цей конкретний формат.

Він використовує тимчасовий файл замість трубопроводу, щоб зробити його сумісним із старими пакетами OpenSSH (як описано в інших відповідях). Тимчасовий файл використовує /dev/shm(спільна пам'ять), якщо є.

#!/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 "$@"
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.