介绍
管理大量的 SSH 密钥和服务器可能随着组织的增长而变得非常困难,正确识别有效密钥和在整个组织中删除无效密钥可能会充满错误,并对您的服务器安全产生巨大的后果。
此外,当服务器发生更改时,有时用户会收到关于无法确认服务器的真实性的警告,大多数用户不会在连接之前双重检查服务器的密钥指纹,允许某人潜在地欺骗服务器并执行中间人攻击。
一个名为 monkeysphere的项目被创建以解决这些问题,它通过利用GPG密钥和信任模型网络来验证服务器的凭证,并提供简单的用户管理。
在本指南中,我们将讨论如何设置猴子圈以验证您的服务器给用户。这将解决用户需要猜测他们正在连接的服务器是否实际上是他们试图访问的服务器的问题。
1The authenticity of host '107.170.43.127 (107.170.43.127)' can't be established.
2ECDSA key fingerprint is 10:14:75:d6:42:a3:c5:59:d1:83:6d:cf:52:61:4a:52.
3Are you sure you want to continue connecting (yes/no)?
我们将在本文中努力避免向用户显示这些信息,在未来的一篇指南中,我们将讨论如何解决易于识别和身份验证用户的问题(https://www.digitalocean.com/community/articles/how-to-authenticate-users-to-a-ssh-server-using-monkeysphere-on-an-ubuntu-vps)。
我们将使用Ubuntu 12.04 VPS实例来配置这个系统,我们将有一个SSH服务器,我们将尝试验证我们的用户,我们还需要其他两个机器来演示(无论是本地计算机还是VPS实例)。
基本战略
整个猴子圈系统依赖GPG键和关键服务器来工作. 在我们开始之前,您将不得不为每个系统配置这些键。
在您开始使用 GPG 之前,您可能想查看我们关于 [如何使用 GPG 密钥] 的文章(https://www.digitalocean.com/community/articles/how-to-use-gpg-to-encrypt-and-sign-messages-on-an-ubuntu-12-04-vps)。
我们的三个机器及其用途将是:
- server.example.com:我们要对客户端验证的SSH服务器
- admin.example.com:我们将使用的管理员计算机来配置访问。这通常是您的家庭计算机,但我们将在我们的指南中使用另一个滴滴
- client.example.com:这是我们将使用的客户端来测试我们的验证。
SSH 伺服器機器應該具有公開可用的網域名稱. 使用此指南 在 DigitalOcean 上設定網域名稱。
对于第一个部分,我们希望在管理员和客户端计算机上生成密钥,然后将这些密钥上传到中央密钥服务器,我们将从密钥服务器中拉下管理员的密钥,并使用客户端密钥签名和信任它,表明我们的客户端信任我们的管理员。
这是整个验证计划的基础,而不是信任计算机或密钥,我们正在利用GPG的信任模型。如果您认为某人对您试图连接的服务器有知识和可靠性,您可以转向该人,让您知道服务器是否合法,在这种情况下,我们的客户会相信服务器管理员可以验证服务器的身份。
然后,我们可以配置 apkeysphere 以使用 GPG 框架来拉下信息,以验证我们信任的管理员为我们试图连接的服务器提供折扣。
设置 GPG 密钥和身份验证
幸运的是,GPG在Ubuntu上默认安装。
我们将首先在我们的客户端系统和管理员系统上创建一些GPG密钥,这些密钥与单个用户有关,并用于识别该用户在全球范围内。
生成 GPG 密钥
我们需要在客户端机和管理机上创建一个 GPG 密钥,在这两个计算机上执行以下操作:
1gpg --gen-key
首先,它问你想要创建哪种类型的密钥。选择1
来创建两个RSA密钥。在下一个问题中接受默认值以创建2048位密钥。选择0
以使密钥永不自动到期,然后键入Y
以确认信息正确。
接下来,您将被要求为每个用户提供您的信息. 我们将使用admin
和电子邮件地址[email protected]
作为我们的管理员密钥. 对于我们的客户,我们将使用客户
和电子邮件[email protected]
。
输入并确认一个密码,以保护密钥。
计算机现在将使用从系统中收集的随机数据创建密钥,这被称为``并用于创建一个真正随机的密钥,这可能需要一段时间。
当密钥被生成时,它将被存储在您的GPG密钥中,您可以通过键入以下内容来查看:
gpg --list-keys
/root/.gnupg/pubring.gpg ------------------------ pub 2048R/08D014B3 2014-03-14 uid client <[email protected]> sub 2048R/4C73683E 2014-03-14
上面的红色部分是一个缩短的密钥ID,我们可以使用这个哈希来参考这个密钥。
我们应该将我们的密钥上传到密钥服务器上。这些密钥服务器遍布世界各地,允许任何人下载我们的关键信息。这就是我们想要的,因为它允许我们的两个用户和SSH服务器互动并建立信任关系。
要将我们的密钥上传到钥匙服务器上,在我们的客户端和管理计算机上,我们需要输入这样的东西。
gpg --send-key key_id
因此,对于上面的客户端密钥,我们可以通过键入将其上传到密钥服务器:
1gpg --send-key 08D014B3
签下钥匙
现在我们的管理员和客户端都拥有 GPG 密钥,并将它们上传到密钥服务器中,它们将开始传播到世界各地的其他密钥服务器。
等待几分钟后,您可以尝试在每个计算机上拉下相反的键,这意味着在客户端计算机上,尝试拉下管理员的键,您还应该拉下管理员计算机的客户端键。
我们将签署这些密钥,这意味着我们认为它们是有效的,并且已经验证了它们是我们试图识别的人的正确密钥。
在您的客户端服务器上,通过输入此键获取您的GPG密钥的指纹,客户端
是您在构建密钥时选择的名称或电子邮件地址:
gpg --with-colons --fingerprint client
tru::1:1394819815:0:3:1:5 pub:u:2048:1:4B3F73E208D014B3:2014-03-14:::u:client <[email protected]>::scESC: fpr:::::::::85ECDB498FB0CAB5F02989E64B3F73E208D014B3: sub:u:2048:1:254105194C73683E:2014-03-14::::::e:
上面突出的输出部分是您正在寻找的指纹。
现在你有这个指纹,在你的管理员的计算机上,你可以告诉GPG用这个指纹寻找一个密钥,然后把它拖到本地计算机,如下:
1gpg --recv-keys 85ECDB498FB0CAB5F02989E64B3F73E208D014B3
这将连接到默认的密钥服务器,并要求通过指纹识别的密钥。
现在我们可以访问密钥,我们可以签署它,表示我们作为管理员信任属于客户端的密钥:
1gpg --sign-key 85ECDB498FB0CAB5F02989E64B3F73E208D014B3
现在,我们已经在本地系统上签署了密钥,现在我们应该将客户端密钥发送回密钥服务器,密钥服务器将更新其客户端密钥上的信息,以表明我们的管理员帐户已签署密钥,并认为它是有效的。
要将签名的密钥发送回钥匙服务器,我们键入:
1gpg --send-key 85ECDB498FB0CAB5F02989E64B3F73E208D014B3
密钥服务器现在有我们的管理员密钥和客户端密钥,就像以前一样。
我们现在需要执行相反的操作(用客户端密钥签署管理员密钥)。
1gpg --with-colons --fingerprint admin
现在,在客户端机器上,我们使用我们从输出中收集的指纹来拉下,签名,然后上传管理员密钥,就像我们以前一样:
1gpg --recv-keys 7C873BB244245CB13BFEFC31F7C66E2FF945A061
2gpg --sign-key 7C873BB244245CB13BFEFC31F7C66E2FF945A061
3gpg --send-key 7C873BB244245CB13BFEFC31F7C66E2FF945A061
之后,在两台机器上,我们需要更新我们的密钥,这是因为我们的每个用户都签署了他们的密钥,但他们没有在自己的计算机上签名,只是在相反的计算机和密钥服务器上。
1gpg --refresh-keys
您需要验证更新是否已被处理,输出应该有一个行,上面写着新签名:1
。
现在,您的每个计算机都应该有两个签名的密钥。
信任管理者的判断
为了使我们的信任网络实际上工作,我们不仅要让客户端签署管理员密钥,我们还必须确认客户端信任
管理员的判断。
这意味着,当管理员说SSH服务器是机器时,它说它是,我们作为客户端可以信任 另一个人,管理员,制造的签名。
首先,我们可以通过键入来查看客户端的当前设置:
1gpg --check-trustdb
1gpg: 3 marginal(s) needed, 1 complete(s) needed, PGP trust model
2gpg: depth: 0 valid: 1 signed: 1 trust: 0-, 0q, 0n, 0m, 0f, 1u
3gpg: depth: 1 valid: 1 signed: 0 trust: 1-, 0q, 0n, 0m, 0f, 0u
这是一个非常令人困惑的信息集。第一行表示我们正在运作的信任模型. 基本上,如果我们有一个密钥,由一个用户签署,我们完全信任,那么我们会认为该密钥也是有效的。
第二行告诉我们关于我们的深度0
信任级别,这基本上是关于我们自己的密钥的信息,我们认为它是有效的和签名的,而信任
部分告诉我们密钥属于u
类别,意思是最终是值得信赖的。
第三行告诉我们关于密钥的深度1
。这些是我们亲自签署的密钥,我们可以看到我们认为一个密钥是有效的(我们签署了管理员密钥以使其有效),并且管理员密钥没有签署我们关心的任何额外密钥。
在该行的信任部分,我们有一个字段,它有1-
。这意味着我们在这个级别(管理员密钥)的单个密钥没有得到信任设置。
我们希望完全信任管理员密钥,这样,管理员标记的任何密钥(如我们试图验证身份的SSH服务器)将被我们认为是合法的。
1gpg --update-trustdb
您将被要求将信任评级分配给您签署的任何当前没有信任值的密钥。
1gpg: 3 marginal(s) needed, 1 complete(s) needed, PGP trust model
2gpg: depth: 0 valid: 1 signed: 1 trust: 0-, 0q, 0n, 0m, 0f, 1u
3No trust value assigned to:
42048R/49E95F19 2014-03-14
5 "admin <[email protected]>"
6 Primary key fingerprint: A612 56B8 5307 B7ED 9AD8 D93E 9E06 881E 49E9 5F19
7
8Please decide how far you trust this user to correctly verify other users' keys
9(by looking at passports, checking fingerprints from different sources, etc.)
10
11 1 = I don't know or won't say
12 2 = I do NOT trust
13 3 = I trust marginally
14 4 = I trust fully
15 s = skip this key
16 q = quit
17
18Your decision?
我们希望完全信任这个密钥,所以输入4
。
现在,由于我们信任管理员的判断,我们可以合理地确定管理员标记的密钥是合法地与所涉及的用户或服务相关联的(通常我们会使用实际名称而不是客户端或管理员)。
安装 Monkeysphere 并配置 SSH 服务器
现在我们有我们的客户端和管理员计算机设置了他们的GPG键,我们可以开始实际的猴子圈安装和配置。
在Ubuntu的默认存储库中,有一个猴子圈包,它包含SSH所需的服务器和客户端工具,以便使用GPG进行验证,因此我们需要在每个计算机上安装该包。
在此模型中的所有计算机(管理员、客户端、SSH服务器)上,通过键入:
1sudo apt-get update
2sudo apt-get install monkeysphere
在SSH服务器上,我们将使用包含在apkeysphere中的包装工具生成一个特殊的GPG密钥。生成的密钥将基于用于识别服务器到客户端的ssh_host_rsa_key
。
在 SSH 服务器上,键入:
monkeysphere-host import-key /etc/ssh/ssh_host_rsa_key ssh://server.example.com
上面的第二个组件应该表示SSH服务器的域名,这将帮助客户在尝试验证服务器连接时找到正确的服务器密钥。
现在,我们可以将我们刚刚创建的密钥再次上传到公共密钥服务器上,这次,我们将再次使用包括在猴子圈套件中的包装程序:
1monkeysphere-host publish-key
这将上传您的服务器密钥,并使其可用于希望连接的客户端。
验证服务器密钥作为服务器管理员
现在,我们有SSH服务器的密钥被传播到世界的密钥服务器,但这如何帮助我们?
好吧,GPG的工作方式是通过建立它称之为信任网络
的方式,简单地说,它通过建立你认识的人的个人网络,并且你可以高确定性地验证他们的身份。
在我们的情况下,我们(作为这个例子的客户端)将知道服务器是否合法的责任转移到我们信任的管理员身上。
因此,我们现在需要做的就是签署SSH服务器的GPG密钥作为服务器管理员,这将使我们的客户端用户能够通过信任的管理员来验证服务器的身份。
在 SSH 服务器上,通过键入获取 GPG 指纹:
1monkeysphere-host show-key
1pub 2048R/0D281337 2014-03-14
2uid ssh://fakedomain.com
3OpenPGP fingerprint: E06A426459E584F272DB708AD2D462790D281337
4ssh fingerprint: 2048 61:1e:a7:66:1d:04:64:80:3f:27:81:34:31:78:8d:df (RSA)
OpenPGP指纹
与我们的GPG指纹相同,这是我们将用来将密钥拖到我们的管理员的计算机并签署的。
在我们的管理员的计算机上,输入此信息以获取 SSH 服务器的密钥。
1gpg --recv-key E06A426459E584F272DB708AD2D462790D281337
我们将签署密钥,就像我们上面的客户端密钥一样:
1gpg --sign-key E06A426459E584F272DB708AD2D462790D281337
最后,我们需要记住将签名的密钥重新上传到密钥服务器:
1gpg --send-key E06A426459E584F272DB708AD2D462790D281337
通过客户端验证 SSH 服务器的身份
现在,我们有所有必要的措施来验证客户端计算机的 SSH 服务器的身份。
要做到这一点,我们将不得不将SSH命令包装到一个猴子圈的实用程序中,这将告诉我们的客户端使用猴子圈来检查我们正在试图嵌入的服务器的GPG密钥,然后它会看到我们是否信任任何确认服务器有效的人。
我们将首次手动完成此操作,以便向您展示正在发生的事情,随后,我们可以将其添加到文件中,以便自动完成此操作。
在客户端上,输入手动命令如下:
ssh -oProxyCommand='monkeysphere ssh-proxycommand %h %p' server.example.com
-------------------- Monkeysphere warning ------------------- Monkeysphere found OpenPGP keys for this hostname, but none had full validity. An OpenPGP key matching the ssh key offered by the host was found: pub 2048R/0D281337 2014-03-14 uid [ unknown] ssh://server.example.com sig!3 0D281337 2014-03-14 ssh://fakedomain.com RSA key fingerprint is 61:1e:a7:66:1d:04:64:80:3f:27:81:34:31:78:8d:df. -------------------- ssh continues below -------------------- The authenticity of host 'server.example.com (<no hostip for proxy command>)' can't be established. ECDSA key fingerprint is 78:50:80:60:2a:a3:51:51:37:9d:25:8b:d4:0c:d1:15. Are you sure you want to continue connecting (yes/no)?
类型的不
在这里。
正如你所看到的,我们有关于如何无法确认我们试图连接的主机的真实性的常见消息,我们还没有解决问题,也没有验证服务器的身份,所以我们必须键入不
,以保护自己不连接到错误的主机。
然而,我们还在Monkeysphere warning
部分标题下获得了额外的信息部分,它告诉我们它能够检索密钥,但无法验证服务器,因为它没有必要的信任关系。
如果我们看看客户端计算机的密钥链中的我们的密钥,我们会注意到我们现在有SSH服务器的密钥:
1gpg --list-keys
1/root/.gnupg/pubring.gpg
2------------------------
3pub 2048R/87791BD0 2014-03-14
4uid client <[email protected]>
5sub 2048R/3294D31D 2014-03-14
6
7pub 2048R/54AD641F 2014-03-14
8uid admin <[email protected]>
9sub 2048R/A87CADCB 2014-03-14
10
11pub 2048R/0D281337 2014-03-14
12uid ssh://fakedomain.com
现在我们只需要更新我们的密钥,这将吸引我们系统中的任何密钥的签名:
1gpg --refresh-keys
您应该再次看到一行说‘新签名:1’
。我们可以通过检查SSH服务器的密钥上可用的签名来看到这一点:
gpg --list-sigs ssh://server.example.com
pub 2048R/0D281337 2014-03-14 uid ssh://server.example.com sig 3 0D281337 2014-03-14 ssh://server.example.com sig 54AD641F 2014-03-14 admin <[email protected]>
正如你所看到的,我们现在看到一个sig
行列出管理员的密钥. 由于我们的客户端信任管理员,我们现在可以通过代理信任SSH服务器。
让我们再次尝试我们的命令:
1ssh -oProxyCommand='monkeysphere ssh-proxycommand %h %p' server.example.com
1[email protected]'s password:
正如你所看到的,我们现在已经收到密码提示,而不要求我们验证SSH服务器的有效性,这是因为我们通过GPG验证了它的身份。
为了避免每当我们想将SSH输入服务器时输入这个长命令,我们将此添加到客户端计算机上的配置文件中:
1nano ~/.ssh/config
1Host *
2ProxyCommand monkeysphere ssh-proxycommand %h %p
这将使我们能够通过SSH作为正常方式连接,并在背景下完成所有猴子圈验证:
1ssh server.example.com
若要双重检查此功能,请轻松删除当前的 known_hosts
文件:
1rm ~/.ssh/known_hosts
现在,重启 ssh 命令:
1ssh server.example.com
您将被登录或请求密码,而不会问您是否接受主机. 您还可以看到‘known_hosts’ 文件已自动重新创建,并且该主机已被添加:
1cat ~/.ssh/known_hosts
1server.example.com ssh-rsa AAAB3NzaC1yc2EAAAADAQABAAABAQC9aTHZmHZSgwNtwichF0AqDI74bCMtI29kqPDZaNn2r86NGIElRUlQiRImmZXs5oEjF0o8VaW6s1cIj0hC5ziDPShJ3VzZTWz9RmJ9xfPPcAPw2JbV1c1Q1bplstQqCZmFcRZyofztnP55HqOiJ4htLMxH+a9lM4AydDZtGHhzU+usxUjHniVbxCUVntpunlwtMk+Mtk9eysVdnJCJyV02/W89HExiO9QRpv+EugKN1eCQYrGvNbKWQKq4gSJ0RDwOSKNgkY/Ii0MsGJ2HuioO9np6IEdeZdgSGHPA23+zZe8asrN62iLUBADDkyIR6FAonCvfh99hbFxpNz2N8Mdb MonkeySphere2014-03-21T21:30:44
结论
如果您将您的组织配置为使用 apkeysphere 用于 SSH,则 SSH 用户将永远不必质疑组织内的主机的合法性。一旦您的用户信任服务器管理员并将他们的 SSH 配置为依赖 apkeysphere,并假设管理员对签署新主机保持警惕,您的用户就永远不应该被要求验证主机的身份。
盲目接受主机作为有效是一个巨大的风险,大多数用户将没有能力合法地检查服务器的身份,而没有管理员的帮助。
这可能看起来像是一个很大的工作,但建立一个信任网络将变得更少的工作,并允许您避免危险的中间风格攻击。
在下一篇文章中,我们将讨论 如何使用apkeysphere来验证用户到SSH服务器。