我正在尝试ssh -v user@host false 2>&1 | grep "Server host key",但是如果未设置基于密钥的身份验证,则会挂起等待密码。

#1 楼

您可以通过组合ssh-keyscanssh-keygen来实现此目的:

评论


也许ssh-keygen -l -f-<(ssh-keyscan主机)可以吗?

–用户
2014-4-28 13:50



OpenSSH> = 7.2 ssh-keyscan可以从stdin中读取:ssh-keyscan host | ssh-keygen -lf-

–mykhal
16 Mar 4 '16 at 19:14

只需做:ssh-keygen -l -f <(ssh-keyscan主机)

–克里斯托弗(Christopher)
16-10-28在4:59

ssh-keygen -l -f-的工作原理与ssh-keygen 7.2及更高版本相同。如Anthony Geoghegan或ssh-keyscan host 2> / dev / null |的答案所述,它会为STDERR生成一些注释行,这些注释行可以被过滤掉。 ssh-keygen -l -f-

–塞德里克·奈特
16年11月16日在16:17

新版本的openssh(至少为7.2)将指纹显示为SHA256(例如:2048 SHA256:gYz11pP / v / SMzUD58jrZ + m1EFC1pvyMxvIrg4PYlvDY),如果您希望使用旧格式,请提供-E md5并看到类似2048 MD5:0b:f5:49:d2:69:a5:49:2c:d9:45:75:87:4d:a0:7d:33。

– MatrixManAtYrService
18年8月21日在0:30



#2 楼

我最近不得不自己做这个,所以我想我要添加一个答案,该答案显示
如何使用进程替换在一行中完成此操作(使用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(从版本

对于ssh-keyscan的旧版本(在OpenSSH版本5.1之前),
默认密钥类型已过时rsa1(SSH协议1),因此需要明确指定密钥类型:

ssh-keyscan -t rsa,dsa hostname


获取Base64密钥的指纹哈希

ssh-keyscan以Base64编码
格式打印SSH服务器的主机密钥。要将其转换为指纹哈希,可以将ssh-keygen实用程序与其-l选项一起使用,以打印指定的公共密钥的指纹。

如果使用Bash,Zsh(或Korn外壳),可以使用过程
替代
以方便使用单层衬里:

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)


使用管道

如果使用POSIX shell(例如如dash),它不具有进程替换功能,
其他使用临时文件的解决方案也可以使用。但是,对于OpenSSH的较新版本(自7.2起),可以使用简单的管道,因为ssh-keygen
接受-作为标准输入流的文件名,从而允许单行
管道命令。

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


评论


好的和彻底的答案,这肯定比拥有临时文件要好!我是否建议您在流程替代版本的开头提供TL; DR,以使不耐烦的人们更快地找到它? :)

– goncalopp
16 Mar 9 '16 at 21:07

在Ubuntu 14.04 LTS上似乎不起作用;我收到错误“ / dev / fd / 63不是公共密钥文件”。子过程确实起作用。

–梅勒
16-10-18在7:26



@melleb我在可以访问的12.04系统上找到了相同的东西。我怀疑来自OpenSSH较旧版本的ssh-keygen从FIFO /命名管道读取时出现问题。有空的时候我会研究这个问题(并更新我的答案)。

– Anthony Geoghegan
16-10-18在9:51

@melleb在花费大量时间下载各种源代码版本并在do_fingerprint()函数中插入调试printf语句之后,我发现在7.2之前的OpenSSH版本中,ssh-keygen用来读取文件的函数无法处理named管道(FIFO)很好,因此进程替换方法将不起作用。

– Anthony Geoghegan
16-10-18在13:35

此方法有效,但是如果使用它来验证指纹,则用户应注意存在竞争状况:使用此命令检查的指纹不一定是所获取密钥的指纹,除非您在调用ssh- Keygen就可以了。

– CodeGnome
18年8月31日在17:11

#3 楼

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

评论


这些示例是否假定SSH始终在端口22上运行?如果ssh在非标准端口上侦听怎么办?

–马丁·维格特(Martin Vegter)
2014年12月1日21:33

@MartinVegter(对Guarin42进行解释,他无法评论:) nmap具有-p选项,可以指定端口,例如-p22000。也可以使用-vv选项来增加详细程度(给定的信息量)

– goncalopp
15年1月29日在11:52

#4 楼

filezilla以十六进制格式显示用md5散列的密钥。

要在ubuntu linux机器上找到此命令,请使用以下命令:

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


注意:将“ localhost”替换为您机器的ip希望检查。

评论


这在Ubuntu 18上对我有用,但是请注意,您将获得localhost 127.0.0.1或domain.tld的不同结果。检查指纹以获取您所关注的URL〜!

– FreeSoftwareServers
20 Mar 19 '20在22:16

#5 楼

这是一个Shell脚本(主要是Bourne shell,但是使用local关键字,在大多数现代/bin/sh中都可用),我已经为此编写了代码。像ssh-hostkey hostname一样使用它。对于给定的主机名或IP地址,它将显示所有主机密钥的sha256和md5格式指纹。您还可以手动将“ md5”或“ sha256”指定为第二个参数,以仅显示该特定格式。在其他答案中)。临时文件使用/dev/shm(共享内存)(如果有)。

#!/bin/sh
usage () {
  printf '%s\n' "Usage: ssh-hostkey HOSTNAME [FPRINTHASH]"
}

ssh_hostkey () {
  local host=""
  local fprinthash=""
  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 "$@"


评论


这是使用命令行选项包装低级工具的不错的演示。包括一个如何使用共享内存/ dev / shm的好处,我不知道这样做很方便。感谢分享!

–核心
20年7月23日在19:49

#6 楼

对于我自己的服务器,我使用以下命令:
ssh-keygen -l -E md5 -f <(cat /etc/ssh/ssh_host_*_key.pub)
ssh-keygen -l -E sha256 -f <(cat /etc/ssh/ssh_host_*_key.pub)