当出现“主机密钥验证失败”时如何建立SSH密钥对

60

我已经在我的桌面电脑和两台服务器之间建立了ssh密钥对,从服务器到我的桌面电脑也是如此。但是,在重新安装操作系统后,我无法通过以下方式重新建立进入我的桌面电脑的密钥对:

mkdir ~/.ssh
chmod 700 ~/.ssh
ssh-keygen -t 
ssh-copy-id username@server

我收到以下错误信息:
(为了保护隐私,斜体中的名称已更改。我的桌面电脑是Ubuntu,但我找不到答案,请参阅此处
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @ 警告:远程主机标识已更改! @ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 有人可能在做一些恶意的事情! 现在可能有人正在窃听您(中间人攻击)! 也有可能RSA主机密钥刚刚被更改。 远程主机发送的RSA密钥指纹是 ab:cd:ef:gh 请联系您的系统管理员。 添加正确的主机密钥到/home/user/.ssh/known_hosts以消除此消息。 /home/user/.ssh/known_hosts中的冒犯性密钥:1 RSA主机密钥已更改并且您要求进行严格检查。 主机密钥验证失败。

https://stackoverflow.com/q/58169386/4393351 - KushalSeth
11个回答

128
如果主机密钥过期或被更改(例如,服务器端进行了新的安装),那么就会出现问题,因此它不再与您的known_hosts中的密钥匹配。
您可以删除当前与主机关联的密钥,并尝试再次进行SSH连接。这样可以确保客户端和服务器都识别到新的密钥。
ssh-keygen -R hostname

这将从known_hosts文件中删除有问题的密钥。
手册中的条目如下:

-R hostname 从known_hosts文件中删除属于hostname的所有密钥。此选项可用于删除哈希主机(参见上面的-H选项)。


1
我也遇到了同样的问题,但是这是真实存在的。我的笔记本电脑在家和公司两个网络之间切换,而且有重叠部分。我需要在工作时ssh到A机器,在家时ssh到B机器,但是这两台机器具有相同的IP地址。是否可能在known_hosts文件中保留这两个机器的有效条目,尽管存在IP地址冲突? - rev
3
“Host key verification failed” 表示远程主机的主机密钥已更改。ssh 将远程主机的主机密钥存储在 ~/.ssh/known_hosts 中。您可以手动编辑该文本文件并删除旧密钥(您可以在错误消息中看到行号),或使用ssh-keygen -R 主机名 - Tarun Gupta
请注意:在本地计算机上运行命令,而不是远程服务器。或者您可以在本地计算机上打开“~/.ssh/known_hosts”文件,并手动删除该行。 - Eddy
man ssh-keygen: -R hostname 从已知主机文件中删除所有属于主机名的密钥。此选项对于删除散列主机(参见上面的-H选项)非常有用。 - AnneTheAgile

19

很有可能,远程主机的IP地址或IP别名不在~/.ssh/known_hosts文件中。您可以使用以下命令将主机名添加到known_hosts文件中。

$ssh-keyscan -H -t rsa ip_or_ipalias >> ~/.ssh/known_hosts

此外,我已经生成了以下脚本以检查特定的IP地址或IP别名是否在know_hosts文件中。

#!/bin/bash
#Jason Xiong: Dec 2013   
# The ip or ipalias stored in known_hosts file is hashed and   
# is not human readable.This script check if the supplied ip    
# or ipalias exists in ~/.ssh/known_hosts file

if [[ $# != 2 ]]; then
   echo "Usage: ./search_known_hosts -i ip_or_ipalias"
   exit;
fi
ip_or_alias=$2;
known_host_file=/home/user/.ssh/known_hosts
entry=1;

cat $known_host_file | while read -r line;do
  if [[ -z "$line" ]]; then
    continue;
  fi   
  hash_type=$(echo $line | sed -e 's/|/ /g'| awk '{print $1}'); 
  key=$(echo $line | sed -e 's/|/ /g'| awk '{print $2}');
  stored_value=$(echo $line | sed -e 's/|/ /g'| awk '{print $3}'); 
  hex_key=$(echo $key | base64 -d | xxd -p); 
  if  [[ $hash_type = 1 ]]; then      
     gen_value=$(echo -n $ip_or_alias | openssl sha1 -mac HMAC \
         -macopt hexkey:$hex_key | cut -c 10-49 | xxd -r -p | base64);     
     if [[ $gen_value = $stored_value ]]; then
       echo $gen_value;
       echo "Found match in known_hosts file : entry#"$entry" !!!!"
     fi
  else
     echo "unknown hash_type"
  fi
  entry=$((entry + 1));
done

这对我有效。我正在使用CI并且想要使用Deployer/Envoy进行SSH连接,因此我需要先添加主机。 - thefallen

5

步骤1:$Bhargava.ssh#

ssh-keygen -R 199.95.30.220

步骤2:$Bhargava.ssh#

ssh-copy-id hostname@199.95.30.220

          Enter the the password.........

步骤三:Bhargava .ssh #

使用ssh命令连接到主机名为199.95.30.220的服务器:

Welcome to Ubuntu 14.04.3 LTS (GNU/Linux 3.13.0-68-generic x86_64) * Documentation: https://help.ubuntu.com/ Ubuntu 14.04.3 LTS server : 228839 ip : 199.95.30.220 hostname : qt.example.com System information as of Thu Mar 24 02:13:43 EDT 2016 System load: 0.67 Processes: 321 Usage of /home: 5.1% of 497.80GB Users logged in: 0 Memory usage: 53% IP address for eth0: 199.95.30.220 Swap usage: 16% IP address for docker0: 172.17.0.1 Graph this data and manage this system at: https://landscape.canonical.com/ Last login: Wed Mar 23 02:07:29 2016 from 103.200.41.50

主机名@qt:~$


谢谢!但是这与上面的答案有什么不同吗? - David LeBauer

4
如果您确定服务器正确,sed -i 1d ~/.ssh/known_hosts 将会删除本地 ~/.ssh/known_hosts 文件中的第一行。下次连接时,新的正确密钥将会添加到该文件中。

2
不错的解决方案。但是这是否假定所涉及的服务器(在本例中是我的桌面)是文件中的第一行?我发现“ssh-keygen -F hostname”会告诉我们主机名密钥所在的行,因此假设n是行号,sed -i nd ~/.ssh/know_hosts应该可以工作。 - David LeBauer
3
@David:您上面粘贴的输出显示“Offending key in /home/user/.ssh/known_hosts:1”。您已经知道行号,不需要运行ssh-keygen -F - ephemient
1
我没有意识到那个数字是什么...谢谢你指出来。 - David LeBauer

2
这意味着您的远程主机密钥已更改(可能是主机密码更改)。
您的终端建议以root用户身份执行此命令。
$ ssh-keygen -f "/root/.ssh/known_hosts" -R [www.website.net]:4231

您需要从您的电脑/服务器中的主机列表中删除该主机名。复制建议的命令并以root用户身份执行。

$ sudo su                                                            // Login as a root user

$ ssh-keygen -f "/root/.ssh/known_hosts" -R [www.website.net]:4231   // Terminal suggested command execute here
Host [www.website.net]:4231 found: line 16 type ECDSA
/root/.ssh/known_hosts updated.
Original contents retained as /root/.ssh/known_hosts.old

$ exit                                                               // Exist from root user

$ sudo ssh root@www.website.net -p 4231                              // Try again

希望这个能够成功。


2
当主机密钥过期或更改时,会出现此问题。您可以删除主机正在使用的密钥,然后再次尝试ssh,以便添加已知于客户端和服务器的新密钥。
您可以使用cat /.ssh/known_hosts检查与您的主机关联的密钥。现在,您可以手动删除主机密钥或使用ssh-keygen选项。您可以执行以下任一选项:
1. 手动删除密钥 vim /.ssh/known_hosts 删除与您的主机关联的密钥。
2. 使用ssh-keygen删除密钥 ssh-keygen -R your_host_or_host_ip 这将删除与主机关联的密钥。
现在,您可以像往常一样ssh到您的主机,并被要求是否继续连接到该主机。一旦输入yes,此主机将添加到您的/.ssh/known_hosts中,并更新密钥。现在,您应该能够访问您的主机。

2
有时候在串行控制台上工作时,使用详细模式-v检查上述命令时会显示/dev/tty不存在,而实际上它是存在的。
在这种情况下,只需删除/dev/tty并将/dev/ttyS0创建为/dev/tty的符号链接即可。

1

首先,您应该删除现有的密钥。在大多数基于Linux的操作系统中,SSH密钥将保存在此文件“/root/.ssh/known_hosts”中,因此为了删除与主机相关的密钥,将使用以下命令:

ssh-keygen -f "/root/.ssh/known_hosts" -R [主机名]

此致 K1


0

当您尝试使用SSH连接远程服务器时:

$ ssh username@ip_address

然后出现错误,解决方法如下:

$ ssh-keygen -f "/home/local_username/.ssh/known_hosts" -R "ip_address"

0
rm -f /home/user/.ssh/known_hosts

或者打开它并删除有问题的IP/主机名的条目

(附言:在您发布的错误消息中,它确切地告诉您这一点)


我曾经尝试过这个,但是我从主机(我的桌面电脑)而不是客户端(我从桌面电脑登录的服务器)中删除了文件。谢谢你的提醒... - David LeBauer
7
你不必删除整个文件... - ephemient
@ephemient:在演示如何删除整个文件之后,这一点已经得到了充分的注意;)我打开了我的电脑上的known_hosts文件,它看起来对我来说相当神秘。我喜欢你的答案。只是看起来我比你稍微快了一步! - Matt Phillips
@ephemient 另外,我很想知道您是否知道删除整个文件会有什么缺点,除了 (下一次) 第一次尝试连接到已知主机的 IP 时会弹出一个警告。它实际上可能会破坏任何东西吗?还是只是一个略微烦人的警告? - Matt Phillips

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接