当我为用户加载私钥时,我可以运行ssh-copy-id user@remotehostname
并提示输入密码。输入正确的密码后,我现在可以使用密钥登录。我以前总是使用此命令-i <path to public key>
作为参数运行,但现在意识到我不需要公钥的路径。
当我以 user@hostname 身份登录时,我查看 .ssh/authorized_keys 文件,并看到我的私钥匹配的公钥,这让我感到困惑 - 我从未提供过公钥。
ssh-copy-id 如何知道哪个公钥与我运行命令时本地加载的私钥匹配?当我不提供授权密钥文件时,它如何知道要添加什么内容?
我希望我说得清楚 - 我一直在运行ssh-copy-id -i <public key>
,这对我来说是有意义的 - 它登录并将公钥复制到授权密钥文件。但是,如果我不提供公钥(即我ssh-add <private key>
在运行 ssh-copy-id 之前运行),只要我加载了私钥,它仍然可以工作,并且我不明白它如何获取公钥。
编辑:为了澄清,我没有保留默认的 id*.pub 命名约定。因此,我在手册页中看到的有关搜索 id*.pub 的逻辑似乎并不适用。事实上,我可以创建一个名为 randompair 的密钥对,加载 randompair,将 rendompair.pub 重命名为 newname.pub,运行 ssh-copy-id ,它仍然加载正确的公钥。
看看 bash 脚本本身让我有点困惑它是如何实现这一点的。
答案1
这在最新系统的手册页中有很好的记录。请注意,该脚本有多个不同版本;架构Linux和RHEL/CentOS似乎有相同的版本Debian/Ubuntu, 但自由BSD有稍微不同的选项。
默认情况下,ssh-copy-id
调用ssh-add -L
会列出您在 SSH 代理中注册的密钥。ssh-add -L
输出您在代理中拥有其私钥的公钥列表。您可能想知道代理如何做到这一点,因为您也没有向其传递公钥。答案是,总是可以从私钥重建公钥(对于 SSH 支持的所有密码系统都是如此,但大多数不支持)。然而,这只适用于密钥的“数学”部分。公钥文件还可以包含注释(您可以使用 进行设置ssh-keygen -C
),并且代理不会加载此注释,因此如果您使用ssh-copy-id
并且它通过代理获取密钥,则远程主机不会在 中包含此注释authorized_keys
。
如果没有正在运行的代理或者没有任何密钥,最近的 Linuxssh-copy-id
会查找(直接从手册页)
匹配的最新文件:
~/.ssh/id*.pub
,(不包括匹配 的文件~/.ssh/*-cert.pub
),因此,如果您创建的密钥不是您想要ssh-copy-id
使用的密钥,只需touch(1)
在您首选密钥的.pub
文件上使用即可将其恢复为最新的。
旧版本的脚本和非 Linux 版本没有这种最新文件行为。据我记得,即使是较旧的版本也不会探测代理,而只是~/.ssh/id_rsa.pub
默认读取默认路径。
答案2
ssh-copy-id 使用 [1] ssh-add -L 命令,该命令允许 [2]
您可以查看 ssh-agent 当前维护的身份的公钥。
所以,如果没有提供-i,它可以通过这种方式找到它。