42

有没有人有使用ansible-vault解密和上传文件的示例。

我正在考虑在源代码控制中加密我的 ssl 证书。

看起来像下面这样的东西应该可以工作。

---
  - name: upload ssl crt
    copy: src=../../vault/encrypted.crt dest=/usr/local/etc/ssl/domain.crt
4

10 回答 10

52

从 Ansible 2.1.x 开始,复制模块现在可以无缝执行此操作。只需使用 Ansible Vault 加密您的文件,然后对文件发出复制任务。

(作为参考,这是添加此功能的功能:https ://github.com/ansible/ansible/pull/15417 )

于 2016-05-27T15:35:01.290 回答
36

更新:自 2016 年起已弃用,Ansible 2.1

在之前的任何 Ansible 版本上2.1

那是行不通的。您将得到的是您的encrypted.crt(使用 Ansible Vault)按字面意思上传domain.crt

您需要做的是让您的剧本成为“保险库”的一部分,并添加一个包含您的证书内容的变量。像这样的东西:

---
- name: My cool playbook
  hosts: all

  vars:
    mycert: |
       aasfasdfasfas
       sdafasdfasdfasdfsa
       asfasfasfddasfasdfa


  tasks:
    # Apparently this causes new lines on newer ansible versions
    # - name: Put uncrypted cert in a file
    #   shell: echo '{{ mycert }}' > mydecrypted.pem

    # You can try this as per
    # https://github.com/ansible/ansible/issues/9172
    - copy:
      content: "{{ mycert }}"
      dest: /mydecrypted.pem

    - name: Upload Cert
      copy: src=/home/ubuntu/mydecrypted.pem dest=/home/ubuntu/mydecrypteddest.pem

    - name: Delete decrypted cert
      file: path=/home/ubuntu/mydecrypted.pem state=absent

您也可以选择mycert使用 Ansible Vault 将变量放在单独的变量文件中。

复制模块已在 Ansible 2.1 中更新。来自变更日志:“复制模块现在可以透明地使用保管库文件作为源,如果提供保管库密码,它将即时解密和复制。” 在这里注意它,因为有些人不可避免地不会忽略已接受的答案。– JK 莱霍

于 2014-04-01T01:12:50.030 回答
21

复制模块中有一个功能请求以本机支持此功能。但在实现之前,这里是解决方法(类似于@dave1010 的答案,但为了完整性重复公共部分):

创建一个secrets.yml使用 ansible Vault 加密的文件,其中包含您的秘密,例如:

---
private_ssl_key: |
  -----BEGIN PRIVATE KEY-----
  abcabcabcabcabcabcabcabcabc
  -----END PRIVATE KEY-----

private_crt: |
  -----BEGIN CERTIFICATE-----
  abcabcabcabcabcabcabcabcabc
  -----END CERTIFICATE-----

在你的剧本中,包括它:

vars_files:
  - secrets.yml

然后您可以在任务中使用变量:

- name: Copy private kay
  copy: content="{{ private_ssl_key }}" dest=/some/path/ssl.key

但是,如果您尝试复制的文件是二进制文件,这将不起作用。在这种情况下,您需要首先使用 base64 对内容进行编码:

cat your_secret_file | /usr/bin/base64

然后将base64编码值放入您的secrets.yml文件中,例如:


crt_b64: |
  ndQbmFQSmxrK2IwOFZnZHNJa0sKICAxdDhFRUdmVzhMM...

然后您可以分两步创建远程文件:

- name: Copy certificate (base64 encoded)
  copy: content="{{ crt_b64 }}" dest=/some/path/cert.b64

- name: Decode certificate
  shell: "base64 -d /some/path/cert.b64 > /some/path/cert.txt"
  args:
    creates: /some/path/cert.txt

请注意,您可以删除cert.b64远程主机上的临时文件。但随后重新运行 playbook 将重新创建它,而不是跳过此任务。所以,我宁愿把它留在那里。

更新:此功能已在Ansible 2.1中实现。

复制模块现在可以透明地使用保管库文件作为源,如果提供保管库密码,它将即时解密和复制。

于 2015-06-24T23:52:32.607 回答
15

我使用了一个模板和一个vars_file来做到这一点:

在您的顶级剧本中:

vars_files:
  - secretvars.yml

在一个任务中:

- name: Private ssl key
  template: src=etc-ssl-private-site.key dest=/etc/ssl/private/site.key

在模板 ( etc-ssl-private-site.key) 中,您需要的只是变量:

{{ private_ssl_key }}

在加密中secretvars.yml(用 加密ansible-vault):

---

private_ssl_key: |
  -----BEGIN PRIVATE KEY-----
  abcabcabcabcabcabcabcabcabc
  -----END PRIVATE KEY-----
于 2014-04-08T14:57:18.437 回答
14

更新:截至2016 年 4 月,我的Github PR已合并,可在 Ansible 2.1 及更高版本中使用。以下是 PR 合并之前的临时解决方案。

想做同样的事情,我创建了一个动作插件来实现该功能。这可以通过github获得。该插件正是 ansible 附带的复制操作插件,但支持 vault 解密。

你可以像这样使用它:

- name: Copy Some Secret File
  copyv: src="secret.txt" dest="/tmp/"

如果 secret.txt 被加密(并且提供了保管库密码),那么它将被解密和复制。

于 2015-07-03T08:40:38.613 回答
12

我认为,你有一个更简单的方法来做到这一点。

如果您以某种格式(如 pkcs12 或只是连接)在一个文件中使用证书+密钥,则可以使用通用openssl(或gpg,或其他)加密。它看起来像这样:

openssl enc -e -aes-256-ctr -in original.pem -out encrypted.aes -k <pass-vault>

之后,您可以将 encrypted.aes 复制到远程主机并就地解密:

- name: copy encrypted cert and key
  copy: src=encrypted.aes dest=/root/ansible-files/ mode=0600

- name: decrypt cert and key
  command: openssl enc -aes-256-ctr -d -in /root/ansible-files/encrypted.aes -out <dest> -k {{ pass-vault }}

如果您有 pem 或 der 格式的单独密钥文件,您可以使用

openssl rsa -in original.pem -out encrypted.pem -aes256 -passout pass:<pass-vault>
于 2014-04-12T01:15:14.587 回答
11

Ansible 2.5 将参数添加decryptcopy模块中。

例如,如果您使用以下方式加密文件:

$ ansible-vault encrypt vault/encrypted.crt

现在您可以使用复制 +解密

---
  - name: upload ssl crt
    copy:
      src: path/to/encrypted-with-vault.crt
      dest: /usr/local/etc/ssl/domain.crt
      decrypt: yes
      mode: 0600
于 2018-07-11T06:07:10.690 回答
4

在“复制”模块被扩展为自动解密保管库文件之前,这里有一个简单的解决方法:

当 stdout 不是 tty 时,ansible-vault view <file>将明文打印到 stdout 而不调用寻呼机。

结合“管道”查找,此行为可以与保险库密码文件一起使用,以输入复制模块的“内容”选项:

- name: "install host key"
  copy: content="{{ lookup('pipe', 'ansible-vault view ' + src_key_file) }}"
        dest={{ dest_key_file }}
于 2015-08-28T21:57:10.703 回答
2

作为剧本的一部分,您还可以使用 local_action 临时解密您的文件:

- name: "temporairly decrypt the twpol.enc"
  sudo: False
  local_action: shell ansible-vault view --vault-password-file {{ lookup('env', 'ANSIBLE_VAULT_PASS_FILE') }} ./roles/copykey/files/key.enc > ./roles/copykey/files/key.txt 

- name: "copy the key to the target machine."
  copy: src=key.txt dest=/tmp

- name: "remove decrypted key.txt file"
  sudo: False
  local_action: rm ./roles/copykey/files/key.txt
于 2016-04-07T20:41:46.050 回答
-1

+1 为copy: content= {{ private_ssl_key }}"上面@utapyngo 建议的方法。

如果您将密钥分发作为一个角色进行,而不仅仅是在剧本中(为什么不这样做,因为您以后可能会再次需要密钥分发),请记住以下几点:

  • 您只能为您的 vars 获取一个文件,因此所有密钥(例如,您有基于主机或其他的不同捆绑包)必须放在一起<role>/vars/main.yml
  • 这里的变量<role>/vars/main.yml是可引用的,没有任何路径(这很好!)
  • 请记住,无论何时您想要变量的内容,都需要引号和花括号,即"{{ your_variable_name }}"
  • 如果要为每个任务复制多个文件,则需要with_items:循环
  • 如果您想将一开始加密时遇到很多麻烦的敏感数据保留在屏幕之外,一个巧妙的技巧是将您的关键变量放在字典中;这样,在您的with_items循环中,您将向其提供字典键而不是变量本身的内容。
于 2015-02-12T21:03:32.573 回答