使用加密变量和文件

当您运行使用加密变量或文件的任务或剧本时,您必须提供解密变量或文件的密码。您可以在命令行中执行此操作,也可以在配置选项或环境变量中设置默认密码源。

传递单个密码

如果任务或剧本中的所有加密变量和文件都需要使用单个密码,您可以使用 --ask-vault-pass--vault-password-file cli 选项。

提示输入密码

ansible-playbook --ask-vault-pass site.yml

/path/to/my/vault-password-file 文件中检索密码

ansible-playbook --vault-password-file /path/to/my/vault-password-file site.yml

从保险库密码客户端脚本 my-vault-password-client.py 中获取密码

ansible-playbook --vault-password-file my-vault-password-client.py

传递保险库 ID

您也可以使用 --vault-id 选项传递带有其保险库标签的单个密码。当在单个清单中使用多个保险库时,这种方法更清晰。

提示输入“dev”保险库 ID 的密码

ansible-playbook --vault-id dev@prompt site.yml

dev-password 文件中检索“dev”保险库 ID 的密码

ansible-playbook --vault-id dev@dev-password site.yml

从保险库密码客户端脚本 my-vault-password-client.py 中获取“dev”保险库 ID 的密码

ansible-playbook --vault-id [email protected]

传递多个保险库密码

如果您的任务或剧本需要使用不同的保险库 ID 加密的多个加密变量或文件,您必须使用 --vault-id 选项,传递多个 --vault-id 选项以指定保险库 ID(“dev”、“prod”、“cloud”、“db”)和密码的来源(提示、文件、脚本)。例如,要使用从文件中读取的“dev”密码并提示输入“prod”密码

ansible-playbook --vault-id dev@dev-password --vault-id prod@prompt site.yml

默认情况下,保险库 ID 标签(dev、prod 等)只是提示。Ansible 尝试使用每个密码来解密保险库内容。与加密数据具有相同标签的密码将首先尝试,之后,每个保险库秘密将按照它们在命令行中提供的顺序尝试。

如果加密数据没有标签,或者标签与任何提供的标签不匹配,将按照指定的顺序尝试密码。在上面的示例中,将首先尝试“dev”密码,然后尝试“prod”密码,以防 Ansible 不知道使用哪个保险库 ID 对某些内容进行加密。

使用 --vault-id 不带保险库 ID

--vault-id 选项也可以在不指定保险库 ID 的情况下使用。此行为等同于 --ask-vault-pass--vault-password-file,因此很少使用。

例如,要使用密码文件 dev-password

ansible-playbook --vault-id dev-password site.yml

提示输入密码

ansible-playbook --vault-id @prompt site.yml

要从可执行脚本 my-vault-password-client.py 中获取密码

ansible-playbook --vault-id my-vault-password-client.py

配置使用加密内容的默认值

设置默认保险库 ID

如果您使用一个保险库 ID 的频率高于任何其他保险库 ID,您可以设置配置选项 DEFAULT_VAULT_IDENTITY_LIST 以指定默认保险库 ID 和密码源。无论何时您不指定 --vault-id,Ansible 将使用默认保险库 ID 和来源。您可以为该选项设置多个值。设置多个值等同于传递多个 --vault-id cli 选项。

设置默认密码源

如果您不想在命令行中提供密码文件,或者如果您使用一个保险库密码文件的频率高于任何其他保险库密码文件,您可以设置 DEFAULT_VAULT_PASSWORD_FILE 配置选项或 ANSIBLE_VAULT_PASSWORD_FILE 环境变量以指定要使用的默认文件。例如,如果您设置 ANSIBLE_VAULT_PASSWORD_FILE=~/.vault_pass.txt,Ansible 将自动在该文件中搜索密码。这很有用,例如,如果您从持续集成系统(如 Jenkins)中使用 Ansible。

您引用的文件可以是包含密码(纯文本)的文件,也可以是返回密码的脚本(具有可执行权限)。

何时显示加密文件?

通常,使用 Ansible Vault 加密的內容在执行后仍然保持加密。但是,有一个例外。如果您将加密文件作为 src 参数传递给 copytemplateunarchivescriptassemble 模块,该文件将不会在目标主机上加密(假设您在运行剧本时提供了正确的保险库密码)。这种行为是故意的,也很有用。您可以加密配置文件或模板以避免共享配置的详细信息,但是当您将该配置复制到环境中的服务器时,您希望它被解密,以便本地用户和进程可以访问它。

使用 Ansible Vault 加密的格式文件

Ansible Vault 创建 UTF-8 编码的 txt 文件。文件格式包括以换行符结尾的标题。例如

$ANSIBLE_VAULT;1.1;AES256

$ANSIBLE_VAULT;1.2;AES256;vault-id-label

标题包含最多四个元素,用分号 (;) 分隔。

  1. 格式 ID ($ANSIBLE_VAULT)。目前,$ANSIBLE_VAULT 是唯一有效的格式 ID。格式 ID 标识使用 Ansible Vault 加密的内容(使用 vault.is_encrypted_file())。

  2. 保险库格式版本 (1.X)。目前,所有受支持的 Ansible 版本在提供带标签的保险库 ID 时,默认情况下将使用“1.1”或“1.2”。“1.0”格式仅支持读取(并且在写入时将自动转换为“1.1”格式)。格式版本目前仅用作精确的字符串比较(版本号目前没有“比较”)。

  3. 用于加密数据的密码算法 (AES256)。目前,AES256 是唯一支持的密码算法。Vault 格式 1.0 使用“AES”,但当前代码始终使用“AES256”。

  4. 用于加密数据的保险库 ID 标签(可选,vault-id-label)。例如,如果您使用 --vault-id dev@prompt 加密文件,则保险库 ID 标签为 dev

注意:将来,标题可能会更改。格式 ID 和格式版本之后的字段取决于格式版本。未来的保险库格式版本可能会添加更多密码算法选项和/或其他字段。

文件的其余内容是“保险库文本”。保险库文本是加密密文的文本装甲版本。每行 80 个字符宽,最后一行的长度可能更短。

Ansible Vault 有效负载格式 1.1 - 1.2

保险库文本是密文和 SHA256 摘要的串联,结果是“十六进制化”的。

“十六进制化”指的是 Python 标准库的 binascii 模块的 hexlify() 方法。

十六进制化结果为

  • 盐的十六进制化字符串,后面跟着换行符 (0x0a)

  • 加密 HMAC 的十六进制化字符串,后面跟着换行符。HMAC 为

    • 一个 RFC2104 风格的 HMAC

      • 输入为

        • AES256 加密的密文

        • 一个 PBKDF2 密钥。该密钥、密码密钥和密码 IV 由以下内容生成

          • 盐(以字节为单位)

          • 10000 次迭代

          • SHA256() 算法

          • 前 32 个字节是密码密钥

          • 后 32 个字节是 HMAC 密钥

          • 剩余的 16 个字节是密码 IV

  • 密文的十六进制化字符串。密文为

  • AES256 加密的 data。data 使用以下方法加密

    • AES-CTR 流密码

    • 密码密钥

    • IV

    • 一个从整数 IV 种子化的 128 位计数器块

    • 明文

      • 原始明文

      • 填充到 AES256 块大小。(用于填充的 data 基于 RFC5652