如何从 Ansible Playbook 中正确加密文件?

How to properly encrypt a file from inside an Ansible Playbook?

我目前正在使用 Ansible 剧本从某些网络设备(基本文本文件)提取配置备份,然后将其传输到外部存储。

我想在将配置备份发送到最终存储之前对其进行加密。从 Ansible 剧本任务 内部 加密文件的最适当方法是什么?对我来说,最明显的方法是使用 shell 模块调用外部加密工具(openssl)或 ansible-vault 命令以 ansible 本身可以稍后在其他上下文中读取的格式加密备份;即以下两项任务之一(简化):

  - name: Encrypt stuff with OpenSSL using a password read from vault file
    shell:
      cmd: openssl {{ openssl_parameters }} -k {{ vaulted_encryption_password }} -in {{ file_to_encrypt }} -out {{ encrypted_file }}

  - name: Encrypt stuff with Ansible-Vault
    shell:
      cmd: ansible-vault encrypt {{ file_to_encrypt }} --vault-password-file {{ vault_password_file }}

但是,none 这些解决方案似乎是完全安全的,因为它们需要通过 shell 将加密密码传递给外部工具(这可能会将密码暴露给监控进程的任何人) host this runs in, example) 或要求在文件上写入纯文本密码以供 ansible-vault 使用。

是否有更好的方法在 Ansible 任务中进行文件加密,而我在这里没有找到? (专用模块,还是其他解决方案?)。

据我所知,没有模块可以直接使用剧本中的 ansible-vault(除了明显的预期用途,即动态解密变量和文件内容)。

通过命令提高 ansible-vault 示例安全性(就列表流程而言)的一种可能方法是使用交互式提示模式并使用 expect 填充密码模块。可以通过向任务添加 no_log: true 参数来添加另一个安全层,这样它就不会打印变量的内容。

这是一个简单的例子(你需要在目标主机上pip install pexpect):

 ---
 - hosts: localhost
   gather_facts: false
 
   tasks:
     - name: Vault encrypt a given file
       vars:
         vault_pass: v3rys3cur3
       expect:
         command: ansible-vault encrypt --ask-vault-pass toto.txt
         responses:
           New Vault password: "{{ vault_pass }}"
           Confirm New Vault password: "{{ vault_pass }}"

这给出(使用详细模式来说明 no_log 功能并提供给定文件存在且尚未加密...):

$ ansible-playbook -v test.yml 
No config file found; using defaults

PLAY [localhost] **************************************************************************************************************************************************************************************************

TASK [Vault encrypt a given file] *********************************************************************************************************************************************************************************
changed: [localhost] => {"censored": "the output has been hidden due to the fact that 'no_log: true' was specified for this result", "changed": true}

PLAY RECAP ********************************************************************************************************************************************************************************************************
localhost                  : ok=1    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0