SSH 证书颁发机构和密钥签名
前提条件¶
- 能够使用命令行工具
- 从命令行管理内容
- 先前使用 SSH 密钥生成的相关经验会有所帮助,但不是必需的
- 对 SSH 和公钥基础设施的基本了解会有所帮助,但不是必需的
- 运行 sshd 守护进程的服务器。
介绍¶
如果您无法验证远程主机密钥的指纹,那么与远程主机的初始 SSH 连接是不安全的。使用证书颁发机构来签署远程主机的公钥可以确保每个信任 CA 的用户在初始连接时都是安全的。
CA 还可以用于签署用户 SSH 密钥。与其将密钥分发到每个远程主机,一个签名就足以授权用户登录到多个服务器。
目标¶
- 提高 SSH 连接的安全性。
- 改进入职流程和密钥管理。
说明¶
- Vim 是作者首选的文本编辑器。使用其他文本编辑器(如 nano 或其他编辑器)是可以接受的。
sudo
或root
的使用意味着提升的权限。
初始连接¶
要确保初始连接安全,您需要事先了解密钥指纹。您可以优化和集成此部署过程以用于新的主机。
在远程主机上显示密钥指纹
user@rocky-vm ~]$ ssh-keygen -E sha256 -l -f /etc/ssh/ssh_host_ed25519_key.pub
256 SHA256:bXWRZCpppNWxXs8o1MyqFlmfO8aSG+nlgJrBM4j4+gE no comment (ED25519)
从客户端建立初始 SSH 连接。密钥指纹正在显示,可以与之前获取的指纹进行比较
[user@rocky ~]$ ssh user@rocky-vm.example.com
The authenticity of host 'rocky-vm.example (192.168.56.101)' can't be established.
ED25519 key fingerprint is SHA256:bXWRZCpppNWxXs8o1MyqFlmfO8aSG+nlgJrBM4j4+gE.
This key is not known by any other names
Are you sure you want to continue connecting (yes/no/[fingerprint])?
创建证书颁发机构¶
创建 CA(私钥和公钥),并将公钥放置在客户端的 known_hosts
文件中,以识别属于 example.com 域的所有主机
[user@rocky ~]$ ssh-keygen -b 4096 -t ed25519 -f CA
[user@rocky ~]$ echo '@cert-authority *.example.com' $(cat CA.pub) >> ~/.ssh/known_hosts
其中
- -b:密钥长度(以字节为单位)
- -t:密钥类型:rsa、ed25519、ecdsa...
- -f:输出密钥文件
或者,您也可以通过编辑 SSH 配置文件 /etc/ssh/ssh_config
在系统范围内指定 known_hosts
文件
Host *
GlobalKnownHostsFile /etc/ssh/ssh_known_hosts
签署公钥¶
创建用户 SSH 密钥并签署它
[user@rocky ~]$ ssh-keygen -b 4096 -t ed2119
[user@rocky ~]$ ssh-keygen -s CA -I user -n user -V +55w id_ed25519.pub
通过 scp
获取服务器的公钥并签署它
[user@rocky ~]$ scp user@rocky-vm.example.com:/etc/ssh/ssh_host_ed25519_key.pub .
[user@rocky ~]$ ssh-keygen -s CA -I rocky-vm -n rocky-vm.example.com -h -V +55w ssh_host_ed25519_key.pub
其中
- -s:签署密钥
- -I:用于日志记录目的识别证书的名称
- -n:标识与证书关联的名称(主机或用户,一个或多个)(如果未指定,则证书对所有用户或主机有效)
- -h:将证书定义为主机密钥,而不是客户端密钥
- -V:证书的有效期
建立信任¶
复制远程主机的证书以供远程主机在连接时与公钥一起呈现
[user@rocky ~]$ scp ssh_host_ed25519_key-cert.pub root@rocky-vm.example.com:/etc/ssh/
将 CA 的公钥复制到远程主机,以使其信任 CA 签署的证书
[user@rocky ~]$ scp CA.pub root@rocky-vm.example.com:/etc/ssh/
将以下几行添加到 /etc/ssh/sshd_config
文件中,以指定服务器要使用的先前复制的密钥和证书,并信任 CA 以识别用户
[user@rocky ~]$ ssh user@rocky-vm.example.com
[user@rocky-vm ~]$ sudo vim /etc/ssh/sshd_config
HostKey /etc/ssh/ssh_host_ed25519_key
HostCertificate /etc/ssh/ssh_host_ed25519_key-cert.pub
TrustedUserCAKeys /etc/ssh/CA.pub
重新启动服务器上的 sshd
服务
[user@rocky-vm ~]$ systemctl restart sshd
测试连接¶
从 known_hosts
文件中删除远程服务器的指纹,并通过建立 SSH 连接来验证设置
[user@rocky ~]$ ssh-keygen -R rocky-vm.example.com
[user@rocky ~]$ ssh user@rocky-vm.example.com
密钥吊销¶
吊销主机或用户密钥对于整个环境的安全性至关重要。因此,重要的是存储先前签署的公钥,以便您以后可以吊销它们。
创建一个空的吊销列表并吊销 user2 的公钥
[user@rocky ~]$ sudo ssh-keygen -k -f /etc/ssh/revokation_list.krl
[user@rocky ~]$ sudo ssh-keygen -k -f /etc/ssh/revokation_list.krl -u /path/to/user2_id_ed25519.pub
将吊销列表复制到远程主机并在 sshd_config
文件中指定它
[user@rocky ~]$ scp /etc/ssh/revokation_list.krl root@rocky-vm.example.com:/etc/ssh/
[user@rocky ~]$ ssh user@rocky-vm.example.com
[user@rocky ~]$ sudo vim /etc/ssh/sshd_config
以下行指定吊销列表
RevokedKeys /etc/ssh/revokation_list.krl
必须重新启动 SSHD 守护进程才能重新加载配置
[user@rocky-vm ~]$ sudo systemctl restart sshd
user2 被服务器拒绝
[user2@rocky ~]$ ssh user2@rocky-vm.example.com
user2@rocky-vm.example.com: Permission denied (publickey,gssapi-keyex,gssapi-with-mic).
吊销服务器密钥也是可能的
[user@rocky ~]$ sudo ssh-keygen -k -f /etc/ssh/revokation_list.krl -u /path/to/ssh_host_ed25519_key.pub
/etc/ssh/ssh_config
中的以下几行在系统范围内应用主机吊销列表
Host *
RevokedHostKeys /etc/ssh/revokation_list.krl
尝试连接到主机将导致以下结果
[user@rocky ~]$ ssh user@rocky-vm.example.com
Host key ED25519-CERT SHA256:bXWRZCpppNWxXs8o1MyqFlmfO8aSG+nlgJrBM4j4+gE revoked by file /etc/ssh/revokation_list.krl
维护和更新吊销列表很重要。您可以自动化此过程,以确保所有主机和用户都可以访问最新的吊销列表。
结论¶
SSH 是管理远程服务器的最有价值的协议之一。实施证书颁发机构可能会有所帮助,尤其是在拥有大量服务器和用户的较大环境中。重要的是维护吊销列表。它可以轻松吊销受损的密钥,而无需替换整个关键基础设施。
作者:Julian Patocki
贡献者:Steven Spencer, Ganna Zhyrnova