如何强制 ssh 从命令行接受新的主机指纹?
Posted
技术标签:
【中文标题】如何强制 ssh 从命令行接受新的主机指纹?【英文标题】:How can I force ssh to accept a new host fingerprint from the command line? 【发布时间】:2014-02-18 11:10:18 【问题描述】:我得到了标准
WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED!
IT IS POSSIBLE THAT SOMEONE IS DOING SOMETHING NASTY!
Someone could be eavesdropping on you right now (man-in-the-middle attack)!
It is also possible that the RSA host key has just been changed.
The fingerprint for the RSA key sent by the remote host is
错误信息。但是,执行命令的系统(Appworx)(我认为是 sftp,并不重要)是自动化的,即使在与第三方供应商确认这是有效更改之后,我也无法轻易接受新密钥。我可以添加一个可以从同一系统(和用户)执行的新 shell 脚本,但似乎没有命令或命令行参数告诉 ssh 接受密钥。我在手册页或 Google 上找不到任何内容。这肯定有可能吗?
【问题讨论】:
【参考方案1】:这里的答案是糟糕的建议。您永远不应该在任何真实世界的系统中关闭 StrictHostKeyChecking(例如,如果您只是在自己的本地家庭网络上玩游戏可能没问题 - 但其他任何事情都不要这样做)。
改为使用:
ssh-keygen -R hostname
这将强制更新 known_hosts
文件,以删除仅更新其密钥的一台服务器的旧密钥。
那么当你使用时:
ssh user@hostname
它将要求您确认指纹 - 就像任何其他“新”(即以前未见过的)服务器一样。
【讨论】:
请大家注意:这是唯一正确的答案!例如,在本地开发 Docker 容器上使用StrictHostKeyChecking no
,这些容器在每次更新映像时都会更改其主机密钥,但不要将其用于实时服务器!真的,你不想那样!
这描述了以交互方式添加密钥。因此,它不是唯一的答案,因为您可以提供 actual 键。这更好,因为您使用的是已知良好的副本。它还允许自动化。
您也可以使用StrictHostKeyChecking accept-new
接受新密钥,但在保存的密钥冲突时仍拒绝连接。
我同意大多数时候这是一个坏主意,但就我而言,我使用 SSH 从 CI 运行远程脚本。部署密钥受到限制,因此它唯一能做的就是运行该脚本,并且该脚本不接受任何参数。即使存在中间人攻击,也不会传输任何可能被破坏或被利用的信息。在这种情况下,我认为禁用主机密钥检查是非常合理的。也许我错过了一些安全隐患?
@RadonRosborough,MITM 将能够从脚本中读取指令和数据。他们将能够测试密钥的限制程度。最好更新 known_hosts:ssh-keyscan $target_host >> ~/.ssh/known_hosts
。解决问题太容易了,没有理由不去做。【参考方案2】:
以下是告诉您的客户信任密钥的方法。更好的方法是提前给它密钥,我在第二段中已经描述过。这是针对 Unix 上的 OpenSSH 客户端,所以我希望它与您的情况有关。
您可以设置StrictHostKeyChecking
参数。它有yes
、no
和ask
选项。默认为ask
。要在系统范围内设置它,请编辑/etc/ssh/ssh_config
;要为您设置它,请编辑~/.ssh/config
;并将其设置为单个命令,请在命令行上提供选项,例如
ssh -o "StrictHostKeyChecking no" hostname
如果您有权访问远程系统的主机密钥,另一种方法是提前将它们添加到您的known_hosts
文件中,以便 SSH 知道它们并且不会提出问题。如果这是可能的,那么从安全的角度来看会更好。毕竟,警告可能是正确的,而您确实可能会受到中间人攻击。
例如,下面是一个脚本,它将检索密钥并将其添加到您的 known_hosts 文件中:
ssh -o 'StrictHostKeyChecking no' hostname cat /etc/ssh/ssh_host_dsa_key.pub >>~/.ssh/known_hosts
【讨论】:
我并没有试图抑制警告。我已经拿到了,以后会拿到更多。我想要一个脚本,在收到警告后,我可以运行该脚本并让它回答“是”,而无需交互。我无法输入“是”。我希望 ssh 有一个“连接到此主机,回答是,然后断开连接”的参数,或者某种实现相同目的的方法。 您的命令有效,但我不确定它在做什么。谢谢你。我还向它添加了 Batchmode,以便它在进入密码提示时退出。非常感谢。 自动回答是是一个安全漏洞。它使您容易被网络钓鱼。除非您在私人开发环境中。那么这会很有帮助。您应该验证指纹+密码/用户名或使用 ssh 公钥/私钥。 我试图绕过检查一次,因为我试图连接到我的服务器是救援模式(因此我实际上是连接到不同的操作系统,使用一个- SSH 登录的时间密码)。我想保留当前的密钥。 糟糕的想法。检查其他答案和 cmets 以了解原因和更好的选择。 tldr:改用StrictHostKeyChecking=accept-new
。【参考方案3】:
虽然常识是不禁用主机密钥检查,但 SSH 本身有一个内置选项可以执行此操作。它相对未知,因为它是新的(在 Openssh 6.5 中添加)。
这是通过-o StrictHostKeyChecking=accept-new
完成的。
警告:仅当您绝对信任要通过 SSH 访问的 IP\主机名时才使用此选项:
ssh -o StrictHostKeyChecking=accept-new mynewserver.example.com
注意,StrictHostKeyChecking=no
会将公钥添加到~/.ssh/known_hosts
即使如果密钥已更改。
accept-new
仅适用于新主机。来自man page:
如果此标志设置为“accept-new”,则 ssh 将自动添加 用户已知主机文件的新主机密钥,但不允许 连接到具有更改的主机密钥的主机。如果这个标志 设置为“no”或“off”,ssh会自动添加新的主机密钥 到用户已知的主机文件并允许连接到主机 更改主机密钥以继续进行,但受到一些限制。 如果此标志设置为询问(默认),新的主机密钥将是 只有在用户确认后才添加到用户已知的主机文件中 那是他们真正想做的,而 ssh 会拒绝 连接到主机密钥已更改的主机。 在所有情况下都会自动验证已知主机的主机密钥。
为什么-o StrictHostKeyChecking=no
是邪恶的?
如果您不检查主机密钥,您可能会在另一台计算机上进行 SSH 会话(是的,这可以通过 IP Hijacking 进行)。然后可以使用您不拥有的敌对服务器来窃取密码和各种数据。 接受新的未知密钥也非常危险。 只有在对网络有绝对信任或服务器没有受到威胁的情况下,才应该这样做。 就个人而言,我仅在机器启动后立即使用cloud-init 在云环境中启动机器时使用此标志。
【讨论】:
【参考方案4】:由于您试图通过在执行 ssh-ing 的主机上运行 bash 脚本来自动执行此操作,并假设:
您不想忽略主机密钥,因为这会带来额外的安全风险。 您要 SSH 的主机上的主机密钥很少更改,如果更改,则有一个很好的众所周知的原因,例如“目标主机已重建” 您想运行此脚本一次以将新密钥添加到known_hosts
,然后不理会known_hosts
。
在你的 bash 脚本中试试这个:
# Remove old key
ssh-keygen -R $target_host
# Add the new key
ssh-keyscan $target_host >> ~/.ssh/known_hosts
【讨论】:
【参考方案5】:您只需更新从服务器发送的当前指纹。只需输入以下内容即可:)
ssh-keygen -f "/home/your_user_name/.ssh/known_hosts" -R "server_ip"
【讨论】:
【参考方案6】:获取 SSH 主机 IP(或 DNS 名称)列表输出到文件 > ssh_hosts
运行单行程序以填充控制节点上的 ~/.ssh/known_hosts(通常这样做是为了为 Ansible 运行准备目标节点)
注意:假设我们更喜欢 ed25519 类型的主机密钥
# add the target hosts key fingerprints
while read -r line; do ssh-keyscan -t ed25519 $line >> ~/.ssh/known_hosts; done<ssh_hosts
# add the SSH Key('s) public bit to target hosts `authorized_keys` file
while read -r line; do ssh-copy-id -i /path/to/key -f user@$line; done<ssh_hosts
【讨论】:
【参考方案7】:添加以下文件
~/.ssh/config
文件中的这个作为内容
StrictHostKeyChecking no
此设置将确保 ssh 不再要求指纹检查。 这应该非常小心地添加,因为这非常危险并且允许访问所有指纹。
【讨论】:
私人互联网,mb。我同意。不要在现实环境中这样做。 显然,它仅适用于您的 Internet VPC/网络中的私有网络主机。面向公众的主机不应该有这个。 这是一个非常冒险的建议,因为它没有说明这是一个巨大的安全漏洞,并且说明会在全局范围内而不是在Host
块内添加它。
@ChrisAdams 我希望你看到我之前关于何时添加的评论。
@vishalsahasrabuddhe 这是一个重要的限定词,它不在原始评论中,它仍然是鲁莽的,因为这会影响每个 SSH 连接,所以你在赌没有人会改变使用模式或在某处复制该配置别的。推荐StrictHostKeyChecking accept-new
或使用Host
只会削弱目标服务器的安全性会更安全。以上是关于如何强制 ssh 从命令行接受新的主机指纹?的主要内容,如果未能解决你的问题,请参考以下文章