OpenSSH 证书登录提供了一种增强安全性的方法来验证用户或主机的身份,避免了传统密码认证可能带来的安全隐患。它包括单向(通常是客户端到服务器)和双向(客户端与服务器互相认证)两种认证方式。

"OpenSSH 双向证书验证"

这里记录一下如何使用 OpenSSH 的证书功能来进行多服务器的秘钥管理。

给服务器设置信任客户端证书

设置完成之后,可以实现:使用 user_ca 签发出的证书登录任意服务器。

使用到的命令:

# 1. 生成CA密钥对:首先需要生成一个证书颁发机构(CA)的密钥对。
ssh-keygen -t rsa -b 4096 -f user_ca -C user_ca
# 这个命令会生成2个文件:user_ca 和 user_ca.pub

# 2 为用户生成密钥对
ssh-keygen -t rsa -b 4096 -f ssh_user_rsa_key
# 这个命令会生成2个文件:ssh_user_rsa_key 和 ssh_user_rsa_key.pub

# 3.签发证书:使用 `user_ca` 私钥对用户或主机公钥进行签名,生成相应的证书
ssh-keygen -s user_ca -I dev@example.com -n user1,user2 -V +30d ssh_user_rsa_key.pub
# 这个命令会生成一个包含有效期的证书文件:`ssh_user_rsa_key-cert.pub`
# 可以使用这个命令查看证书的详细信息:
ssh-keygen -L -f ssh_user_rsa_key-cert.pub

## 参数说明:
## -s : CA 指定应用于签名的 CA 私有密钥的文件名。
## -I : 证书的身份 ———— 用于标识用户或者服务器的字符串。
## -n : 指定证书将对身份验证有效的委托人列表(以逗号分隔)
## -V : 指定证书的有效期。

# 4. 在服务器的 `/etc/ssh/sshd_config` 中启用证书认证,并指定CA公钥的位置。
TrustedUserCAKeys /etc/ssh/user_ca.pub

# 5. 最后需要重启 SSHD 服务,才能生效
systemctl restart sshd

给客户端设置信任服务端证书

设置完成之后可以实现:服务器会向连接的所有人提供自己的证书。

使用到的命令:

# 1. 生成CA密钥对:首先需要生成一个证书颁发机构(CA)的密钥对。
ssh-keygen -t rsa -b 4096 -f host_ca -C host_ca
# 这个命令会生成2个文件:host_ca 和 host_ca.pub

# 2 为主机生成密钥对
ssh-keygen -t rsa -b 4096 -f ssh_host_rsa_key
# 这个命令会生成2个文件:ssh_host_rsa_key 和 ssh_host_rsa_key.pub

# 3.签发证书:使用CA私钥对用户或主机公钥进行签名,生成相应的证书
ssh-keygen -s host_ca -I host.example.com -h -n host.example.com -V +30d ssh_host_rsa_key.pub
# 这个命令会生成一个包含有效期的证书文件:ssh_host_rsa_key-cert.pub,可以使用这个命令查看证书的详细信息:
ssh-keygen -L -f ssh_host_rsa_key-cert.pub

## 参数说明:
## -s : CA 指定应用于签名的 CA 私有密钥的文件名。
## -I : 证书的身份 ———— 用于标识用户或者服务器的字符串。
## -h : 指定此证书将是主机证书,而不是用户证书。
## -n : 指定证书将对身份验证有效的委托人列表(以逗号分隔)
## -V : 指定证书的有效期。

# 4.1 在服务器端的 `/etc/ssh/ssh_config` 单独声明证书文件的位置
HostCertificate /etc/ssh/ssh_host_rsa_key-cert.pub
# 4.2 重启服务器端的 SSHD 服务。

# 5.1 在客户端的 `/etc/ssh/sshd_config` 中启用证书认证
TrustedUserCAKeys /etc/ssh/host_ca.pub
# 5.2 在客户端的 `~/.ssh/known_hosts` 中信任服务器 CA 的公钥,还可以配置为模式匹配模式
@cert-authority host1,host2,*.example.com ssh-rsa xxxx这里是 host_ca.pub 的内容xxxxx
# 5.3 最后需要重启客户端的 SSHD 服务,才能生效
systemctl restart sshd

通过 Ansible 脚本来进行批量部署

# 下面是个单向的验证模式,只给服务器设置信任客户端证书CA。
---
- name: Manage SSH keys and certificates using OpenSSH
hosts: all
gather_facts: no
vars:
user_ca_path: "{{ playbook_dir }}/ssh/ansible_user_ca_key"
user_key_path: "{{ playbook_dir }}/ssh/ansible_ssh_user_rsa_key"
user_pub_path: "{{ playbook_dir }}/ssh/ansible_ssh_user_rsa_key.pub"
cert_validity_days: +30d
# cert_validity_days: "-10d:-1d" # 生成一个过去的时间进行验证

tasks:
- name: Generate the Ansible User CA and cert
delegate_to: localhost
openssh_keypair:
path: "{{ user_ca_path }}"
type: rsa
size: 4096
state: present
force: no

- name: Ensure the Ansible User key exists
delegate_to: localhost
openssh_keypair:
path: "{{ user_key_path }}"
type: rsa
size: 4096
state: present
force: no

- name: Configure SSHD on target servers
hosts: coreos
become: yes
vars:
user_ca_pub_path: "{{ playbook_dir }}/ssh/ansible_user_ca_key.pub"
user_key_path: "{{ playbook_dir }}/ssh/ansible_ssh_user_rsa_key"

tasks:
- name: Copy the CA certificate to the target server
copy:
src: "{{ user_ca_pub_path }}"
dest: "/etc/ssh/trusted_ansible_user_ca_key.pub"
owner: root
group: root
mode: "0644"

- name: Ensure correct configuration in sshd_config
lineinfile:
path: /etc/ssh/sshd_config.d/62-ansible-user-ca.conf
create: yes # 确保文件存在或创建新文件
line: "TrustedUserCAKeys /etc/ssh/trusted_ansible_user_ca_key.pub"
state: present

- name: Restart SSHD service to apply changes
systemd:
name: sshd
state: restarted
enabled: yes

参考文章:https://goteleport.com/blog/how-to-configure-ssh-certificate-based-authentication/