已知主机中实际上包含什么内容?

70

在运行 ssh user@foo.com 命令之前,我没有 .ssh 目录。

这个命令创建了一个 .ssh 目录,并在其中放置了一个名为 known_hosts 的文件。

该文件中包含了如下的一些文本。

foo.com,107.180.00.00 ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAuJfqSnraBz//Ux4j/hZpLv2eYUxNUgCk+9ClqoSgfcu4vXbWtUGSjo75UVQf+uguOeBnRLppJJ3mt0R5c/PPcawUGWfffk33t+biYcqra9xUcyfiGtO/Icko2L1J0EYTXM/8x8VK6UYFMfad2gltnZRa8Am50oHTXot1Df0RljUBxvh/UhmTJUrODpyrl2xY1OMWjM+S6uYCMNeSQGEpNfsWiCIStRnctMZSxiYJOLTSC4F2GF7B8pYFBn5rSwVHp17WCdO+4BZfwvH3HSSH8IWoyFhki+NlG912SEBJXcryvc0JPfAB9DTB4mRImjgrRT8vz5QeaCDrh8k4/A+U1fff

我原以为这可能是从我的服务器中提取的公钥或私钥,但事实并非如此。

这是什么,并且它有什么作用?

我只是想更多了解SSH及其工作原理。例如,在这种情况下,我没有在本地机器上设置私钥,因此像预期的那样提示输入密码。

研究

根据https://security.stackexchange.com/questions/20706/what-is-the-difference-between-authorized-key-and-known-host-file-for-ssh所说,它应该是服务器的公钥。


但事实并非如此。你认为是什么原因呢?你是否阅读了 sshd(8) 的手册页面,其中包含了该文件的描述和格式? - Jakuje
2个回答

42

这个文件实际上是你的个人证书颁发机构。它是你确定准确的所有SSH服务器主机公钥的列表。known_hosts中的每个条目都是一个由三个或更多空格分隔字段组成的大行,如下所示:

a. 一个或多个服务器名称或IP地址,用逗号连接在一起。

foo.com,107.180.00.00

b. 密钥类型。

ssh-rsa

c. 编码后保持ASCII范围内的公钥数据本身。

AAAAB3NzaC1yc2EAAAABIwAAAQEAuJfqSnraBz//Ux4j/hZpLv2eYUxNUgCk+9ClqoSgfcu4vXbWtUGSjo75UVQf+uguOeBnRLppJJ3mt0R5c/PPcawUGWfffk33t+biYcqra9xUcyfiGtO/Icko2L1J0EYTXM/8x8VK6UYFMfad2gltnZRa8Am50oHTXot1Df0RljUBxvh/UhmTJUrODpyrl2xY1OMWjM+S6uYCMNeSQGEpNfsWiCIStRnctMZSxiYJOLTSC4F2GF7B8pYFBn5rSwVHp17WCdO+4BZfwvH3HSSH8IWoyFhki+NlG912SEBJXcryvc0JPfAB9DTB4mRImjgrRT8vz5QeaCDrh8k4/A+U1fff

d. 任何可选的注释数据。

还有!!这个帖子可能对你有用:

https://security.stackexchange.com/a/20710


5
但是它从哪里获取这个公钥呢? - cade galt
1
@cadegalt,服务器通常会自动生成主机密钥并将其写入/etc/ssh/ssh_host_rsa_key - wisbucky
@wisbucky,你提到的文件没有包含公钥 - Victor Yarema
2
@cadegalt,sshd 具有多个用于与 ssh 客户端进行安全通信的密钥。我认为在每种特定情况下,它都会选择客户端支持的最安全的密钥。在连接初始化期间发送给客户端的公钥可以是存储在 /etc/ssh 目录中的任何一个 *.pub 文件中的公钥。您可以使用命令 find /etc/ssh -name '*.pub' 枚举这些文件。或者您可以使用 find /etc/ssh -name '*.pub' -print -exec cat {} \; -exec echo \; 命令查看这些文件的内容。 - Victor Yarema
2
@VictorYarema 您是正确的,我的错误。我应该说服务器的公钥在服务器的 /etc/ssh/*.pub 上。 - wisbucky

14
为了补充上面的回答和您的评论, SSH会话有四个构建块:
  1. 加密(每个会话后通过密钥交换派生对称密钥)
  2. 数据完整性(MAC,例如SHA,HMAC)
  3. 密钥交换方法
  4. 公钥方法或主机密钥方法

SSH算法协商涉及一个密钥交换状态机,当发送SSH_MSG_KEXINIT消息以及算法列表时,该过程开始。

密钥交换方法或简称kex指定用于加密和主机身份验证主机公钥(ssh-rsa, ssh-dss ..),并将其发送到客户端。以下步骤是使用Diffie hellman密钥交换算法进行kex的基本步骤:

引用RFC https://www.rfc-editor.org/rfc/rfc4253

用于交换密钥的步骤如下。其中C是客户端;S是服务器;p是一个大的安全素数;g是GF(p)子群的生成器;q是子群的阶;V_S是S的标识字符串;V_C是C的标识字符串;K_S是S的公共主机密钥;I_C是C的SSH_MSG_KEXINIT消息,I_S是S的SSH_MSG_KEXINIT消息,在此部分开始之前已经交换过。

  1. C生成一个随机数x(1 < x < q),并计算e = g^x mod p。C将e发送给S。
  1. S生成一个随机数y(0 < y < q),并计算f = g^y mod p。S接收e。它计算K = e^y mod p,H = hash(V_C || V_S || I_C || I_S || K_S || e || f || K)(这些元素根据其类型编码;请参见下文),S使用他的私有主机密钥在H上签名并发送(K_S || f || s)给C。签名操作可能涉及第二次哈希运算。 C验证K_S是否真的是S的主机密钥(例如,使用证书或本地数据库)。C也可以接受没有验证的密钥;然而,这样做将使协议对主动攻击不安全(但出于许多环境中的实际原因,短期内可能是可取的)。然后,C计算K = f^x mod p,H = hash(V_C || V_S || I_C || I_S || K_S || e || f || K),并验证H上的签名s。 在某些系统中,步骤三中提到的本地数据库可以是.ssh/known_hosts文件。 因此,回答您的问题,公钥在密钥交换期间由主机发送给客户端。 以下是当前定义的公钥和/或证书格式: ssh-dss REQUIRED sign Raw DSS Key ssh-rsa RECOMMENDED sign Raw RSA Key pgp-sign-rsa OPTIONAL sign OpenPGP证书(RSA密钥) pgp-sign-dss OPTIONAL sign OpenPGP证书(DSS密钥)

1
长话短说,我不需要在任何时候生成此密钥,它是通过您发布的链接指定的协议完成的。 - cade galt
如果您是ssh客户端,则无需生成主机密钥。 - cmidi
@cmidi,有没有一种方法可以在终端中使用此密钥来连接,而不是通过ssh命令使用user@host? - ShifraSec

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