我有一个充满 ssh 私钥的目录,我想在不登录的情况下检查哪些服务器接受哪些密钥。如何才能做到这一点,而不使用 ssh-add 将 ssh 密钥添加到我的身份验证客户端或登录在服务器上? ssh 如何知道应该尝试使用哪些密钥进行身份验证?服务器是否发送它可以使用的密钥的指纹,或者客户端是否发送其所有指纹,然后服务器检查它们?
答案1
你可以使用类似的东西:
#!/bin/bash
KEYPATH=~/.ssh/*
HOSTS=( localhost hosta hostb )
probekey ()
{
for privkey in $KEYPATH
do
if [[ "$(file $privkey)" =~ "private" ]]
then
#echo "Probing key $privkey for host $1"
ssh -i "${privkey}" -o "IdentitiesOnly yes" -o "PreferredAuthentications publickey" -o "ControlMaster no" "$1" exit 2>/dev/null
if [ "$?" == "0" ]
then
echo "Key ${privkey} matches for host $1"
fi
fi
done
}
for HOST in ${HOSTS[@]}
do
probekey $HOST
done
该脚本的主要作用是迭代主机数组 ( $HOSTS
) 并执行该probekey
功能。该函数遍历 中的文件列表$KEYPATH
,检查文件类型是否包含 private(对于 RSA 或 DSA 私钥文件),如果匹配,则ssh
使用该特定密钥启动与主机的连接。如果连接成功,则返回码为 0,并打印一条消息。
这不是问题的准确答案,因为它做登录主机(当密钥匹配时)并执行exit
命令再次直接注销。
答案2
如果不登录,您无法检查服务器上接受哪些密钥。了解密钥是否被接受的唯一方法是尝试使用它登录。
如果有一种方法可以列出帐户接受的密钥,这将侵犯隐私,并且在某些情况下会更容易泄露。 SSH 甚至不会告诉您帐户名是否有效:拒绝登录就是拒绝登录,无论是因为帐户名未知还是因为身份验证数据无效。否则至少会暴露谁在机器上拥有帐户,从而侵犯隐私。它还将使针对弱密码帐户的暴力攻击变得更容易,并且更难以在日志和反入侵系统中检测到,因为攻击者可以专注于现有帐户。
由 SSH 客户端选择尝试发送到服务器的密钥。对于 OpenSSH,可以使用IdentityFile
配置选项(-i
命令行选项)进行配置,并选择要加载到 ssh-agent 中的密钥或指定IdentitiesOnly
配置选项。服务器向客户端发送质询(随机生成的字符串)。客户端必须回复使用私钥加密签名的质询以及相应的公钥。服务器验证签名是否是使用该密钥的质询的有效签名,以及请求的用户名和公钥的组合是否有效。 (通常,最后一部分意味着用户~/.ssh/authorized_keys
文件中有一行包含此公钥。)允许客户端进行多次尝试(几次后服务器将放弃并关闭连接)。
如果您忘记了哪个密钥对哪个服务器有效,最简单的方法是登录到服务器并检查~/.ssh/authorized_keys
那里的文件。如果您知道登录该服务器的唯一方法是尝试每个密钥直到一个成功,那么您就必须这样做(这当然会告诉您可以使用什么密钥,所以您不需要阅读~/.ssh/authorized_keys
) 。如果您必须对同一个帐户进行多次尝试,请做好准备,让服务器在您完成之前关闭连接;等待几秒钟,然后重试。
为了将来参考,如果您有许多不同的密钥,请维护一个具有适合每个主机的.ssh/config
正确指令的密钥。IdentityFile
¹我正在简化实际协议,仅保留此处必要的内容。