如何在每次 Ansible 階段執行時設定 SSH 金鑰簽署過程?或至少每隔一段時間。
我有一個管道,它使用 Terraform 創建虛擬機,然後運行 Ansible。在 cloud-init 階段,建立並簽署主機金鑰,並配置公用使用者 CA 金鑰。客戶端/主機 CA 權限在 HashiCorp Vault 中配置/運行。因此,此時,無論配置什麼虛擬機,我都可以透過 SSH 連接到每個虛擬機,因為我@cert-authority *.example.com ecdsa-sha2-nistp521 AAAAB3NzaC1yc2EAAA...
在 .NET 中全域設定了主機 CA 公鑰/etc/ssh/ssh_known_hosts
。我需要做的就是創建新的個人金鑰並對其進行簽名,因為我的 TTL 很短。
但這在詹金斯中不起作用。 Jenkins 將所有 SSH 金鑰儲存在下面/var/lib/jenkins/.ssh
,預設情況下什麼都沒有。如果只是出於測試原因,我將我的個人用戶(或生成的)金鑰和證書+ ssh 設定檔複製到/var/lib/jenkins/.ssh
,那麼 Jenkins 可以愉快地運行 Ansible。但是,每次我在基礎存儲庫中進行一些提交時,我都無法生成、簽署和複製詹金斯密鑰。創建長壽證書的味道也不好。
SSH 金鑰簽章和輪替的慣用自動化工作流程是什麼?
答案1
我將自己列出“BAD”解決方案。不好,因為密鑰輪換是手動的,而且 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 金鑰(包括私人金鑰)嗎?由你決定。
獲得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 服務和計時器單元執行每天進行憑證輪調的 shell 腳本。因此,此時 Jenkins 使用自己的新使用者憑證來執行 Terraform 和 Ansible。 https://stackoverflow.com/a/65875997/6651080