Відповіді:
Ви можете зробити це, комбінуючи 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
не працює)
ssh-keyscan host | ssh-keygen -lf -
ssh-keygen -l -f <(ssh-keyscan host)
ssh-keygen -l -f -
працює так, як очікувалося в ssh-keygen 7.2 і вище. Він видає рядки коментарів до STDERR, які можна відфільтрувати, про що згадується у відповіді Ентоні Геоґеґана абоssh-keyscan host 2>/dev/null | ssh-keygen -l -f -
Нещодавно мені довелося це зробити самостійно, тому я подумав додати відповідь, яка показує, як це можна зробити (з версіями 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
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 -
ssh-keygen
у старих версій OpenSSH виникають проблеми з читанням з FIFO / названої труби. Я вивчу це (і оновлю свою відповідь), коли отримаю трохи вільного часу.
printf
у програму операторів налагодження do_fingerprint()
я виявив, що з версіями OpenSSH до 7.2 функції, які використовуються ssh-keygen
для читання файлів, не дуже добре обробляють названі труби (FIFO). метод заміщення процесу не працює.
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
-p
опцію, яка може вказати порт, наприклад -p 22000
. Також можливо скористатися -vv
опцією для збільшення багатослівності (кількість наданої інформації)
Ось сценарій оболонки (в основному оболонка Борна, але за допомогою 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 "$@"
ssh-keygen -l -f - <(ssh-keyscan host)
, правда?