Jenkins SSH 主机/用户证书工作流程

Jenkins SSH 主机/用户证书工作流程

每次运行某个 Ansible 阶段时如何设置 SSH 密钥签名过程?或者至少在某个间隔内设置。

我有使用 Terraform 创建虚拟机然后运行 ​​Ansible 的管道。在 cloud-init 阶段,创建并签名主机密钥,并配置公共用户 CA 密钥。客户端/主机 CA 颁发机构在 HashiCorp Vault 中配置/运行。因此,此时,无论配置了哪些虚拟机,我都可以通过 SSH 进入每个虚拟机,因为我已在@cert-authority *.example.com ecdsa-sha2-nistp521 AAAAB3NzaC1yc2EAAA...中全局设置了主机 CA 公钥/etc/ssh/ssh_known_hosts。我需要做的就是创建新的个人密钥并对其进行签名,因为我的 TTL 很短。

但这在 Jenkins 中不起作用。Jenkins 将所有 SSH 密钥存储在 下/var/lib/jenkins/.ssh,默认情况下什么都没有。如果只是为了测试,我将我的个人用户(或生成的)密钥和证书 + ssh 配置文件复制到 中/var/lib/jenkins/.ssh,那么 Jenkins 可以愉快地运行 Ansible。但是,每次我在 infra repo 中执行某些提交时,我都无法生成、签名和复制 jenkins 密钥。创建长期有效的证书也不好。

SSH 密钥签名和轮换的惯用自动化工作流程是什么?

答案1

我将自己列出“不好”的解决方案。不好,因为密钥轮换是手动的,而且由于我们很懒,TTL 很可能会很长。

在 Vault 中,你需要创建一个新的“jenkins”SSH 角色,其 TTL 如下52w

然后,理想情况下,您需要在 Jenkins 主机上创建新的密钥。

ssh-keygen -t ecdsa -b 521 -f /var/lib/jenkins/.ssh/id_ecdsa -C "jenkins@jenkins-01"

然后通过 Vault 签名

vault write -field=signed_key ssh-client-signer/sign/jenkinsrole public_key=/var/lib/jenkins/.ssh/id_ecdsa.pub > /var/lib/jenkins/.ssh/id_ecdsa-cert.pub

这意味着 Vault 应该在系统上。...这是一个两难的问题 - 您是否想通过网络复制 ssh 密钥(包括私钥),这有点奇怪,或者您想在 Jenkins 机器上安装 Vault。这取决于你。

获得id_ecdsa-cert.pub证书后,您可以检查它ssh-keygen -Lf /var/lib/jenkins/.ssh/id_ecdsa-cert.pub并查看其有效期、原理等是否正确。

因为基础设施很可能会出现偏差,所以静态存储 SSH 配置/var/lib/jenkins/.ssh/config将会很麻烦。

相反,你可以创建ansible-ssh.cfg包含类似内容的文件

Host bastion
  HostName bastion.example.com
  IdentitiesOnly yes
  IdentityFile ~/.ssh/id_ecdsa
  CertificateFile ~/.ssh/id_ecdsa-cert.pub
  Port 22
  Protocol 2
  User ansible
  LogLevel INFO

该文件可以(应该)与 Ansible 代码的其余部分位于一起。

然后,在ansible.cfg文件中包含 SSH 节

[ssh_connection]
ssh_args = -F ./ansible-ssh.cfg

这样,Ansible 将始终获取最新的 SSH 配置。

如果您使用 Terraform,那么可以动态更新 SSH 配置文件以包含新主机等。

此解决方案不仅限于 Vault。它ssh-keygen本身也可以轻松实现。

更新:最终我得到了一个小型 shell 脚本,该脚本使用 approle 进行授权,然后签署证书。Systemd 服务和 Timer 单元执行该 shell 脚本,该脚本每天进行证书轮换。因此此时 Jenkins 使用它自己的新用户证书来运行 Terraform 和 Ansible。 https://stackoverflow.com/a/65875997/6651080

相关内容