我们计划在项目中使用ansible保管库,以防止git中的密码或密钥泄漏。

想法是将所有敏感数据放入一个普通文件中,然后在使用git之前使用密码使用ansible-vault对文件进行加密。

要解密文件,我们必须将Vault密码传递给ansible,我正在考虑3种可能性:


将其存储在服务器环境变量中
将其作为选项传递给ansible-playbook命令
将其存储到未版本控制的文件中。

是否还有其他选项,这是最好的(也是安全的)方式存储ansible-vault密码,ansible最佳做法文档对此没有说明。

评论

非常相关的演讲:danielsomerfield.github.io/turtles

这里有一些很好的答案:devops.stackexchange.com/questions/3806/…

#1 楼


我们的想法是将我们所有的敏感数据都放入[...]


在实施解决方案之前,应仔细分析这句话中“全部”的含义计划。

Ansible Vault是一个非常有用的工具,但仅应用于存储以下秘密: />容易使主人变得毫无用处,使他们不知道他们,但可能非法地“记住”他们(通常是外来雇员)。

第二点很重要。

许多人,甚至可能是整个DevOps团队,都将可以访问该可用的保险库密码,因此可以访问所有机密。如果需要,具有未经授权访问权限的人或机器应无权使用它们。

具体来说,如果您使用ansible部署数据库及其用户,则使用Vault中的密码,但是如果该服务可以从Internet获得并且不需要任何VPN身份验证,则必须非常小心(并且很可能考虑其他解决方案)! (DevOps)暴露给该机密,如果对它们施加了一个安全屏障(例如,撤销了VPN访问),则应该不能使用“记住的”密码。除此之外,在更改密码之前,也应撤消对源代码存储库(存储库的访问)的访问。 />
尝试在保管库中存储Internet上任何人或计算机可以使用的机密将是一个错误(例如,用户的VPN凭据)。


还有其他选择,这是存储ansible-Vault密码的最佳(和安全)方法。


在上一段条件下,我认为一个好的做法是是:


将文件库密码存储在外部安全文件库中(例如HashiCorp的文件库或用于凭据管理的任何SaaS)
允许对DevOps的外部文件库项进行访问(他们需要使用密码测试)和CI / CD系统或Ansible控制器

遵守约定以使用机密!您将无法查看对机密所做的更改,也无法grep机密文件中的ansible变量!因此,从一开始就要彻底。一个好的约定是用secret_前缀命名存储在ansible保管库中的所有变量。当您看到类似以下内容的内容时:

postgres.yml:

postgres_password: "{{ secret_postgres_password }}"


,您将知道该值存储在ansible保管库中。 br />


评论


有关将Ansible Vault密码存储在更安全的地方(HashiCorp Vault或SaaS保险库(例如AWS Secrets Manager))的要点。但是,如果有人离开了团队,仍然需要轮换(更改),因为他们即使短暂访问也可以访问。可以通过使用单独的保管库(开发,测试,生产)(即YAML中的机密文件)缓解这种情况。 Ansible 2.4+还允许您使用“文件库ID”为此类文件指定不同的密码-文档页面

– RichVel
19年1月30日在7:23

Ansible 2.3引入了一项功能,该功能仅加密YAML文件中的值,而不加密整个文件中的值-比您在答案末尾的第3点中提到的旧约定更易于维护。

– RichVel
19年2月3日在14:01

#2 楼


我们计划在项目中使用ansible保险库,以防止git中的密码或密钥泄漏。使用Ansible保险库这样的系统有很多安全方面的缺点:


没有审计线索可以了解谁访问了该系统。随身带走秘密商店
员工离职时,删除他们的访问权限意味着更改密码并将其重新分配给其他人
旧版本的Vault可以永久使用已泄露的Ansible Vault密码,因为存储在版本控制中的秘密必须是静态的

没有这些缺点的,可能更安全,虽然更复杂的系统是使用Hashicorp Vault存储您的秘密。然后,您仍然可以使用https://github.com/jhaals/ansible-vault从Ansible Vault中几乎轻松地从中提取值。 ,这就是乌龟的问题。对于人类而言,我认为最好的解决方案是定期提示输入密码,并在很短的时间后使令牌过期。对于机器,请使用AWS身份验证后端或类似身份验证。您永远无法完全摆脱对某个地方进行身份验证的需要,但是您可以使攻击者更难获得对其的访问权。您,那么肯定可以使用Ansible保管库。为什么要将密码完全存储在各个计算机上?对于交互式使用,您只需提示输入密码,用户便可以将其存储在所选的密码管理器中。 OS X上的iTerm具有与Keychain.app集成的密码管理器,使密码管理器在此特别容易。

评论


使用ansible保管库的最佳方法是不使用它。.谢谢指出!

–风暴
18年2月8日在8:09

对于中小型组织,我建议您考虑使用基于云的秘密管理器(例如AWS Secrets Manager),这比为HashiCorp Vault运行高可用性集群要少得多,但是可以大大改善Ansible的安全性。保险柜,包括审核和精细的访问控制。当然,您最终会依赖于该服务,但是可以通过一些应用程序编码和Ansible工作将其封装。主要好处是Ansible根本不需要管理某些秘密,例如数据库密码-只需让应用从机密管理器中获取机密即可。

– RichVel
19年1月30日在7:26

#3 楼

这很大程度上取决于您在处理敏感数据方面的内部政策。

我想告诉你我的做法,并解释一下我认为的利弊。我将Ansible Vault密码保存在控制机上的文件中,并有一个指向它的环境变量:

测试和开发剧本),一些同事也有,当然,我们在主要的Ansible控制机器上也有。

优点:


不在共享的位置/存储库中(您所说的是非版本文件)
一个人不需要知道您的Ansible Vault密码来运行剧本(这是在您拥有CI工具(例如Jenkins)的条件下,您可以在其中轻松启动剧本)的情况。 />旋转密码不容易
每个在您的剧本上工作的人都需要将其放在工作站上在您的日常操作中采用。

评论


不错的组合..检查其他答案,尽管您可能会感兴趣。

–风暴
18年2月8日在8:12

#4 楼

我使用keyctl将它们存储在终端会话中。打开终端会话时,只需输入一次密码。

keyctl允许您将密码存储在不同级别,我选择了会话级别,但可以将其存储在用户或主机级别。 >
要执行此操作,请在文件ansible.cfg中定义属性vault_identity_list

vault_identity_list = my_key@./scripts/my_key.py


在目录./scripts中创建一个名为my_key.py的Python脚本内容:

 #!/usr/bin/python
# coding: utf8

import subprocess
import sys
import getpass

key_name = "my_key"
try:
  keyid = int(subprocess.Popen("keyctl request user {} @s".format(key_name), shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE).stdout.read())
  print subprocess.Popen("keyctl print {}".format(str(keyid)), shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE).stdout.read().rstrip()
except ValueError:
  sys.stderr.write("Password for '{}' : ".format(key_name))
  password = getpass.getpass("").rstrip()
  subprocess.Popen("keyctl add user {} '{}' @s".format(key_name, password), shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
  print password
 


现在,当您键入ansible-playbook -e @my_vault.vault ...时,它每次只要求您输入一次密码会话。

通过这种方法,您可以轻松地使用多个保管库(每个保管库都带有python脚本,我找不到在所有保管库中使用相同脚本的方法)。

#5 楼

看看这个项目来管理您的ansant Vault加密密码https://github.com/Smile-SA/ansible-vault-manager

它可以处理带有插件的多个密钥环存储平台(仅目前)已实施AWS SSM)。将鼠标悬停与当前的Ansible项目进行集成非常容易...

评论


如果您更轻松地将其具体化,而不是添加一般性的内容,将会有所帮助。我阅读了github页面的自述文件,但是您能否更改答案,所以它包含一个清晰的示例?我想尝试一下。

– 030
19年11月11日15:15