我正在学习SSH协议的基础知识。我对以下2个文件的内容感到困惑:


~/.ssh/authorized_keys:保存服务器的授权公共密钥列表。当客户端连接到服务器时,服务器通过检查存储在此文件中的已签名公钥来对客户端进行身份验证
~/.ssh/known_hosts:包含用户访问的SSH服务器的DSA主机密钥。该文件对于确保SSH客户端连接正确的SSH服务器非常重要。

我不确定这意味着什么。请帮忙。

评论

在Unix和Linux上类似的问题:基于SSH密钥的身份验证:known_hosts与authorized_keys

#1 楼

使用known_hosts文件,客户端可以对服务器进行身份验证,以检查它是否未连接到模仿者。 authorized_keys文件允许服务器对用户进行身份验证。

服务器身份验证

建立SSH连接时发生的第一件事就是服务器发送其公钥。客户端,并向客户端证明(由于公用密钥加密)知道关联的私钥。这将对服务器进行身份验证:如果协议的这一部分成功完成,则客户端将知道服务器是它声称的身份。

客户端可以检查服务器是否是已知服务器,而不是某些试图假冒正确服务器的恶意服务器。 SSH仅提供一种简单的机制来验证服务器的合法性:它在客户端计算机上的~/.ssh/known_hosts文件(还会有一个全系统文件/etc/ssh/known_hosts)中记住您已连接的服务器。第一次连接服务器时,需要通过其他某种方式进行检查,以确保服务器提供的公钥确实是您要连接的服务器的公钥。如果您具有要连接的服务器的公钥,则可以将其手动添加到客户端上的~/.ssh/known_hosts

known_hosts可以包含受支持的任何类型的公钥SSH实现,而不仅仅是DSA(还包括RSA和ECDSA)。

在向服务器发送任何机密数据之前,必须先对服务器进行身份验证。特别是,如果用户身份验证涉及密码,则不得将密码发送到未经身份验证的服务器。

用户身份验证

服务器仅在以下情况下允许远程用户登录:该用户可以证明他们有权访问该帐户。根据服务器的配置和用户的选择,用户可以提供几种形式的凭据之一(下面的列表并不详尽)。


用户可以提供他尝试登录的帐户的密码;然后,服务器将验证密码是否正确。
用户可以出示公共密钥并证明他拥有与该公共密钥关联的私有密钥。这与用于验证服务器的方法完全相同,但是现在用户正在尝试证明其身份,而服务器正在对其进行验证。如果用户证明自己知道私钥并且公钥在帐户的授权列表中(服务器上的~/.ssh/authorized_keys),则可以接受登录尝试。
另一种类型的方法涉及委托对用户进行身份验证的工作的一部分到客户端计算机。当许多机器共享相同的帐户时,这会在受控环境(例如企业)中发生。服务器通过与另一端使用的相同机制来认证客户端计算机,然后依靠客户端来认证用户。


评论


谢谢,这是非常有帮助的。正确地说,在客户端上维护了known_hosts文件,而在服务器上维护了authorized_key文件

– Ankit
2012年9月28日在7:25

@Ankit是的,就是这种情况。

–吉尔斯'所以-不再是邪恶的'
2012-09-28 14:38

我在服务器上都有两个文件,并通过SSH对其进行了测试。但是这两个文件具有不同的内容。那么这些文件中的密钥不同吗?

– Timo
18年4月11日在8:19

@Timo按键完全无关。一个是机器的钥匙,另一个是用户的钥匙。

–吉尔斯'所以-不再是邪恶的'
18年4月11日在14:06

@Gilles因此,一旦将服务器公钥的条目添加到客户端计算机中的known_hosts文件中,两者之间的任何后续ssh会话都不需要服务器证明其具有正确的私钥吗?

–极客
19年8月30日在11:53

#2 楼

SSH使用这两个文件,但它们的用途完全不同,这很容易解释您的困惑。
授权密钥
默认情况下,SSH使用由主机OS管理的用户帐户和密码。 (嗯,实际上是由PAM管理的,但是这种区别在这里可能不太有用。)这意味着,当您尝试使用用户名'bob'和某些密码连接到SSH时,SSH服务器程序将询问操作系统“我有个叫“ bob”的人告诉我他的密码是“ wonka”。我可以让他进入吗?”如果答案是肯定的,则SSH允许您进行身份验证,然后继续进行自己的尝试。
除密码外,SSH还允许您使用所谓的公共密钥加密技术来识别您的身份。具体的加密算法可能会有所不同,但通常是RSA或DSA,或更近期的是ECDSA。无论如何,使用ssh-keygen程序设置密钥时,都会创建两个文件。一个是您的私钥,另一个是您的公钥。名称是不言自明的。通过设计,公钥可以像蒲公英种子一样散落在风中,而不会影响您。私钥应始终保持严格的保密状态。
因此,您要做的就是将公钥放入authorized_keys文件中。然后,当您尝试使用用户名'bob'和您的私钥连接到SSH时,它将询问操作系统“我叫这个人叫'bob',可以在这里吗?”如果答案是肯定的,则SSH将检查您的私钥并验证authorized_keys文件中的公钥是否与其配对。如果两个答案都是肯定的,则允许您进入。
已知主机
authorized_keys文件用于认证用户的方式非常相似,known_hosts文件用于认证服务器的方式。每当在新服务器上配置SSH时,它始终会为服务器生成公用和专用密钥,就像为用户所做的一样。每次您连接到SSH服务器时,它都会向您显示其公钥,并证明它拥有相应的私钥。如果没有公用密钥,则您的计算机会要求它并将其添加到known_hosts文件中。如果您有钥匙,并且钥匙匹配,则可以立即连接。如果密钥不匹配,则会收到严重的警告。这就是事情变得有趣的地方。密钥不匹配通常发生的3种情况是:

服务器上更改了密钥。这可能是由于重新安装操作系统或在某些操作系统上更新SSH时重新创建了密钥。
您要连接的主机名或IP地址曾经属于其他服务器。这可能是地址重新分配,DHCP或类似的东西。
正在发生恶意的中间人攻击。这是密钥检查试图保护您免受攻击的最大事情。

在这两种情况下,SSH程序known_hostsauthorized_keys都使用公共密钥加密技术来识别客户端或服务器。

评论


“每次连接到SSH服务器时,它都会提供其私钥以证明其身份。”我当然希望不会!我认为您的意思是它的公钥。如果服务器向我提供了客户机,则客户机具有其私钥-它(A)对我不起作用来对其进行身份验证,并且(B)表明该服务器配置错误,以至于我应立即停止与其进行业务往来。 。私钥只能由指定用户在原始计算机上访问。这就是重点。 ;-)

– underscore_d
15/09/22在20:33



这个答案对我的帮助超过了公认的答案(:

–chaosguru
18年8月29日在9:07



如果我使用ssh连接到本地服务器(本地IP),然后再从同一台计算机连接到现在却远程连接到同一服务器(公共IP),它将触发密钥不匹配吗?您如何减轻这种情况?

–迪安树脂
19年8月8日在3:55



#3 楼

关于包含公共密钥的安全文件

为了帮助您了解“ known_hosts”和“ authorized_keys”之间的区别,这里有一些上下文说明了这些文件如何适合“ ssh”。这是一个过分的简化; “ ssh”的功能和复杂性比这里提到的要多。

关联在可信源中

虽然有人说公钥值“可以安全地像风中的种子一样散布。”请记住,决定花园中种下哪种种子的是菜农,而不是种子荚。尽管公开密钥不是秘密的,但是需要严格的保护以保持密钥与密钥正在认证的事物的可信关联。委托建立此关联的位置包括“ known_hosts”,“ authorized_keys”和“ Certificate Authority”列表。

“ ssh”使用的可信源

对于公众-与“ ssh”相关的密钥,密钥必须提前注册,并存储在适当的安全文件中。 (这个普遍的事实有一个重要的例外,将在后面讨论。)服务器和客户端都有各自自己的安全存储的公钥列表;仅当双方都注册时,登录才会成功。


“ known_hosts”驻留在客户端上
“ authorized_keys”驻留在服务器上

客户端的安全文件称为“ known_hosts”,服务器的安全文件称为“ authorized_keys”。这些文件的相似之处在于,每个文件每行都有一个带有一个公钥的文本,但是它们在格式和用法上都有细微的差别。

密钥对用于身份验证

公私钥对用于执行“非对称密码”。 “ ssh”程序可以使用非对称密码进行身份验证,其中实体必须回答挑战以证明其身份。通过使用一个键进行编码来创建挑战,然后通过使用另一个键进行解码来应对挑战。 (请注意,非对称密码技术仅在登录阶段使用;然后,“ ssh”(TSL / SSL)切换为另一种加密形式来处理数据流。)

服务器的一对密钥对,客户端的另一方

在“ ssh”中,双方(客户端和服务器)都对另一方表示怀疑。这是对“ ssh”的前身(即“ telnet”)的改进。使用“ telnet”时,要求客户端提供密码,但是服务器没有经过审查。缺乏审查使“中间人”攻击得以发生,对安全造成了灾难性后果。相比之下,在“ ssh”过程中,客户端不放弃任何信息,直到服务器首先回答挑战为止。

“ ssh”身份验证中的步骤

共享任何登录名之前信息,“ ssh”客户端首先通过挑战服务器以证明“您真的是我的真实身份吗?”,从而消除了中间人攻击的机会。为了应对这一挑战,客户端需要知道与目标服务器关联的公共密钥。客户端必须在“ known_hosts”文件中找到服务器的名称。关联的公共密钥在服务器名称之后位于同一行。服务器名称和公共密钥之间的关联必须保持严格;因此,“ known_hosts”文件的权限必须为600-其他任何人都不能写入(读取)。

服务器一旦通过身份验证,就有机会挑战客户端。身份验证将涉及在“ authorized_keys”中找到的公共密钥之一。 (当这些键都不起作用时,“ sshd”过程将退回到密码样式身份验证。)

文件格式

因此,对于“ ssh”,与任何登录过程一样,存在“朋友”列表,并且仅允许列表中的那些尝试通过挑战。对于客户端,“ known_hosts”文件是可以充当服务器(主机)的朋友的列表;这些按名称列出。对于服务器,等效的朋友列表是“ authorized_keys”文件。但是该文件中没有名称,因为公共密钥本身的作用就像标识符。 (服务器不在乎登录名来自何处,而仅在进行登录。客户端尝试访问特定帐户时,在调用“ ssh”时将帐户名指定为参数。请记住,“ authorized_keys “文件是特定于该帐户的,因为该文件位于该帐户的主目录下。)

尽管配置条目中可以表达许多功能,但最基本,最常见的用法如下参数。请注意,参数用空格字符分隔。

对于“ known_hosts”:

{server-id} ssh-rsa {public-key-string} {comment}


对于“ authorized_keys”:

ssh-rsa {public-key-string} {comment}


请注意,令牌ssh-rsa表示用于编码的算法是“ rsa”。其他有效的算法包括“ dsa”和“ ecdsa”。因此,可以使用其他令牌代替此处显示的ssh-rsa

让“ ssh”自动配置“ known_hosts”条目

在这两种情况下,如果在安全文件中均未找到公钥,则不会发生非对称加密。如前所述,该规则有一个例外。通过登录到用户“ known_hosts”文件中未列出的服务器,允许用户有意识地选择冒险遭受中间人攻击。 “ ssh”程序会警告用户,但是如果用户选择前进,则“ ssh”客户端将允许它“仅此一次”。为了确保它只发生一次,“ ssh”进程通过向服务器询问公钥,然后将其写入“ known_hosts”文件中,以所需的信息自动配置“ known_hosts”文件。通过允许对手提供服务器名称与公钥的关联,此异常完全破坏了安全性。之所以允许这种安全风险,是因为它使许多人容易得多。当然,正确和安全的方法是让用户在尝试登录服务器之前,将带有服务器名和公钥的行手动插入“ known_hosts”文件中。 (但是对于低风险情况,额外的工作可能没有意义。)

一对多关系

客户端的“ known_hosts”文件中的条目具有服务器名称和适用于服务器计算机的公共密钥。服务器具有用于回答所有挑战的单个私钥,并且客户端的“ known_hosts”条目必须具有匹配的公钥。因此,曾经访问特定服务器的所有客户端在其“ known_hosts”文件中将具有相同的公共密钥条目。 1:N关系是服务器的公钥可以出现在许多客户端的“ known_hosts”文件中。

“ authorized_keys”文件中的条目标识允许友好客户访问该帐户。朋友可能使用相同的公钥-私钥对访问多个不同的服务器。这允许单个密钥对向曾经联系过的所有服务器进行身份验证。每个目标服务器帐户在其“ authorized_keys”文件中将具有相同的公共密钥条目。 1:N关系是,一个客户端的公共密钥可以出现在多个服务器上多个帐户的“ authorized_keys”文件中。

有时,在多个客户端计算机上工作的用户将复制相同的密钥对;通常,这是在用户在台式机和笔记本电脑上工作时完成的。由于客户端计算机使用相同的密钥进行身份验证,因此它们将与服务器的“ authorized_keys”中的相同条目匹配。

私钥的位置

对于服务器端,系统进程或守护程序处理所有传入的“ ssh”登录请求。该守护程序名为“ sshd”。私钥的位置取决于SSL的安装,例如Apple将其放在/System/Library/OpenSSL,但是在安装自己的OpenSSL版本后,该位置将是/opt/local/etc/openssl。对于客户端,您调用需要时使用“ ssh”(或“ scp”)。您的命令行将包含各种参数,其中之一可以选择指定要使用的私钥。默认情况下,客户端密钥对通常称为$HOME/.ssh/id_rsa$HOME/.ssh/id_rsa.pub

总括来说,“ known_hosts”和“ authorized_keys”都包含公共密钥,但是...


known_hosts-客户端检查主机是否为真实主机
authorized_keys-主机检查是否允许客户端登录


评论


SSH客户端通常没有密钥。 authorized_keys中列出的公共密钥标识用户,而不是计算机。

–吉尔斯'所以-不再是邪恶的'
19年8月31日在21:33

谢谢。这是文件和密钥之间关系的非常清晰且易于理解的解释。

–汤姆·巴斯科姆(Tom Bascom)
6月18日18:29

#4 楼

完全不是真的。

known_hosts文件包含主机的指纹。它不是远程主机的公钥或私钥。

它是由它们的密钥生成的-但是很重要的是它本身不是密钥。

如果您通过SFTP到可能解析为多个(可变)主机(负载平衡等)的地址,您必须从所有可能的端点添加指纹,否则它将首先工作,然后在路由到第二个(或后续)主机时失败。 />

评论


erm查看您的known_hosts文件,并在连接时将其与主机指纹进行比较...。这应该可以将其清除一点。此外,无论示例是known_hosts文件中的指纹还是公钥,您的示例都将完全相同。

– Njomsky
15年2月16日在22:54