如何创建SSHCA以使用Ubuntu验证主机和客户端
状态: 已弃用
本文介绍了不再受支持的 Ubuntu 版本。 如果您当前正在运行运行 Ubuntu 12.04 的服务器,我们强烈建议您升级或迁移到受支持的 Ubuntu 版本:
原因: Ubuntu 12.04 已于 2017 年 4 月 28 日终止生命周期 (EOL) and no longer receives security patches or updates. This guide is no longer maintained.
请参阅: 本指南可能仍可用作参考,但可能不适用于其他 Ubuntu 版本。 如果可用,我们强烈建议使用为您正在使用的 Ubuntu 版本编写的指南。 您可以使用页面顶部的搜索功能来查找更新的版本。
介绍
在配置具有许多用户的大量服务器时,为您的基础架构保持 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 signing_key -I key_identifier -h -n host_name -V +52w host_rsa_key
让我们来看看这一切意味着什么。
- -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-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCxC+gikReZlWEnZhKkGzhcNeRD3dKh0L1opw4/LQJcUPfRj07E3ambJfKhX/+G4gfrKZ/ju0nanbq+XViNA4cpTIJq6xVk1uVvnQVOi09p4SIyqffahO9S+GxGj8apv7GkailNyYvoMYordMbIx8UVxtcTR5AeWZMAXJM6GdIyRkKxH0/Zm1r9tsVPraaMOsKc++8isjJilwiQAhxdWVqvojPmXWE6V1R4E0wNgiHOZ+Wc72nfHh0oivZC4/i3JuZVH7kIDb+ugbsL8zFfauDevuxWeJVWn8r8SduMUVTMCzlqZKlhWb4SNCfv4j7DolKZ+KcQLbAfwybVr3Jy5dSl root@auth
使用此信息,您的 ~/.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用户名 @客户 .example.com:/home/用户名/.ssh/id_rsa.pub 。
现在我们在证书机器上拥有了密钥,我们可以使用我们的 users_ca
密钥对其进行签名。 这将与我们上次使用 server_ca
密钥签署密钥非常相似,只是现在,我们不包括 -h
参数,因为这些是用户密钥。
我们想要的命令是这样的。 更改“用户名”值以反映您要签名的用户的名称,以便于管理:
ssh-keygen -s users_ca -I user_ username -n username -V +52w id_rsa.pub
签名用户密钥 id_rsa-cert.pub: id “user_username” 序列号 0 用于用户名,从 2014-03-20T14:45:00 到 2015-03-19T14:46:52 有效
系统将提示您输入在创建密钥期间设置的 users_ca
密码。 现在,我们的目录中有一个 id_rsa-cert.pub
文件,我们需要将其传输回我们的客户端计算机:
scp id_rsa-cert.pub用户名 @客户 .example.com:/home/用户名/.ssh/
现在,当您从客户端计算机登录 sshserver.example.com
时,即使您以前从未以该用户身份登录此服务器,也不应该要求您提供身份验证详细信息。
结论
通过签署您的主机和用户密钥,您可以为用户和服务器验证创建一个更灵活的系统。 这允许您为整个基础架构设置一个集中式授权,以便向您的用户验证您的服务器,以及向您的服务器验证您的用户。
虽然可能不是创建集中式身份验证的最强大方式,但它很容易设置和利用现有工具,无需大量时间和配置。 它还具有不需要 CA 服务器在线检查证书的优点。