前面关于 SPIRE 的内容中,介绍了使用 JOIN Token 证实节点身份的方法。这种方法比较简易,但是完全依赖 SPIRE Server/Agent 的“内循环”,并不利于外部管理,同时每次节点更新,都要照本宣科的重来一遍。对于动态集群来说,这种方式并不理想,SPIRE 包含了面向 OpenStack、几大公有云以及 TPM 等的花钱证实节点身份的方案;除了这些之外,还有个经济型的证实方法——使用 SSH。
我们一般使用的免密登录 SSH 方案通常是点对点的,总结来说就是服务器和客户端各自有各自的公私钥,互相进行信任操作:
ssh-keygen
命令生成自己的公私钥know_hosts
文件里面,代表信任该地址和证书的组合authorized_keys
文件之中,代表认可以该密钥作为特定用户的身份证明。不难看出,这个过程实际上是跟前面的 JOIN Token 方式是对等的,并不会提升节点证实过程的可管理性。因此 SPIRE 的 SSH 插件要求使用基于 CA 的 SSH 方法。
这种方式比上面的点对点认证方式稍微复杂一些。主要区别在于:
大概要完成几个工作:
例如 ChatGPT 告诉我的步骤是这样的:
几个关键的命令:
下面的命令可以用于 SSHD 初始化,利用 CA 生成 HostKey:
ssh-keygen -s /etc/ssh/ca \
-I "$(hostname --fqdn) host key" \
-n "$(hostname),$(hostname --fqdn),$(hostname -I|tr ' ' ',')" \
-V -5m:+3650d \
-h \
/etc/ssh/ssh_host_rsa_key.pub \
/etc/ssh/ssh_host_dsa_key.pub \
/etc/ssh/ssh_host_ecdsa_key.pub
查看一下生成的证书内容:
$ ssh-keygen -L -f ssh_host_rsa_key-cert.pub
ssh_host_rsa_key-cert.pub:
Type: ssh-rsa-cert-v01@openssh.com host certificate
Public key: RSA-CERT SHA256:[...]
Signing CA: RSA SHA256:[...] (using rsa-sha2-512)
Key ID: "ssh"
Serial: 0
Valid: from 2022-12-16T08:12:02 to 2032-12-13T08:17:02
Principals:
ssh
ssh
10.211.55.9
fdb2:2c26:f4e4:0:21c:42ff:fe2a:18c4
Critical Options: (none)
Extensions: (none)
生成主机凭据之后,将证书和密钥信息加入 /etc/ssh/sshd_config
:
HostKey /etc/ssh/ssh_host_ecdsa_key
HostKey /etc/ssh/ssh_host_ed25519_key
HostKey /etc/ssh/ssh_host_rsa_key
HostCertificate /etc/ssh/ssh_host_ecdsa_key-cert.pub
HostCertificate /etc/ssh/ssh_host_ed25519_key-cert.pub
HostCertificate /etc/ssh/ssh_host_rsa_key-cert.pub
和前面提到的 FingerPrint 方式类似,把 CA 证书公钥加入到客户端的 ~/.ssh/know_hosts
之中,例如:
@cert-authority * ssh-rsa ...AAAAB3NzaC1yc2EAAAADAQABAAABgQCb... someone@ssh
和前面生成主机身份证书的情况类似,这次去掉了 -h
参数:
ssh-keygen -s /etc/ssh/ca \
-I "$(whoami)@$(hostname --fqdn) user key" \
-n "$(whoami)" \
-V -5m:+3650d \
~/.ssh/id_rsa.pub
同样在 /etc/ssh/sshd_config
配置中加入 TrustedUserCAKeys
,具体取值为用户 CA 的公钥文件名。
完成这些内容之后,如果使用新的身份证书登录成功,则代表前置任务完成。否则可以参考以下材料:
前面的 SSH 配置只是个铺垫。SPIRE 使用 SSHPOP 实现了 Server 和 Agent 侧的节点证实插件,两个插件需要协同工作,官网的说明非常简明扼要:
稍稍延展说明一下需要注意的要点:
因此上面语焉不详的配置就比较清楚了:
cert_authorities
需要的是客户端证书内容,例如 ["ssh-rsa XXXX46IvQ+bDEXYvf8pM= someone@ssh"]
cert_authorities_path
指向节点 CA 公钥,例如 XXXX/ca.pub
host_cert_path
指向主机证书文件,例如 XXXX_key-cert.pub
host_key_path
指向密钥文件,例如 XXXX_key
配置完成之后,启动 SPIRE Server,获取并把 Trust Bundle 传递给 SPIRE Agent,启动 SPIRE Agent,可以看到生成了形如 "spiffe://spiffe.dom/spire/agent/sshpop/XXXX
的 SVID,说明这个证实过程已经成功完成。
本以为这是个顺便完成的东西,结果从来没想过 SSH 还有个 CA 这样的玩意,卡了好些时间,轻敌了。 另,值此辞旧迎新之际,祝大家身体健康、事业稳定、学习进步、物资充足——最重要运气爆棚吧:)