题 “在known_hosts中添加正确的主机密钥”/每个主机名的多个ssh主机密钥?


试图ssh到我控制的计算机,我收到了熟悉的消息:

@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@    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 a host key has just been changed.
The fingerprint for the RSA key sent by the remote host is
[...].
Please contact your system administrator.
Add correct host key in /home/sward/.ssh/known_hosts to get rid of this message.
Offending RSA key in /home/sward/.ssh/known_hosts:86
RSA host key for [...] has changed and you have requested strict checking.
Host key verification failed.

我确实改变了关键。我读了几十篇帖子,说解决这个问题的方法是删除旧的密钥 known_hosts 文件。

但我想要的是让ssh同时接受旧密钥和新密钥。错误消息中的语言(“Add correct host key“)建议应该有一些方法来添加正确的主机密钥而不删除旧主机密钥。

我无法弄清楚如何在不删除旧主机密钥的情况下添加新主机密钥。

这是可能的,还是错误信息只是极具误导性?


121
2017-10-13 14:01




这是生成错误的主机密钥。主机应该只有一个密钥。这与客户端或用户密钥无关。你有一个在不同主机之间浮动的IP地址吗? - David Schwartz
就我而言,我知道在不久的将来,我会在摆弄两把钥匙的同时摆弄一些东西。看来这对于你建议的具有多个主机情况的一个IP也很有用。主要是我想知道除了任何特定的实际应用之外,这对我自己的教育是否可行。 - Samuel Edwin Ward


答案:


  1. 获取服务器的rsa密钥:

    $ ssh-keyscan -t rsa server_ip
    # server_ip SSH-2.0-OpenSSH_4.3
    server_ip ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAwH5EXZG...
    
  2. 并在客户端上添加此密钥 ~/.ssh/known_hosts

    server_ip ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAqx9m529...(the offending key)
    server_ip ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAwH5EXZG...
    

126
2017-10-13 14:38



这有效!但是,我正在使用“HashKnownHosts”,因此条目看起来有点不合适。幸运的是,ssh_config(5)向我指出了ssh-keygen(1),它解释了我可以使用“ssh-keygen -H”来散列未散列的条目。谢谢! - Samuel Edwin Ward
这“有效”,但你没有验证密钥,所以你很容易受到mitm攻击...... - JasperWallace
@JasperWallace,只要第一步是通过安全连接完成(例如使用localhost),它应该是非常安全的,我认为 - ony
有没有办法从服务器收集所有密钥类型?有时您不知道它们是RSA,DSA,ECDSA,RSA1 ......等。 - Sopalajo de Arrierez
@SopalajodeArrierez同样的联机帮助页也说你可以用逗号分隔类型,所以这样做 ssh-keyscan -t rsa1,dsa,rsa,ecdsa,ed25519 server_ip  - 但找到的唯一理由 rsa1 和 dsa 密钥用于标识需要升级/重新配置的服务器 - kbolino


使用以下命令从known_hosts中删除该条目:

ssh-keygen -R *ip_address_or_hostname*

这将从中删除有问题的IP或主机名 的known_hosts 文件并尝试再次连接。

从手册页:

-R hostname
  从known_hosts文件中删除属于hostname的所有密钥。此选项对于删除散列主机很有用(请参阅-H选项   以上)。


74
2018-02-09 06:49



“如何在不删除旧主机密钥的情况下添加新主机密钥。” - Samuel Edwin Ward
这是最好的解决方案! - Thomas Decaux
这怎么有19票?它没有接近回答问题.. - Molomby
当我谷歌“自动获取git ssh更新主机密钥”时,你的问题就出现了。这个答案就是我要找的。打开一个我想要的新问题可能会将其作为副本关闭。 - Jason Goemaat
主机名也有效 - damluar


一个非常简单的方法是:

cp ~/.ssh/known_hosts ~/.ssh/known_hosts.bak

然后编辑known_hosts以清除原始密钥,然后使用以下命令ssh到主机:

ssh name@computer

它会自动添加新密钥;然后比较两个文件。像meld这样的程序是比较两个文件的好方法。然后合并文件以使known_hosts包含两个键

我保留两个密钥的“理由”是目标系统是多引导的,即使我敢说有一种方法可以在安装中同步密钥,但允许多个密钥似乎更简单。

编辑 2015/06

我现在应该添加,重新审视它,我注意到一种更简单的方法[只要条目可识别,通常来自主机名/ IP地址,除了引用其特定位置的错误消息之外];

  1. 编辑known_hosts以在“旧”条目的开头添加# known_hosts暂时
  2. 将[ssh连接到主机],同意提示“自动”添加新密钥
  3. 然后重新编辑known_hosts以删除#

甚至还有HostKeyAlias选项

ssh -o HostKeyAlias=mynewaliasforthemachine name@computer

然后,在ssh客户端在别名下添加新密钥之后,您可以编辑known_hosts以替换别名的“真实”主机名/ IP地址,或者使用别名选项连接到该主机的那个版本


16
2018-04-30 22:29



这'融合'? meldmerge.org - Samuel Edwin Ward
这就是融合:) apt-get / yum安装名称简直就是融合 - Mark
我做了一个你的建议的变体,它运行良好 - 而不是cp,mv,然后是ssh,然后cat~ / .ssh / known_hosts.bak~ / .ssh / known_hosts> tmp; mv tmp~ / .ssh / known_hosts - Peter N Lewis


我有一个覆盆子pi的问题,我用几个不同的系统启动(开发系统用于编译arm二进制文件,项目,xbmc等)并遇到了同样的问题。他们在本地网络上使用DHCP,而我的路由器总是重用相同的IP,因为MAC地址是相同的。我通过在hosts文件中使用不同的域名来解决它:

10.10.10.110 pi-dev
10.10.10.110 pi-xbmc
10.10.10.110 pi-etc

known_hosts文件按主机名保存指纹,因此即使它是相同的IP地址,每个唯一的主机名也会获得不同的条目。

我厌倦了每次使用新系统时都将名称添加到主机文件中,所以我想通过在ip地址上使用前导零来实现更加懒惰的方式:

$ ssh pi@10.10.10.110
$ ssh pi@010.10.10.110
$ ssh pi@10.010.10.110

(uncanonicalized)ip地址的每个变体都在known_hosts中获得它自己的条目。


7
2017-11-04 02:28



OpenSSH的人对我很明智,这个漏洞不再适用于更新的版本。 - Mike
您可以使用 CheckHostIP no 在 ~/.ssh/config 能够仍然使用漏洞。您甚至可以在那里定义别名,这样您就不必动摇 /etc/hosts 并定义 CheckHostIP no 仅适用于这3个主机名。 - GnP


如果您的客户端和服务器都具有OpenSSH 6.8或更高版本,则可以使用 UpdateHostKeys yes 你的选择 ssh_config 要么 ~/.ssh/config。例如:

Host *
    UpdateHostKeys yes

这使得SSH存储服务器必须拥有的所有主机密钥 known_hosts,当服务器更改或删除一个主机密钥时,密钥也会在您的密钥中更改或删除 known_hosts


2
2017-09-22 04:28



这是迄今为止最有用的答案!虽然如果主机密钥已经更改,它没有明确提供解决原始问题的方法,但所有其他答案都不安全,因为它们不验证新的主机密钥。此选项允许您对新主机密钥进行安全翻转。 - Jaap Eldering


我不明白你为什么要使用两个键,但你当然可以添加多个有效键 ~/.ssh/known_hosts 文件,但你必须手动完成。

另一种解决方案可能是使用 StrictHostKeyChecking=no 此特定主机的选项:

ssh -o StrictHostKeyChecking=no user@host

你可以把它放在你的别名中 ~/.profile 或类似的东西。

alias hc=ssh -o StrictHostKeyChecking=no user@host

1
2017-10-13 14:49



在这种情况下,StrictHostKeyChecking似乎没有帮助;显然它只指定主机不在known_hosts文件中时的行为。这里提到: gossamer-threads.com/lists/openssh/dev/45349#45349 - Samuel Edwin Ward
它在这里工作。您将收到警告,但登录仍在继续。 - Sven♦
那很奇怪。你在使用密码验证吗?你在使用OpenSSH吗? - Samuel Edwin Ward


如果你 只要 ssh到本地网络然后......

一个简单的解决方案是擦除旧密钥文件并将其替换为空密钥文件。这将允许您使用新密钥重新授权所有连接。如果您为本地网络之外的站点存储了ssh密钥,则需要确保初始连接是安全的,就像第一次连接到该服务器时一样。

例如

cp known_hosts known_hosts.old
rm known_hosts
nano known_hosts

然后按空格键,退格键cntl + x和'y'保存新缓冲区(文件)。这是不好的做法,但可以提供给你的不是经常在本地网络外进行ssh'ing(例如,uni或工作服务器)

在一个安全的本地网络上,这是安全的,因为你根本无法让一个人在中间攻击。

使用您理解的代码总是更好!


0
2018-06-15 21:44



擦拭整个 known_hosts 每次文件都会否定ssh提供的大部分安全性。 - kasperd
实际上,我认为在安全的内部网络上,理解代码和规避安全性比无意识地复制代码更安全。在外部网络上,情况会有所不同。 - Aaron


这么多的答案,但是很多,通过完全关闭严格的主机检查来放弃保护,或者破坏不相关的主机信息,或者只是强迫用户以交互方式接受密钥,可能在以后出现意外时。

这是一种简单的技术,允许您保留严格的主机检查,但是当您使用时,以受控方式更新密钥 期望 它要改变:

  • 删除旧密钥并在一个命令中更新

    ssh-keygen -R server.example.com && \
        ssh -o StrictHostKeyChecking=no server.example.com echo SSH host key updated.
    
  • 如果使用IP地址或其他主机名,请重复此操作。

这种方法的优点是它只对服务器重新键入一次。如果您尝试删除的服务器在已知主机文件中不存在,则大多数版本的ssh-keygen似乎都不会返回错误,如果这是您的问题,请按顺序使用这两个命令。

此方法还验证连接并为ssh命令(登录,更新主机密钥和输出)中的日志发出良好消息 SSH主机密钥已更新 然后立即退出。

如果您的ssh-keygen版本返回非零退出代码,并且您更喜欢无错误地处理此问题,无论是先前连接还是先前连接,只需按顺序使用这两个命令,忽略ssh-keygen命令上的任何错误。

如果使用此技术,则永远不需要更改ssh命令,或关闭主机检查,除非在该ssh命令期间。您可以确定将来的ssh会话可以正常工作而不会发生冲突或需要显式接受新密钥,只要上面的ssh命令运行时没有错误。


-1
2017-09-18 01:56





我有同样的问题。

我所做的只是 sudo nano /home/user/.ssh/ host_allow 并删除了密钥。

当我回到服务器时,它添加了一个新密钥。


-3
2018-05-18 11:31



关于为什么会发生这种情况的更多信息将有助于答案。 - Drew Khoury


使用sed命令删除有问题的行

OUTPUT: as show in above example
Offending key in /home/user/.ssh/known_hosts:86

删除已知主机中提到的第86行。

CODE: 
sed -i '86d' /home/user/.ssh/known_hosts

下次使用ssh访问时,系统会自动添加新密钥。

更新版本的ssh

使用:

ssh-keygen -R <hostname|ip address>

它将删除主机名条目并备份旧的 .known_host 如 known_hosts.old


-4
2018-06-14 05:47



“但我想要的是让ssh同时接受旧密钥和新密钥。”你的答案不会这样做。 - Samuel Edwin Ward