Как расшифровать строку с помощью ansible-vault 2.3.0

Я ждал ansible 2.3, так как он собирался ввести функцию encrypt_string.

К сожалению, я не уверен, как я могу прочитать зашифрованную строку.

Я попробовал decrypt_string, расшифровать (файл), просмотреть (файл), но ничего не работает.

cat test.yml 
---
test: !vault |
     $ANSIBLE_VAULT;1.1;AES256
     37366638363362303836383335623066343562666662386233306537333232396637346463376430
     3664323265333036663736383837326263376637616466610a383430623562633235616531303861
     66313432303063343230613665323930386138613334303839626131373033656463303736366166
     6635346135636437360a313031376566303238303835353364313434363163343066363932346165
     6136

Я получаю сообщение об ошибке ERROR! input is not vault encrypted data for test.yml.

Как я могу расшифровать строку, чтобы знать ее значение без необходимости запускать воспроизведение?


person MMT    schedule 18.04.2017    source источник
comment
Вы можете извлечь зашифрованную часть и передать ее на стандартный ввод ansible-vault decrypt, но я думаю, что играть все равно будет проще.   -  person techraf    schedule 18.04.2017
comment
Проголосуйте за github.com/ansible/ansible/issues/26190, чтобы разрешить ansible-vault decrypt обрабатывать встроенные зашифрованные переменные.   -  person Shane    schedule 27.09.2017


Ответы (14)


Вы пытались установить зашифрованную строку как переменную, а затем использовать -debug для получения ее расшифрованного вывода?

i.e.

Определите свою зашифрованную строку как переменную test в своей книге, а затем выполните:

-debug: msg="My Secret value is {{test | replace('\n', '')}}"

в вашем playbook, а затем запустите playbook:

$ ansible-playbook -i localhost YourPlaybook.yml --vault-password-file path/to/your/secret_key_file
person NAF    schedule 18.04.2017
comment
Я придумал аналогичное решение, т.е. tasks: name: "{{ test_var }}", однако я надеялся на что-то большее, чем с параметрами строки шифрования / дешифрования eyaml. - person MMT; 18.04.2017

Вы также можете использовать простую команду ansible для соответствующей комбинации хоста / группы / инвентаря, например:

$ ansible my_server -m debug -a 'var=my_secret'
my_server | SUCCESS => {
    "my_secret": "373861663362363036363361663037373661353137303762"
}
person famousgarkin    schedule 26.07.2017
comment
Еще проще просто использовать localhost вместо my_server. - person Welsh; 02.10.2017
comment
@Welsh может быть, зависит от настройки вашей группы / хоста. - person famousgarkin; 02.10.2017
comment
В принципе, это самый простой вариант. Это позволяет избежать необходимости копировать текст из файла hosts / vars, обрезать пробелы и вставлять его в терминал. К сожалению, для меня это привело к FAILED! => {"msg": "Attempting to decrypt but no vault secrets found"}. Возможно, это связано с тем, что переменная, которую я хочу расшифровать, была определена для группы, а не для конкретного хоста? - person ; 17.02.2018
comment
@sampablokuper Это сообщение об ошибке означает, что ansible не может найти пароли для дешифрования. Вам необходимо указать путь к файлу паролей или использовать флаг --ask-vault-pass, чтобы эта командная строка запрашивала у вас пароль. - person Omn; 13.06.2018
comment
Если ваша зашифрованная переменная находится в файле vars, вы можете добавить параметр -e '@path/to/vars/file' в свою команду ansible для последней команды: ansible localhost -e '@vars/file' --ask-vault-pass -m debug -a 'var=my_secret' - person wfaulk; 15.04.2020

Вы можете направить вход, затем указать ansible-vault на вывод в stderr, а затем перенаправить stdout на /dev/null, поскольку инструмент печатает Decryption successful.

Часть /dev/stdin/ может не понадобиться в новых версиях Ansible.

Что-то типа:

echo 'YOUR_SECRET_VALUE' | ansible-vault decrypt /dev/stdin --output=/dev/stderr > /dev/null

Вот пример:

echo '$ANSIBLE_VAULT;1.1;AES256
30636561663762383436386639353737363431353033326634623639666132623738643764366530
6332363635613832396361333634303135663735356134350a383265333537383739353864663136
30393363653361373738656361613435626237643633383261663138653466393332333036353737
3335396631613239380a616531626235346361333737353831376633633264326566623339663463
6235' | ansible-vault decrypt /dev/stdin --output=/dev/stderr > /dev/null

Я надеюсь, что они реализуют более простой способ сделать это.

Изменить: переменные среды в качестве входных данных:

Чтобы добиться аналогичного поведения с многострочными переменными среды на bash, используйте printf вместо echo

Пример (пароль: 123):

export chiphertext='$ANSIBLE_VAULT;1.1;AES256
65333363656231663530393762613031336662613262326666386233643763636339366235626334
3236636366366131383962323463633861653061346538360a386566363337383133613761313566
31623761656437393862643936373564313565663633636366396231653131386364336534626338
3430343561626237660a333562616537623035396539343634656439356439616439376630396438
3730'

printf "%s\n" $chiphertext | ansible-vault decrypt /dev/stdin --output=/dev/stderr > /dev/null
person Scudelletti    schedule 29.06.2017
comment
По какой-то причине echo "$ciphertext" | ansible-vault decrypt /dev/stdin у меня не работает. Я продолжал получать ERROR! [Errno 2] No such file or directory: u'/proc/22899/fd/pipe:[39394403]'. Мне пришлось передать $ciphertext во временный файл вместо использования /dev/stdin. - person Dave Parrish; 04.07.2017
comment
@DaveParrish вы должны использовать одинарные кавычки в эхо. Поскольку оболочка считает $ANSIBLE_VAULT переменной среды, но это не так. Пример: export AAA=Wow Затем запустить echo "$AAA" вернет Wow. echo '$AAA' вернет $AAA - person Scudelletti; 04.07.2017
comment
у вас есть решение для использования переменной bash, которая тогда содержит зашифрованный текст? echo '$chiphertext' | ansible-vault decrypt /dev/stdin будет работать? - person Dave Parrish; 05.07.2017
comment
@DaveParrish Я думал, что $ciphertext был заполнителем, своего рода абстракцией, а не переменной env. Простите за это. Я заметил, что получаю другой результат, так как использую zsh. Вы можете попробовать использовать printf вместо echo, добавляя новую строку в конце каждой строки. Команда будет похожа на printf "%s\n" $chiphertext | ansible-vault decrypt /dev/stdin --output=/dev/stderr > /dev/null. Я обновил ответ этой информацией. - person Scudelletti; 06.07.2017
comment
printf у меня тоже не работает. Я действительно не уверен, почему, но использование временного файла для меня является приемлемым решением. - person Dave Parrish; 06.07.2017
comment
comment
(N.B. В моем комментарии выше я использую $ciphertext в качестве заполнителя, а не не в качестве переменной Bash. Я считаю, что это отличается от того, как @DaveParrish использовал его выше. Извините, если это кого-то смущает!) - person ; 17.02.2018
comment
Сработало у меня, когда достал /dev/stdin. Последние версии, вероятно, определяют, получает ли он стандартный ввод, так что он нужен. - person Andrey Kaipov; 14.08.2020

поскольку целые файлы хранилища плохо сочетаются с историями git, можно использовать строки хранилища в файлах переменных, а также упрощает поиск переменных по имени.

Вот простой рабочий пример:

Я хочу поместить fredsSecretString: value в vars.yml (его значение - fastfredfedfourfrankfurters, но тише, не давайте людям знать !!)

$ ansible-vault encrypt_string 'fastfredfedfourfrankfurters' -n fredsSecretString >> vars.yml
New Vault password: fred
Confirm New Vault password: fred
$ cat vars.yml
fredsSecretString: !vault |
          $ANSIBLE_VAULT;1.1;AES256
          36643662303931336362356361373334663632343139383832626130636237333134373034326565
          3736626632306265393565653338356138626433333339310a323832663233316666353764373733
          30613239313731653932323536303537623362653464376365383963373366336335656635666637
          3238313530643164320a336337303734303930303163326235623834383337343363326461653162
          33353861663464313866353330376566346636303334353732383564633263373862

Чтобы расшифровать значение, верните зашифрованную строку обратно в ansible-vault следующим образом:

    $ echo '$ANSIBLE_VAULT;1.1;AES256
    36643662303931336362356361373334663632343139383832626130636237333134373034326565
    3736626632306265393565653338356138626433333339310a323832663233316666353764373733
    30613239313731653932323536303537623362653464376365383963373366336335656635666637
    3238313530643164320a336337303734303930303163326235623834383337343363326461653162
    33353861663464313866353330376566346636303334353732383564633263373862' |
 ansible-vault decrypt && echo
    Vault password: fred
    Decryption successful
    fastfredfedfourfrankfurters
    $
person Coleman Corrigan    schedule 14.07.2017
comment
Фантастика! Спасибо, что показали нам это. Для всех, кто пытается это сделать, обратите внимание, что для того, чтобы это сработало, вам необходимо удалить пробелы из строки ANSIBLE_VAULT. Это то, что @ coleman-corrigan показывает выше, но я пропустил первую пару попыток. - person Robert J; 19.01.2018
comment
Пришлось заменить новую строку литералом (\ n) и включить интерпретацию escape-последовательностей # echo -e '$ANSIBLE_VAULT;1.1;AES256\n34626638366161336437303439643066366466376431346336613332336433386539303737613663\n6639393965653239356435613038303030616163333565300a313932616365383336323839363935\n66363439666461323466343366343737373834353333363935346132356663346365386163323733\n3332316134323064310a386164373661323233333862643231303034663632363061383433616166\n62653564653035316165666363656461386632333738666663323664303963393437' | ansible-vault decrypt && echo Vault password: Decryption successful - person KVS; 30.08.2018
comment
Для расшифровки я добавил tr -d ' ', чтобы удалить пробелы, чтобы я мог скопировать секрет прямо из исходного кода без необходимости сначала манипулировать им. например echo '$ANSIBLE_VAULT;1.1;AES256 366436623039313363623563613733346636323431393838326261306...' | tr -d ' ' | ansible-vault decrypt && echo - person Joy Peterson; 13.12.2018
comment
Все это очень полезно, но я не могу поверить, насколько это больно ... - person user2490003; 26.09.2019
comment
У меня была проблема с пробелами в новых строках - вы должны удалить их для успешного выполнения - в противном случае вы получите сообщение об ошибке: valt format unhexlify error: on-hexadecimal digit found for - person fty4; 15.01.2020

Вот еще один способ расшифровать строки

$ ansible localhost \
       -m debug \
       -a "var=mysecret" \
       -e "@inventory/group_vars/master"
localhost | SUCCESS => {
"mysecret": "somesecret\n"
}

Уловка здесь в том, что мы передаем файл с секретным хранилищем Ansible mysecret внутри него ansible, и он может его расшифровать.

ПРИМЕЧАНИЕ. Если у вас нет пароля для расшифровки зашифрованного секретного хранилища Ansible, вы также можете передать его:

$ ansible localhost --vault-password-file=~/.vault_pass.txt \
       -m debug \
       -a "var=mysecret" \
       -e "@inventory/group_vars/master"
localhost | SUCCESS => {
"mysecret": "somesecret\n"
}
person Felicia Lyn-Shue    schedule 23.09.2019
comment
Я добавил --ask-vault-pass к вашему первому примеру. - person Alexey Vazhnov; 04.10.2019

yq извлекает зашифрованное значение var, затем создает временный файл и использует его с ansible-vault:

cat ansible_file.yml | yq -r ".variable_name" > tmp_file.txt

# you can also use 'ansible-vault decrypt'
ansible-vault view --ask-vault-pass tmp_file.txt
person alfredocambera    schedule 26.03.2019
comment
Мне нравится твой ответ. Это очень просто и полезно. У меня есть пара вещей, о которых нужно сообщить. При установке через brew в OS X инструмент yq не использует -r, а просто r для чтения по определенному пути. Кроме того, нет необходимости в cat & pipe, у него есть возможность читать прямо из файла. И, наконец, мы можем напрямую расшифровать его, не используя временный файл. - person maricn; 25.06.2019
comment
Мое предложение было бы: yq -t r group_vars/staging.yml "app.super_secret_key" | ansible-vault decrypt --vault-password-file .vault_pass_staging - person maricn; 25.06.2019
comment
Спасибо не знал этого - person alfredocambera; 25.06.2019

Вот то, что работает для меня, аналогично тому, что делает Скуделлетти, но передает проход в хранилище, т.е.

echo '$ANSIBLE_VAULT;1.1;AES256
31363861346536343331393539323936346464386534346337306565626466393764666366363637
6533373165656431393662653463646430663933363431380a336130363131373238326330393931
39343533396161323834613030383339653633393133393932613562396630303530393030396335
3630656237663038630a363032373633363161633464653431386237333262343231313830363965
31393930343532323133386536376637373463396534623631633234393565373337613530643031
38393862616635326339373731353465303364303365336132613566396666626536636533303839
393465653830393231636638643735313666' | ansible-vault decrypt --vault-password-file /path/to/your/.vault_pass.txt /dev/stdin --output=/dev/stderr > /dev/null && echo

Для удобства вывод будет в отдельной строке, благодаря завершающему && echo. Разрешение моего прохода в хранилище - 644, если вы столкнетесь с какими-либо ошибками с разрешениями.

Надеюсь, поможет!

person radtek    schedule 21.11.2018
comment
Я просто получаю ERROR! [Errno 2] No such file or directory: u'/proc/8952/fd/pipe:[18950245]' - person Yngvar Kristiansen; 22.05.2019
comment
Какая версия ансибла? Возможно, это устарело, я могу попробовать с той версией, которая у вас есть. - person radtek; 16.06.2021

Несмотря на то, что нет проблем с отображением зашифрованных строковых значений с помощью доступных отладочных сообщений или использования ansible cli, есть еще одно решение, которое может быть удобным для нужд автоматизации. Вы можете использовать библиотеки python из ansible и использовать их в своем коде (в основном, все это находится в ansible.parsing. *)

1) Укажите пароль хранилища и создайте «хранилище» с секретами.

# Load vault password and prepare secrets for decryption
loader = DataLoader()
secret = vault.get_file_vault_secret(filename=vault_password_file, loader=loader)
secret.load()
vault_secrets = [('default', secret)]
_vault = vault.VaultLib(vault_secrets)

2) Загрузите файл yaml с помощью AnsibleLoader:

with codecs.open(input_file, 'r', encoding='utf-8') as f:
    loaded_yaml = AnsibleLoader(f, vault_secrets=_vault.secrets).get_single_data()

3) Если вам нужно зашифровать новую строку и обновить словарь:

    new_encrypted_value = objects.AnsibleVaultEncryptedUnicode.from_plaintext(source_system_password, _vault, vault_secrets[0][1])
    loaded_yaml[target_env]['credentials'][external_system_name]['password'] = new_encrypted_variable

4) После завершения обработки напишите ответ с помощью AnsibleDumper:

with open('new_variables.yml','w') as fd:
    yaml.dump(loaded_yaml, fd, Dumper=AnsibleDumper, encoding=None, default_flow_style=False)
person andruhan    schedule 21.02.2018
comment
не могли бы вы включить соответствующие imports. Я пытаюсь написать сценарий для расшифровки / шифрования отдельных варов из файлов доступных варов. Я разбирал файлы с помощью yq, но этот подход кажется лучше. - person alfredocambera; 02.04.2019

Эта одна команда извлекает только зашифрованные данные и передает их для дешифрования. Мне это нравится немного больше, так как вам не нужно вручную извлекать данные.

$ grep -v vault test.yml | awk '{$1=$1;print}' | ansible-vault decrypt
person Scott Carlson    schedule 01.02.2019
comment
Я просто получаю ERROR! input is not vault encrypted data- is not a vault encrypted file for - - person Yngvar Kristiansen; 22.05.2019

Для тех, кто хочет определить псевдоним и забыть о каналах и временных файлах, вот решение, которое вы можете принять:

function decrypt_ansible_vault_string() { 
   export FN=$1
   export KEY=$2
   ansible-vault view <(yq r $FN $KEY)
   }

Пример использования:

$ head myrole/var/main.yml
# Variables here override defaults
website:
  server: 127.0.0.1
  port: 8081
  session:
    hash_key: !vault |
          $ANSIBLE_VAULT;1.1;AES256
          33626439623630633332343836316334376637323738323061373334373733326566613262373036
          6632623432373263613139646432333331313731326232390a653031366564313235323065303865
          32383563393261326633306663663437386134666230373332646234656464356331646335636564

$ decrypt_ansible_vault_string myrole/vars/main.yml website.session.hash_key

Этот ответ расширяет комментарий от @maricn. Обратите внимание, я использую this yq, но подойдет любой инструмент запросов yaml. Здесь важен принцип использования подоболочки (без временных файлов). Также обратите внимание, вы можете добавить --ask-vault-password. Однако использование секрета, зашифрованного с помощью GPG, намного удобнее, поскольку вам не нужно каждый раз вводить пароль, и этот рабочий процесс намного лучше для команд (YMVV и IHMO). Вот хорошее руководство по использованию GPG с ansible-vault.

Вставьте это в свой .bashrc и наслаждайтесь.

Обновить

Меня разочаровал ansible-vault encrypt\decrypt рабочий процесс. Итак, я создал оболочку для расшифровки строк в файлах var. Проверьте это: https://github.com/oz123/ansible-vault-string-helper

person oz123    schedule 20.11.2020

Вот как я шифрую и дешифрую строки прямо на ходу, дополнительно для использования в качестве переменных среды.

yq особенно полезен здесь для интерпретации ввода yaml.

В одной строке, если бы я должен был протестировать шифрование и дешифрование строки, я бы сделал следующее:

echo -n "test some input that will be encrypted and decrypted" | ansible-vault encrypt_string --vault-id $vault_key --stdin-name testvar_name | yq r - "testvar_name" | ansible-vault decrypt --vault-id $vault_key

Я предполагаю, что обычно интересующиеся этим заинтересованы в расшифровке переменных окружения. Вот как я реализую этот вариант использования, где testvar - это зашифрованная переменная среды, а $ vault-id - это путь к ключу, который вы используете для шифрования / дешифрования.

testvar=$(echo -n "test some input that will be encrypted and stored as an env var" | ansible-vault encrypt_string --vault-id $vault_key --stdin-name testvar_name | base64 -w 0)
result=$(echo $testvar | base64 -d | /var/lib/snapd/snap/bin/yq r - "testvar_name" | ansible-vault decrypt --vault-id $vault_key); echo $result
person openCivilisation    schedule 01.03.2020

Для файла типа test.yml:

---
test: !vault |
     $ANSIBLE_VAULT;1.1;AES256
     37366638363362303836383335623066343562666662386233306537333232396637346463376430
     3664323265333036663736383837326263376637616466610a383430623562633235616531303861
     66313432303063343230613665323930386138613334303839626131373033656463303736366166
     6635346135636437360a313031376566303238303835353364313434363163343066363932346165
     6136

следующая грубая реализация (рекомендуется только для некоторых быстрых ручных действий, очевидно):

for row in $(cat test.yml | yq -c '.[]'); do
    decrypt() {
     printf "decrypting '%s'" $row | sed -e 's/^"//' -e 's/"$//'
     echo "---"
     printf $row | sed -e 's/^"//' -e 's/"$//' | ansible-vault decrypt -
    }
   echo -e "==\n: $(decrypt '.')"
done

должен работать, при условии, что у вас есть ключ для шифрования данных.

person Stanislav    schedule 01.03.2020

Обращаясь к этому вопросу и ответам здесь, я просто хотел бы добавить быстрый сценарий bash, который я приготовил вместе, который читает весь файл yaml в поисках строк, которые можно расшифровать, выгружая на экран.

Это далеко не идеально, и я не самый лучший в bash, но надеюсь, что это поможет кому-то, кто был в той же ситуации, что и я, желая сделать общий дамп.

Чтобы использовать следующий сценарий, необходимо иметь пароль хранилища в файле (текущий рабочий путь) с именем vault_pass вместе с установленным yq and jq. Файл для анализа должен быть первым аргументом. например ./vault_reader.sh group_vars/production.yml

#!/bin/bash
KEY_OR_VALUE=key
for row in $(yq read -j $1 | jq); do  
    if [ "$KEY_OR_VALUE" == "key" ]
    then
        KEY_OR_VALUE="value"
        echo $(sed -e "s/\"//g" -e "s/\://g" <<<$row)
    else
        KEY_OR_VALUE="key"
        ENC_VALUE=$(sed -e "s/\"//g" -e "s/\://g" -e"s/\,//g"<<<$row)
        if [[ $ENC_VALUE = '$ANSIBLE_VAULT'* ]]; then
            echo -e "$ENC_VALUE" | ansible-vault decrypt --vault-password-file vault_pass
        fi
        echo ""
    fi
done
person Simon    schedule 23.09.2020
comment
Это работает только с yq v2.x, который уже устарел. - person Altus; 05.07.2021

Вы можете сделать это с помощью однострочника

ansible localhost -m debug -a var='NAME_OF_ENCRYPTED_VAR' -e "@PATH_TO_FILE_WITH_VARIABLE" --vault-id yourid@/path/to/file

или введите пароль из командной строки

ansible localhost -m debug -a var='NAME_OF_ENCRYPTED_VAR' -e "@PATH_TO_FILE_WITH_VARIABLE" --ask-vault-pass
person Evren Yurtesen    schedule 09.03.2021