Отримайте відбиток ключа сервера 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.