管理 vault 密码
如果你能制定一套管理 vault 密码的策略,那么管理加密内容会变得更加容易。vault 密码可以是任何你选择的字符串。没有特殊的命令来创建 vault 密码。但是,你需要记录你的 vault 密码。每次使用 Ansible Vault 加密变量或文件时,都必须提供一个密码。当你在命令或剧本(playbook)中使用加密的变量或文件时,必须提供与加密时相同的密码。要制定管理 vault 密码的策略,请从以下两个问题开始:
你是想用同一个密码加密所有内容,还是针对不同需求使用不同密码?
你想将密码存储在哪里?
在单密码和多密码之间做出选择
如果你拥有一个小团队或只有少量敏感值,你可以为所有使用 Ansible Vault 加密的内容使用同一个密码。请按照下文所述,将你的 vault 密码安全地存储在文件或密钥管理器(secret manager)中。
如果你拥有一个较大的团队或许多敏感值,可以使用多个密码。例如,你可以为不同的用户或不同的访问级别使用不同的密码。根据你的需求,你可能想为每个加密文件、每个目录或每个环境设置不同的密码。你可能有一个剧本,其中包含两个变量文件,一个用于开发环境(dev),一个用于生产环境(production),且分别用两个不同的密码加密。运行剧本时,你可以使用 vault ID 为目标环境选择正确的 vault 密码。
使用 vault ID 管理多个密码
如果你使用多个 vault 密码,可以通过 vault ID 来区分它们。vault ID 的使用方式有三种:
在创建加密内容时,通过
--vault-id将其传递给 ansible-vault 命令在存储该 vault ID 对应密码的地方将其包含在内(参见 存储和访问 vault 密码)
在运行使用该 vault ID 加密内容的剧本时,通过
--vault-id将其传递给 ansible-playbook 命令
当你将 vault ID 作为 ansible-vault 命令的选项传递时,你实际上是为加密内容添加了一个标签(一个提示或昵称)。这个标签记录了你使用哪个密码对其进行了加密。加密的变量或文件在头部以明文形式包含该 vault ID 标签。vault ID 是加密内容之前的最后一个元素。例如:
my_encrypted_var: !vault | $ANSIBLE_VAULT;1.2;AES256;dev 30613233633461343837653833666333643061636561303338373661313838333565653635353162 3263363434623733343538653462613064333634333464660a663633623939393439316636633863 61636237636537333938306331383339353265363239643939666639386530626330633337633833 6664656334373166630a363736393262666465663432613932613036303963343263623137386239 6330
除了标签外,你还必须为相关的密码提供一个来源。根据你存储 vault 密码的方式,来源可以是提示符、文件或脚本。其模式如下:
--vault-id label@source
如果你的剧本使用了多个用不同密码加密的变量或文件,那么在运行该剧本时必须传递 vault ID。你可以单独使用 --vault-id,或者配合 --vault-password-file 或 --ask-vault-pass 使用。其模式与创建加密内容时相同:包含标签以及匹配密码的来源。
请参阅下文关于使用 vault ID 加密内容以及使用 vault ID 加密内容的示例。--vault-id 选项适用于任何与 vault 交互的 Ansible 命令,包括 ansible-vault、ansible-playbook 等。
vault ID 的局限性
Ansible 并不强制要求每次使用特定的 vault ID 标签时都必须使用相同的密码。你可以使用同一个 vault ID 标签但使用不同的密码来加密不同的变量或文件。这种情况通常发生在你在提示符处输入密码时出现错误。你也可以故意为同一个 vault ID 标签使用不同的密码。例如,你可以将每个标签作为一类密码的引用,而不是单个密码。在这种情况下,你必须始终知道在特定语境下应使用哪个具体的密码或文件。然而,更常见的情况是你误将两个文件用同一个 vault ID 标签但不同的密码进行了加密。如果你意外地用相同的标签但不同的密码加密了两个文件,你可以 重新加密(rekey) 其中一个文件来解决此问题。
强制执行 vault ID 匹配
默认情况下,vault ID 标签仅是一个提示,用于提醒你使用了哪个密码来加密变量或文件。Ansible 不会检查加密内容头部中的 vault ID 是否与你在使用该内容时提供的 vault ID 匹配。Ansible 会解密由你的命令或剧本调用的所有使用你所提供密码加密的文件和变量。若要检查加密内容,且仅在其包含的 vault ID 与你通过 --vault-id 提供的 ID 匹配时才对其进行解密,请设置配置选项 DEFAULT_VAULT_ID_MATCH。当你设置 DEFAULT_VAULT_ID_MATCH 后,每个密码仅用于解密使用相同标签加密的数据。这种方式高效且可预测,可以在不同值使用不同密码加密时减少错误。
注意
即使启用了 DEFAULT_VAULT_ID_MATCH 设置,Ansible 仍然不强制要求每次使用特定 vault ID 标签时都必须使用相同的密码。
存储和访问 vault 密码
你可以记住你的 vault 密码,或者从任何来源手动复制 vault 密码并将其粘贴到命令行提示符中,但大多数用户会将它们安全地存储,并在 Ansible 内部根据需要访问。你有两种在 Ansible 内部存储 vault 密码的选项:存储在文件中,或存储在第三方工具中(如系统钥匙串或密钥管理器)。如果你将密码存储在第三方工具中,你需要一个 vault 密码客户端脚本以便在 Ansible 内部检索它们。
将密码存储在文件中
要将 vault 密码存储在文件中,请将密码作为字符串输入到文件的单行中。确保文件的权限设置正确。请勿将密码文件添加到源代码控制(如 Git)中。
当你运行一个使用存储在文件中的 vault 密码的剧本时,请在 --vault-password-file 标志中指定该文件。例如:
ansible-playbook --extra-vars @secrets.enc --vault-password-file secrets.pass
通过 vault 密码客户端脚本将密码存储在第三方工具中
你可以将 vault 密码存储在系统钥匙串、数据库或密钥管理器中,并使用 vault 密码客户端脚本在 Ansible 内部检索它们。将密码作为单行字符串输入。如果你的密码具有 vault ID,请以兼容你的密码存储工具的方式对其进行存储。
创建 vault 密码客户端脚本的步骤:
创建一个文件名以
-client或-client.EXTENSION结尾的文件使该文件具有可执行权限
- 在脚本内部:
将密码打印到标准输出(stdout)
接受
--vault-id选项如果脚本需要提示输入数据(例如,数据库密码),请将提示显示在 TTY 中。
当你运行一个使用存储在第三方工具中 vault 密码的剧本时,请在 --vault-id 标志中将脚本指定为来源。例如:
ansible-playbook --vault-id dev@contrib-scripts/vault/vault-keyring-client.py
Ansible 在执行客户端脚本时会带上 --vault-id 选项,这样脚本就知道你指定了哪个 vault ID 标签。例如,一个从密钥管理器加载密码的脚本可以使用 vault ID 标签来选择“dev”或“prod”密码。上面的示例命令将导致以下客户端脚本执行过程:
contrib-scripts/vault/vault-keyring-client.py --vault-id dev
有关从系统钥匙串加载密码的客户端脚本示例,请参阅 vault-keyring-client 脚本。