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

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

我想在将配置备份发送到最终存储之前对其进行加密。从 inside Ansible playbook 任务中加密文件的最充分方法是什么?对我来说,显而易见的方法是使用 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 }}

然而,这些解决方案似乎都不是完全安全的,因为它们需要通过 shell 将加密密码传递给外部工具(例如,这可以将密码暴露给任何监视主机上运行的进程的人)或需要编写明文-text 文件上的密码供 ansible-vault 使用。

有没有更好的方法在我在这里遗漏的 Ansible 任务中进行文件加密? (专用模块或其他解决方案?)。

stack overflow How do I properly encrypt a file from inside an Ansible Playbook?
原文答案
author avatar

接受的答案

我知道没有模块可以直接使用 playbook 中的 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

答案: