当简单地使用命令行时,主要策略是使用cache
git 凭据助手:
git config --global credential.helper cache
git config --global credential.username {{ gituser }}
git pull {{ repository1 }}
... asks password
... pulls
git pull {{ repository2 }}
... pulls
... etc.
但是如果我使用 ansible git 模块,提示不起作用(也不实用)。我目前看到的唯一解决方案是使用:
- git: repo=https://{{ gituser }}:{{ gitpass }}@{{ repo_url }} dest={{ dest }}
我在哪里获取gituser
并gitpass
使用vars_prompt:
,或者从 ansible 的本地安全存储获取。然而,这有一个不良的副作用,即它以{{ dest }}/.git/config
纯文本形式存储密码,我想避免这种情况。
有没有办法在剧本运行时从 ansible 设置密码,但不将其存储在服务器上?
答案1
有没有办法在剧本运行时从 ansible 设置密码,但不将其存储在服务器上?
该ansible
git
模块目前没有办法指定密码是临时的,即确保.git
在克隆上游存储库后将其从目录中删除。
command
您可以通过在调用模块之后调用模块来“破解”这一点git
,以从存储库配置中删除上游远程,这显然会删除所有机密。这确实意味着机密在拉取操作期间暂时存储在主机上——这可能不合适,具体取决于您正在使用的威胁模型。
有更好的方法吗?
这些场景是SSH 密钥认证脱颖而出,每EEAA 的评论。如果您可以使用 SSH 向您的 git 上游进行身份验证,则可以在 Ansible 会话中使用 SSH 代理转发将您的 SSH 代理从控制主机传递到目标服务器。
这是一种强大的凭证共享方法,它仅在会话期间有效,因此机密留在远程主机上的长期风险被最小化。
答案2
最后,我采用了与 @CosmicOssifrage 提到的 hack 类似的解决方案。主要区别在于,这git remote remove origin
不足以删除所有机密,因为密码被写入了 中的各种文件中.git/logs/
。所以最后我只是创建了一个包含文件,调用 sed 来清理混乱:
- name: git password cleanup
shell: cd {{ git_dir }}/.git ; sed -i 's/https:\/\/{{ gituser }}:{{ gitpass }}@/https:\/\/{{ gituser }}@/' config logs/HEAD logs/refs/heads/* logs/refs/remotes/*/*
这叫做:
- git: repo={{ repository }} dest=/var/www/
- include: ../../library/git_password_cleanup.yml git_dir=/var/www/
这种方法无法解决的问题是,如果 git checkout 由于某种原因失败,则不会运行下一个命令,从而将凭据保留在那里。对于当前的 ansible 故障处理策略来说,这个解决方案会相当尴尬,所以我选择冒这个险。