Как загрузить зашифрованный файл с помощью скрытого хранилища?
Есть ли у кого-нибудь пример дешифрования и загрузки файла с помощью ansible-vault.
Я думаю о том, чтобы мои сертификаты ssl зашифрованы в исходном контроле.
Кажется, что что-то вроде следующего должно работать.
---
- name: upload ssl crt
copy: src=../../vault/encrypted.crt dest=/usr/local/etc/ssl/domain.crt
Ответы
Ответ 1
Это не сработает. То, что вы получите, это ваш encrypted.crt
(с Ansible Vault), загруженный буквально как domain.crt
Что вам нужно сделать, так это сделать вашу игру в разделе "Vault" и добавить переменную, содержащую ваш контент сертификата. Что-то вроде этого:
---
- 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 Laiho
Ответ 2
Существует запрос функции для поддержки этого в модуле копирования. Но до тех пор, пока это не будет реализовано, вот обходной путь (похожий на ответ @dave1010, но повторяющий общие части для полноты):
Создайте файл secrets.yml
, зашифрованный с помощью скрытого хранилища, в котором содержатся ваши секреты, например:
---
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
на удаленном хосте. Но затем повторное воспроизведение пьесы воссоздает его, а не пропускает эту задачу. Поэтому я предпочитаю оставить его там.
UPDATE:
Эта функция реализована в Ansible 2.1.
модуль копирования теперь может прозрачно использовать сводчатый файл в качестве источника, если были сохранены пароли хранилища, которые будут расшифровываться и копироваться на лету.
Ответ 3
Теперь модуль копирования делает это без проблем с Ansible 2.1.x. Просто зашифруйте файл с помощью Ansible Vault, а затем выполните задачу копирования в файле.
(Для справки, здесь функция, которая добавила это: https://github.com/ansible/ansible/pull/15417)
Ответ 4
Я использовал шаблон и 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-----
Ответ 5
Обновление: по состоянию на Апрель 2016 мой Github PR был объединен и доступен в Ansible 2.1 и более поздних версиях. Ниже было промежуточное решение до тех пор, пока PR не был объединен.
Желая сделать то же самое, я создал плагин действий для реализации этой функции. Это доступно через github. Плагин - это плагин с плагином для копирования, который поставляется с возможностью доступа, но с поддержкой дешифрования хранилища.
Вы можете использовать его следующим образом:
- name: Copy Some Secret File
copyv: src="secret.txt" dest="/tmp/"
если secret.txt зашифрован (и предоставляется пароль хранилища), то он будет дешифрован и скопирован.
Ответ 6
Думаю, у вас есть более простой способ сделать это.
Если вы используете ключ сертификата + в одном файле в каком-то формате (например, 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>
Ответ 7
До тех пор, пока модуль "copy" не будет расширен для автоматического дешифрования файлов хранилища, выполните простой способ:
Когда stdout не является tty, ansible-vault view <file>
печатает текст в stdout без вызова пейджера.
В сочетании с поиском "pipe" это поведение можно использовать с файлом паролей хранилища для подачи в "контент" модуля копирования:
- name: "install host key"
copy: content="{{ lookup('pipe', 'ansible-vault view ' + src_key_file) }}"
dest={{ dest_key_file }}
Ответ 8
Вы также можете использовать 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
Ответ 9
+1 для метода copy: content= {{ private_ssl_key }}"
, предложенного выше @utapyngo.
Если вы занимаетесь распределением ключей в роли роли, а не только в учебнике (а почему бы и нет, поскольку распространение ключей - это то, что вам может понадобиться позже), помните следующее:
- Вы получите только один файл для ваших варов, поэтому все ключи (скажем, у вас разные пулы на основе хост-машин или что-то еще) должны собраться вместе в
<role>/vars/main.yml
- Переменные в этом
<role>/vars/main.yml
являются ссылочными без каких-либо путей (это приятно!)
- Помните, что всякий раз, когда вам нужно содержимое переменной, вам нужны кавычки и завитки, т.е.
"{{ your_variable_name }}"
- Если вы хотите скопировать несколько файлов на одну задачу, вам понадобится цикл
with_items:
- Если вы хотите, чтобы ваши конфиденциальные данные вы столкнулись с такими трудностями, чтобы зашифровать в первую очередь с экрана, аккуратный трюк заключается в следующем в ваших ключевых переменных внутри словаря; Таким образом, в вашем цикле
with_items
вы кормите его словарным ключом, а не содержимым самой переменной.