使用 Ansible Vault 加密内容

在制定了管理和存储 Vault 密码的策略后,就可以开始加密内容了。您可以使用 Ansible Vault 加密两种类型的内容:变量和文件。加密内容始终包含 !vault 标签,该标签告诉 Ansible 和 YAML 内容需要解密,以及一个 | 字符,该字符允许使用多行字符串。使用 --vault-id 创建的加密内容也包含 Vault ID 标签。有关加密过程和使用 Ansible Vault 加密的内容格式的更多详细信息,请参阅 使用 Ansible Vault 加密的文件格式。下表显示了加密变量和加密文件之间的主要区别

加密变量

加密文件

加密了多少内容?

纯文本文件中的变量

整个文件

何时解密?

按需解密,仅在需要时解密

在加载或引用时 [1]

可以加密什么?

仅变量

任何结构化数据文件

使用 Ansible Vault 加密单个变量

您可以使用 ansible-vault encrypt_string 命令加密 YAML 文件中的单个值。有关如何安全地显示 Vaulted 变量的一种方法,请参阅 安全地显示 Vaulted 变量

加密变量的优点和缺点

使用变量级加密,您的文件仍然易于阅读。您可以混合使用纯文本和加密变量,即使在 Playbook 或角色中内联也是如此。但是,密码轮换不像文件级加密那样简单。您无法 重新生成密钥 加密变量。此外,变量级加密仅适用于变量。如果您想加密任务或其他内容,则必须加密整个文件。

创建加密变量

ansible-vault encrypt_string 命令会对您键入(或复制或生成)的任何字符串进行加密并格式化,使其可以包含在 Playbook、角色或变量文件中。要创建基本的加密变量,请将三个选项传递给 ansible-vault encrypt_string 命令

  • Vault 密码的来源(提示、文件或脚本,无论有没有 Vault ID)

  • 要加密的字符串

  • 字符串名称(变量的名称)

模式如下所示

ansible-vault encrypt_string <password_source> '<string_to_encrypt>' --name '<string_name_of_variable>'

例如,要使用存储在 ‘a_password_file’ 中的唯一密码加密字符串 ‘foobar’,并将变量命名为 ‘the_secret’

ansible-vault encrypt_string --vault-password-file a_password_file 'foobar' --name 'the_secret'

上面的命令会创建以下内容

the_secret: !vault |
      $ANSIBLE_VAULT;1.1;AES256
      62313365396662343061393464336163383764373764613633653634306231386433626436623361
      6134333665353966363534333632666535333761666131620a663537646436643839616531643561
      63396265333966386166373632626539326166353965363262633030333630313338646335303630
      3438626666666137650a353638643435666633633964366338633066623234616432373231333331
      6564

要加密字符串 ‘foooodev’,使用存储在 ‘a_password_file’ 中的 ‘dev’ Vault 密码添加 Vault ID 标签 ‘dev’,并将加密变量命名为 ‘the_dev_secret’

ansible-vault encrypt_string --vault-id dev@a_password_file 'foooodev' --name 'the_dev_secret'

上面的命令会创建以下内容

the_dev_secret: !vault |
          $ANSIBLE_VAULT;1.2;AES256;dev
          30613233633461343837653833666333643061636561303338373661313838333565653635353162
          3263363434623733343538653462613064333634333464660a663633623939393439316636633863
          61636237636537333938306331383339353265363239643939666639386530626330633337633833
          6664656334373166630a363736393262666465663432613932613036303963343263623137386239
          6330

要加密从 stdin 读取的字符串 ‘letmein’,使用存储在 a_password_file 中的 ‘dev’ Vault 密码添加 Vault ID ‘dev’,并将变量命名为 ‘db_password’

echo -n 'letmein' | ansible-vault encrypt_string --vault-id dev@a_password_file --stdin-name 'db_password'

警告

直接在命令行(不使用提示)键入机密内容会将机密字符串留在您的 Shell 历史记录中。不要在测试之外执行此操作。

上面的命令会创建以下输出

Reading plaintext input from stdin. (ctrl-d to end input, twice if your content does not already have a new line)
db_password: !vault |
          $ANSIBLE_VAULT;1.2;AES256;dev
          61323931353866666336306139373937316366366138656131323863373866376666353364373761
          3539633234313836346435323766306164626134376564330a373530313635343535343133316133
          36643666306434616266376434363239346433643238336464643566386135356334303736353136
          6565633133366366360a326566323363363936613664616364623437336130623133343530333739
          3039

要提示输入要加密的字符串,请使用 ‘a_password_file’ 中的 ‘dev’ Vault 密码对其进行加密,将变量命名为 ‘new_user_password’ 并为其指定 Vault ID 标签 ‘dev’

ansible-vault encrypt_string --vault-id dev@a_password_file --stdin-name 'new_user_password'

上面的命令会触发以下提示

Reading plaintext input from stdin. (ctrl-d to end input, twice if your content does not already have a new line)

键入要加密的字符串(例如,‘hunter2’),按 ctrl-d,然后等待。

警告

在提供要加密的字符串后,不要按 Enter。这会将换行符添加到加密值中。

上面的序列会创建以下输出

new_user_password: !vault |
          $ANSIBLE_VAULT;1.2;AES256;dev
          37636561366636643464376336303466613062633537323632306566653533383833366462366662
          6565353063303065303831323539656138653863353230620a653638643639333133306331336365
          62373737623337616130386137373461306535383538373162316263386165376131623631323434
          3866363862363335620a376466656164383032633338306162326639643635663936623939666238
          3161

您可以将以上任何示例的输出添加到任何 Playbook、变量文件或角色中,以供将来使用。加密变量比纯文本变量大,但它们可以保护您的敏感内容,同时让 Playbook、变量文件或角色的其余部分保持纯文本,以便您可以轻松阅读。

查看加密变量

您可以使用 debug 模块查看加密变量的原始值。您必须传递用于加密该变量的密码。例如,如果您将上面最后一个示例创建的变量存储在名为 ‘vars.yml’ 的文件中,则可以像这样查看该变量的未加密值

ansible localhost -m ansible.builtin.debug -a var="new_user_password" -e "@vars.yml" --vault-id dev@a_password_file

localhost | SUCCESS => {
    "new_user_password": "hunter2"
}

使用 Ansible Vault 加密文件

Ansible Vault 可以加密 Ansible 使用的任何结构化数据文件,包括

  • 来自清单的组变量文件

  • 来自清单的主机变量文件

  • 使用 -e @file.yml-e @file.json 传递给 ansible-playbook 的变量文件

  • include_varsvars_files 加载的变量文件

  • 角色中的变量文件

  • 角色中的默认文件

  • 任务文件

  • 处理程序文件

  • 二进制文件或其他任意文件

整个文件都将在 Vault 中加密。

注意

Ansible Vault 使用编辑器来创建或修改加密文件。有关保护编辑器的一些指导,请参阅 保护编辑器的步骤

加密文件的优点和缺点

文件级加密易于使用。使用 重新生成密钥 命令可以轻松实现加密文件的密码轮换。加密文件不仅可以隐藏敏感值,还可以隐藏您使用的变量名称。但是,使用文件级加密,文件内容不再容易访问和读取。这对于加密的任务文件来说可能是一个问题。当加密变量文件时,有关如何将这些变量的引用保留在未加密的文件中,请参阅 安全地显示 Vaulted 变量。Ansible 在加载或引用时始终会解密整个加密文件,因为除非 Ansible 解密该文件,否则它无法知道是否需要该内容。

创建加密文件

要使用 ‘multi_password_file’ 中的 ‘test’ Vault 密码创建名为 ‘foo.yml’ 的新加密数据文件

ansible-vault create --vault-id test@multi_password_file foo.yml

该工具会启动一个编辑器(您使用 $EDITOR 定义的任何编辑器,默认编辑器是 vi)。添加内容。当您关闭编辑器会话时,该文件将保存为加密数据。文件头反映了用于创建它的 Vault ID

``$ANSIBLE_VAULT;1.2;AES256;test``

要创建一个新的加密数据文件,其中 Vault ID 为 ‘my_new_password’,并提示输入密码

ansible-vault create --vault-id my_new_password@prompt foo.yml

再次,在编辑器中向文件添加内容并保存。请务必记住在提示时创建的新密码,以便在需要解密该文件时找到它。

加密现有文件

要加密现有文件,请使用 ansible-vault encrypt 命令。此命令可以一次操作多个文件。例如

ansible-vault encrypt foo.yml bar.yml baz.yml

要使用“project” ID 加密现有文件,并在提示时输入密码

ansible-vault encrypt --vault-id project@prompt foo.yml bar.yml baz.yml

查看加密文件

要查看加密文件的内容而不编辑它,可以使用 ansible-vault view 命令

ansible-vault view foo.yml bar.yml baz.yml

编辑加密文件

要就地编辑加密文件,请使用 ansible-vault edit 命令。此命令将文件解密到临时文件,允许您编辑内容,然后在您关闭编辑器时保存并重新加密内容并删除临时文件。例如

ansible-vault edit foo.yml

要编辑使用 vault2 密码文件加密并分配了 vault ID pass2 的文件

ansible-vault edit --vault-id pass2@vault2 foo.yml

更改加密文件的密码和/或 vault ID

要更改一个或多个加密文件的密码,请使用 rekey 命令

ansible-vault rekey foo.yml bar.yml baz.yml

此命令可以一次重新加密多个数据文件,并会要求输入原始密码和新密码。要为重新加密的文件设置不同的 ID,请将新 ID 传递给 --new-vault-id。例如,要将使用“preprod1” vault ID 加密的一系列文件从“ppold”文件重新加密到“preprod2” vault ID,并在提示时输入新密码

ansible-vault rekey --vault-id preprod1@ppold --new-vault-id preprod2@prompt foo.yml bar.yml baz.yml

解密加密文件

如果您有不再需要加密的加密文件,您可以通过运行 ansible-vault decrypt 命令永久解密它。此命令会将未加密的文件保存到磁盘,因此请确保您不想 edit 它。

ansible-vault decrypt foo.yml bar.yml baz.yml

保护编辑器的步骤

Ansible Vault 依赖于您配置的编辑器,这可能成为信息泄露的来源。大多数编辑器都有防止数据丢失的方法,但这些方法通常依赖于额外的纯文本文件,这些文件可能包含您机密的明文副本。请查阅您的编辑器文档,配置编辑器以避免泄露安全数据。以下章节提供了关于常见编辑器的一些指导,但不应将其视为保护编辑器的完整指南。

vim

您可以在命令模式下设置以下 vim 选项,以避免信息泄露的情况。您可能需要修改更多设置以确保安全,尤其是在使用插件时,请查阅 vim 文档。

  1. 禁用在崩溃或中断时充当自动保存的交换文件。

set noswapfile
  1. 禁用备份文件的创建。

set nobackup
set nowritebackup
  1. 禁用 viminfo 文件从当前会话复制数据。

set viminfo=
  1. 禁用复制到系统剪贴板。

set clipboard=

您可以选择将这些设置添加到 .vimrc 中,以应用于所有文件,或者仅应用于特定路径或扩展名。有关详细信息,请参阅 vim 手册。

Emacs

您可以设置以下 Emacs 选项,以避免信息泄露的情况。您可能需要修改更多设置以确保安全,尤其是在使用插件时,请查阅 Emacs 文档。

  1. 不要将数据复制到系统剪贴板。

(setq x-select-enable-clipboard nil)
  1. 禁用备份文件的创建。

(setq make-backup-files nil)
  1. 禁用自动保存文件。

(setq auto-save-default nil)