确定 Vault 密码的管理与存储策略之后,就可以开始加密内容。Ansible Vault 支持加密变量和文件。加密内容始终包含 !vault 标签,告诉 Ansible 和 YAML 该内容需要解密;还包含 | 字符,以支持多行字符串。用 --vault-id 创建的加密内容也包含 Vault ID 标签。加密过程和格式详见 Ansible Vault 格式。两类加密的主要区别如下:
| 对比项 | 加密变量 | 加密文件 |
|---|---|---|
| 加密范围 | 明文文件中的变量 | 整个文件 |
| 解密时机 | 按需,只在需要时解密 | 每次加载或引用时解密 |
| 可加密内容 | 仅变量 | 任意结构化数据文件 |
Ansible 必须先解密文件,才能知道是否需要其中的内容,因此会解密 playbook 和角色引用的全部加密文件。
加密单个变量
可使用 ansible-vault encrypt_string 加密 YAML 文件中的单个值。若要让加密变量在安全的前提下仍易于查找,参见变量与 Vault 的组织建议。
变量加密的优缺点
变量级加密保持文件易读,可以混合明文和加密变量,甚至在 play 或角色中直接混用。但密码轮换不如文件级加密简单:加密变量无法使用 rekey。变量级加密仅适用于变量;要加密任务或其他内容,必须加密整个文件。
创建加密变量
ansible-vault encrypt_string 将输入、复制或生成的字符串加密,并格式化为可放入 playbook、角色或变量文件的内容。创建基本加密变量需要提供三个参数:
- 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 密码,添加 dev ID 标签,并将变量命名为 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
要从标准输入读取并加密 letmein,使用 a_password_file 中的 dev 密码,添加 dev ID,将变量命名为 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 密码,将变量命名为 new_user_password,并添加 dev ID 标签:
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、变量文件或角色,供以后使用。加密变量比明文变量更大,但能够保护敏感内容,同时保持其余内容为明文,便于阅读。
查看加密变量
可以使用 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 使用的结构化数据文件,包括:
- 清单中的组变量文件。
- 清单中的主机变量文件。
- 通过
-e @file.yml或-e @file.json传给 ansible-playbook 的变量文件。 - 由
include_vars或vars_files加载的变量文件。 - 角色中的变量文件。
- 角色中的默认值文件。
- 任务文件。
- 处理器文件。
- 二进制文件或其他任意文件。
Vault 会加密整个文件。
注意:Ansible Vault 使用编辑器创建或修改加密文件。编辑器安全设置见本文后面的说明。
文件加密的优缺点
文件级加密易于使用,通过 rekey 轮换密码也很直接。它不仅可以隐藏敏感值,还可以隐藏变量名称。不过,加密之后文件内容不再易于访问和阅读,这可能给加密任务文件带来问题。加密变量文件时,可按前述变量组织建议,在未加密文件中保留变量引用。Ansible 每次加载或引用加密文件时都会解密整个文件,因为只有解密后才能知道是否需要其内容。
创建加密文件
要使用 multi_password_file 中的 test 密码,创建名为 foo.yml 的加密数据文件:
ansible-vault create --vault-id test@multi_password_file foo.yml
工具会启动 $EDITOR 指定的编辑器,默认是 vi。加入内容,关闭编辑器会话后,文件会保存为加密数据。文件头反映创建时使用的 Vault ID:
``$ANSIBLE_VAULT;1.2;AES256;test``
要创建一个分配了 my_new_password ID 的加密文件,并提示输入密码:
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 加密、分配了 pass2 ID 的文件:
ansible-vault edit --vault-id pass2@vault2 foo.yml
更改密码或 Vault ID
使用 ansible-vault rekey 更改一个或多个加密文件的密码:
ansible-vault rekey foo.yml bar.yml baz.yml
该命令可以一次重新加密多个文件,并提示输入原密码和新密码。要为重新加密的文件设置不同 ID,使用 --new-vault-id。例如,将使用 ppold 文件中的 preprod1 密码加密的文件,改为 preprod2 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
解密加密字符串
若只想检查加密字符串的内容,也可通过标准输入传入它:
echo -e '$ANSIBLE_VAULT;1.1;V2\neyJrZXkiOiAiZ0FBQUFBQm5UYzlPUVgzeUc5NFo3R2pzYVNMSXVsdXA3Z0paMmczNVRtS0NqMUcwMTVx\nSU1JVDlJZlRrSXBkVThmLXhKS00xZGl6X3F3YXZmWWUteGJWaHNZZXZNWl9hMWZvLVRYM3ZUZDRvaHRR\nWkhIdkJmZEZWNlBwVjhNVjJFT05QbDFwandaazAiLCAiY2lwaGVydGV4dCI6ICJnQUFBQUFCblRjOU9u\nWmM2dDh2VEN5c3NTQVlyV0hMclNEOFZfSGd2eEVHdERCdkJfakFpcUpaWWNTV19sR2hPY0VsWEVweS0z\nQ0NBcmJfdUdsUEt0NzJuSmFxVVVmRFIzdz09In0=' | ansible-vault decrypt
还可以使用以下命令提示输入内容,与 encrypt_string 类似,按两次 Ctrl+D 结束输入:
ansible-vault decrypt
Reading ciphertext input from stdin
保护编辑器的步骤
Ansible Vault 依赖已配置的编辑器,而编辑器可能泄露信息。多数编辑器提供防止数据丢失的机制,但这些机制通常依赖额外的明文文件,可能包含秘密的明文副本。请查阅编辑器文档,配置它以避免泄露敏感数据。下面提供常见编辑器的一些建议,并不是完整的编辑器安全指南。
vim
可在命令模式中设置以下选项,避免某些泄露情形。尤其在使用插件时,还可能需要修改其他设置,因此也应查阅 vim 文档。
- 禁用交换文件,避免崩溃或中断时自动保存秘密。
set noswapfile
- 禁用备份文件。
set nobackup
set nowritebackup
- 禁止 viminfo 文件复制当前会话的数据。
set viminfo=
- 禁止复制到系统剪贴板。
set clipboard=
可以将这些设置加入 .vimrc,作用于全部文件,或仅指定路径、扩展名。具体见 vim 手册。
Emacs
可设置以下 Emacs 选项,避免某些泄露情形。尤其在使用插件时,还可能需要修改其他设置,请查阅 Emacs 文档。
- 不将数据复制到系统剪贴板。
(setq x-select-enable-clipboard nil)
- 禁用备份文件。
(setq make-backup-files nil)
- 禁用自动保存文件。
(setq auto-save-default nil)
来源与许可
原文:Encrypting content with Ansible Vault,Ansible 文档及贡献者。官方源文件来自 ansible-documentation,本地附完整源与 COPYING。本文为中文翻译,代码、密文与输出保留原样;源文档内容已与所登记的 latest 页面核对,文中保留该页面的 API 与示例格式。示例秘密均为原文公开示例,命令未在本任务中运行。











暂无评论内容