简介
在配置大量具有许多用户的服务器时,保持基础架构的 SSH 访问一致可能会变得复杂。有许多实现集中式身份验证机构的方法,例如 LDAP,但有时这些方法可能过于复杂。
SSH 实际上具有使用证书机构对服务器和客户端进行身份验证的功能。这种功能是双向的。使用此系统,您可以将主机验证为客户端,避免有关无法验证主机真实性的混乱消息。您还可以将客户端验证为主机,从而允许您在一个地方注册新的 SSH 密钥并允许组织范围内的访问。
我们将讨论如何利用上述两种方式中的证书。我们将在三个 Ubuntu 12.04 VPS 实例上进行演示。其中一个将作为主机,另一个作为客户端,第三个将作为证书机构。
如何配置主机证书
我们将首先配置证书,以便将我们的服务器验证为我们的客户端。这将允许我们的客户端连接到我们的服务器,而无需质疑服务器的真实性。
我们从将用作证书机构的机器开始。在本示例中,我们将将其称为 “auth.example.com
”。
生成签名密钥
首先,我们需要生成一些将充当签名密钥的 RSA 密钥。可以使用任何用户,但 root 用户可能是一个不错的选择。我们将创建名为 “server_ca
” 和 “server_ca.pub
” 的密钥,因为这些将用于验证我们的服务器。
让我们在我们的主目录中创建这些密钥:
cd ~ ssh-keygen -f server_ca
系统会询问您是否要创建一个密码。这将在密钥落入错误手中时为您的密钥增加额外的保护层。完成后,您将在主目录中拥有一个私钥和公钥:
ls
server_ca server_ca.pub
签署主机密钥
现在我们有了我们的密钥,我们可以开始签署我们的主机密钥。
我们应该首先签署证书机构本身的主机密钥。我们可以使用以下语法来执行此操作:
ssh-keygen -s <span class="highlight">signing_key</span> -I <span class="highlight">key_identifier</span> -h -n <span class="highlight">host_name</span> -V +52w <span class="highlight">host_rsa_key</span>
让我们来看看这些都表示什么。
- -s:这是我们刚刚创建的私钥,我们将使用它来签署所有其他密钥。
- -I:这是用于标识证书的名称。在证书用于身份验证时,它用于记录目的。
- -h:这将标记生成的证书为主机密钥,而不是客户端密钥。
- -n:这用于标识与此证书关联的名称(用户或主机)。
- -V:这指定证书的有效期。在这种情况下,我们指定证书将在一年后过期(52周)。
之后,我们指定要签署的密钥。
在我们的情况下,要签署我们自己的主机 RSA 密钥,我们将使用类似于以下内容的行。我们将将此服务器标识为 “host_auth_server
”。在创建签名密钥时,系统会提示我们输入密码:
ssh-keygen -s server_ca -I host_auth_server -h -n auth.example.com -V +52w /etc/ssh/ssh_host_rsa_key.pub
Signed host key /etc/ssh/ssh_host_rsa_key-cert.pub: id "host_auth_server" serial 0 for auth.example.com valid from 2014-03-20T12:25:00 to 2015-03-19T12:26:05
从输出中可以看出,我们的证书有效期为一年。它已在与我们的服务器主机密钥相同的目录中创建(/etc/ssh/
),名称为 “ssh_host_rsa_key-cert.pub
”。
现在我们已经在证书机构本身上签署了我们的主机密钥,我们可以签署我们要验证到客户端的单独 SSH 服务器的主机密钥。
从我们的 SSH 服务器复制主机密钥。我们将将此机器称为 “sshserver.example.com
”。您可以使用 scp
来执行此操作:
cd ~ scp root@sshserver.example.com:/etc/ssh/ssh_host_rsa_key.pub .
现在,我们可以使用与上面相同的方法从此文件创建证书。我们需要更改一些值,以便引用我们要签署的新主机:
ssh-keygen -s server_ca -I host_sshserver -h -n sshserver.example.com -V +52w ssh_host_rsa_key.pub
Signed host key ssh_host_rsa_key-cert.pub: id "host_sshserver" serial 0 for sshserver.example.com valid from 2014-03-20T12:40:00 to 2015-03-19T12:41:48
现在,我们需要将生成的证书文件复制回主机。同样,我们可以使用 scp
来执行此操作:
scp ssh_host_rsa_key-cert.pub root@sshserver.example.com:/etc/ssh/
之后,我们可以从我们的身份验证服务器上删除 SSH 服务器的公钥和证书:
rm ssh_host_rsa_key.pub ssh_host_rsa_key-cert.pub
现在我们已经放置了签名证书,我们只需要配置我们的组件来使用它们。
配置组件以使用主机证书
首先,我们需要继续配置我们的两台服务器(auth.example.com 和 sshserver.example.com),让它们意识到我们创建的证书文件。
在这两台机器上,我们需要编辑主 SSH 守护程序配置文件。确保你正在编辑 sshd_config
文件,而不是 ssh_config
文件:
sudo nano /etc/ssh/sshd_config
如果你找到了 HostCertificate
行,请进行修改。否则,将以下内容添加到文件末尾。我们需要指定主机证书文件的路径:
HostCertificate /etc/ssh/ssh_host_rsa_key-cert.pub
完成后保存并关闭文件。
现在,重新启动 SSH 守护程序以使这些更改生效:
sudo service ssh restart
对于所有需要配置主机证书的服务器都要执行此操作。
现在,我们的服务器已配置为使用证书,但我们的客户端不知道如何检查服务器将呈现的证书。
在我们的客户端机器上,我们将称之为 “client.example.com
”,打开或创建 “~/.ssh/known_hosts
” 文件:
nano ~/.ssh/known_hosts
我们需要删除与我们为证书条目配置的服务器有关的任何条目。最好是删除所有内容。
之后,我们需要添加一个特殊条目,指定我们应该使用来检查我们的主机在登录期间将给我们的证书的公钥。以 @cert-authority
开头,之后可以包括一个域限制,指定将应用密钥的域,然后是我们一直在签署所有内容的公共证书颁发机构密钥。
在你的证书颁发机构机器上,你可以通过输入以下命令获取公共证书签名密钥:
cat ~/server_ca.pub
使用这些信息,你的 ~/.ssh/known_hosts
文件中的行应该如下所示:
@cert-authority *.example.com ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCxC+gikReZlWEnZhKkGzhcNeRD3dKh0L1opw4/LQJcUPfRj07E3ambJfKhX/+G4gfrKZ/ju0nanbq+XViNA4cpTIJq6xVk1uVvnQVOi09p4SIyqffahO9S+GxGj8apv7GkailNyYvoMYordMbIx8UVxtcTR5AeWZMAXJM6GdIyRkKxH0/Zm1r9tsVPraaMOsKc++8isjJilwiQAhxdWVqvojPmXWE6V1R4E0wNgiHOZ+Wc72nfHh0oivZC4/i3JuZVH7kIDb+ugbsL8zFfauDevuxWeJVWn8r8SduMUVTMCzlqZKlhWb4SNCfv4j7DolKZ+KcQLbAfwybVr3Jy5dSl root@auth
完成后保存并关闭文件。
现在,当你首次从客户端访问 SSH 服务器(使用完整主机名)时,你不应该被问及是否信任远程主机。这是因为主机已向你呈现其主机证书,由证书颁发机构签名。你已经检查了你的 known_hosts
文件,并验证了证书的合法性。
如何配置用户密钥
现在我们已经学会了如何将服务器认证给用户,我们也可以配置我们的证书颁发机构来认证用户给我们的服务器。
与之前一样,这个过程将从我们的证书颁发机构服务器开始。我们需要生成一组新的密钥,这次是用来签署用户证书的:
ssh-keygen -f users_ca
同样,选择一个密码,以便在有人获得访问权限时保护您的密钥。
配置服务器以接受用户认证登录
完成后,您需要将公钥复制到需要验证用户真实性的每个SSH服务器上。我们将像往常一样使用 scp
来完成这个操作:
scp users_ca.pub root@sshserver.example.com:/etc/ssh/
我们需要修改我们的SSH守护程序配置在我们的SSH服务器上查找这个密钥。
在我们的 “sshserver.example.com
” 主机上,打开配置文件:
sudo nano /etc/ssh/sshd_config
在底部,在我们的 HostCertificate
行下面,我们需要添加另一行引用我们刚刚复制过来的文件:
TrustedUserCAKeys /etc/ssh/users_ca.pub
同样,我们需要重新启动SSH守护程序以使这些更改生效:
sudo service ssh restart
签署用户登录密钥
现在服务器已经配置为信任由 users_ca
密钥签署的密钥,我们需要实际签署用户的认证密钥,以便这个方案能够工作。
首先,我们需要使用 scp
将我们的客户端密钥传输到证书颁发机构服务器上。从证书服务器上,输入:
cd ~ scp <span class="highlight">username</span>@client.example.com:/home/<span class="highlight">username</span>/.ssh/id_rsa.pub .
现在我们在证书机器上有了这个密钥,我们可以使用我们的 users_ca
密钥对其进行签名。这将与上次使用 server_ca
密钥签署密钥非常相似,只是现在我们不包括 -h
参数,因为这些是用户密钥。
我们想要的命令类似于这样。将 “username” 值更改为要签名以便更容易管理的用户的名称:
ssh-keygen -s users_ca -I user_<span class="highlight">username</span> -n <span class="highlight">username</span> -V +52w id_rsa.pub
Signed user key id_rsa-cert.pub: id "user_username" serial 0 for username valid from 2014-03-20T14:45:00 to 2015-03-19T14:46:52
您将被提示输入在密钥创建过程中设置的 users_ca
密码。现在,我们在我们的目录中有一个 id_rsa-cert.pub
文件,我们需要将其传输回我们的客户端机器:
scp id_rsa-cert.pub <span class="highlight">username</span>@client.example.com:/home/<span class="highlight">username</span>/.ssh/
现在,当您从您的客户端计算机登录到 sshserver.example.com
时,即使您以前从未以这个用户登录到这个服务器,也不应该被要求输入您的认证详细信息。
结论
通过签署您的主机和用户密钥,您可以为用户和服务器验证创建一个更灵活的系统。这使您能够建立一个集中的权威来验证您的服务器给您的用户,以及您的用户给您的服务器。
虽然也许不是创建集中式认证的最强大方式,但它易于设置并利用现有工具,而不需要大量的时间和配置。它还具有不需要CA服务器在线检查证书的优点。