Answers:
您可以通过将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及更高版本中的预期工作。正如Anthony Geoghegan或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
以Base64编码
格式输出SSH服务器的主机密钥。要将其转换为指纹哈希,ssh-keygen
可以将该实用程序及其-l
选项一起使用以打印指定公钥的指纹。
如果使用Bash,Zsh(或Korn Shell),则可以将进程替换用于方便的单行代码:
ssh-keygen -lf <(ssh-keyscan hostname 2>/dev/null)
注意:在7.2之前的OpenSSH版本中,用于ssh-keygen
读取文件的功能
不能很好地处理命名管道(FIFO),因此该方法将不起作用,因此需要使用临时文件。
密钥的ssh-keygen
打印SHA256指纹哈希的最新版本。要获取服务器密钥指纹的MD5哈希值(旧的行为),该-E
选项可用于指定哈希算法:
ssh-keygen -E md5 -lf <(ssh-keyscan hostname 2>/dev/null)
如果使用dash
不具有进程替代功能的POSIX Shell(例如),则其他使用临时文件的解决方案将起作用。但是,对于较新版本的OpenSSH(自7.2起),可以使用简单的管道,因为ssh-keygen
它将接受-
为标准输入流的文件名,从而允许使用单行管道命令。
ssh-keyscan hostname 2>/dev/null | ssh-keygen -E md5 -lf -
ssh-keygen
从旧版本的OpenSSH读取FIFO /命名管道时出现问题。有空的时候我会研究这个问题(并更新我的答案)。
printf
在do_fingerprint()
函数中插入调试语句后,我发现在7.2之前的OpenSSH版本中,用于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
选项来增加详细程度(给定的信息量)
这是我编写的shell脚本(主要是Bourne shell,但是使用local
关键字,在大多数现代版本中都可用/bin/sh
)。像这样使用它ssh-hostkey hostname
。对于给定的主机名或IP地址,它将显示所有主机密钥的sha256和md5格式指纹。您也可以手动指定“ 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)
可以吗?