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

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

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

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

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

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

23 ответа

Решение

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

т.е.

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

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

в вашей книге, а затем запустите книгу:

ansible-playbook -i localhost YourPlaybook.yml --vault-password-file path/to/your/secret_key_file

`

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

$ ansible my_server -m debug -a 'var=my_secret'
my_server | SUCCESS => {
    "my_secret": "373861663362363036363361663037373661353137303762"
}

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

Что-то вроде:

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

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

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

Я хочу поместить fredsSecretString: значение в 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-хранилище следующим образом:

    $ echo '$ANSIBLE_VAULT;1.1;AES256
    36643662303931336362356361373334663632343139383832626130636237333134373034326565
    3736626632306265393565653338356138626433333339310a323832663233316666353764373733
    30613239313731653932323536303537623362653464376365383963373366336335656635666637
    3238313530643164320a336337303734303930303163326235623834383337343363326461653162
    33353861663464313866353330376566346636303334353732383564633263373862' |
 ansible-vault decrypt && echo
    Vault password: fred
    Decryption successful
    fastfredfedfourfrankfurters
    $

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

$ 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"
}

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

You can do it with a one-liner

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

or enter the password from command line

      ansible localhost -m debug -a var='NAME_OF_ENCRYPTED_VAR' -e "@PATH_TO_FILE_WITH_VARIABLE" --ask-vault-pass

С помощью этого вы можете расшифровать файл, содержащий только строку доступного хранилища:

      cat encrypted_vault_string | ansible-vault decrypt

выход:

      Vault passsword: <enter password, is not echoed to you>
Decryption successful
< decrypted string here>

Строка ansible Vault выглядит так:

      $ANSIBE_VAULT;1.1;AES256
123456789...
123456789...
123456789...
1234

Это также работает без промежуточного файла

      echo -e '$ANSIBLE_VAULT;1.1;AES256\n123456789...789' | ansible-vault decrypt

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

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, если вы столкнетесь с какими-либо ошибками разрешения.

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

You can copy the encrypted string to a file but you need to only copy the encrypted part and not the other yml parts.

So you file need to change from:

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

to:

      $ANSIBLE_VAULT;1.1;AES256
37366638363362303836383335623066343562666662386233306537333232396637346463376430
3664323265333036663736383837326263376637616466610a383430623562633235616531303861
66313432303063343230613665323930386138613334303839626131373033656463303736366166
6635346135636437360a313031376566303238303835353364313434363163343066363932346136

And you'll be able to decript or view with

ansible-vault decrypt --vault-password-file <path to passwordfile> test.yml

ansible-vault view --vault-password-file <path to passwordfile> test.yml

And perhaps drop the .yml because that doesn't make sense anymore.

Хотя нет проблем с отображением зашифрованных строковых значений в ANSIBLE отладочных сообщениях или использованием 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)

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

cat test.yml | grep -v vault| awk '{$1=$1;print}' | ansible-vault decrypt

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

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. Примечание. Я использую этот 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

Попытка расшифровать /dev/stdin, как в ansible-vault decrypt /dev/stdin, или используя --vault-password-file=/dev/stdin, как упоминают другие комментаторы, также не работает для меня с такими ошибками, как ERROR! [Errno 2] No such file or directory: '/proc/100/fd/pipe:[12930445]'.

Однако, --vault-password-fileтакже требует исполняемый файл для создания пароля на стандартный вывод, так что вы можете использовать /bin/catввести пароль:

echo password | ansible-vault decrypt --output - --vault-password-file=/bin/cat ./encrypted_vault_file

Я знаю, что это было давно, но это сработало для меня, когда я пропустил это через ansible-vault decryptбез всего остального, вот так:

      $ echo '$ANSIBLE_VAULT;1.1;AES256
38613538323065373061616466616334306237336461333935393261646131616232643238626635
3336633631366539383039343437306664336165326565650a353233303431613362653838643135
34363763366134393366356339343039313035366164636133326639376334313335316565373330
3435633463313334310a653239313039323135363865313933626464663363656164343662303763
34616663626530656630633839346531653862633332396365396432366234333861' | ansible-vault decrypt
Decryption successful
super-secret-string$ 

На всякий случай, если кому интересно. у меня анзибл версия 2.9.26

Самый удобный способ сделать это — просто добавить функцию в ваш или, imo.

      vdecr() {
  unset IFS
  if [[ -n "$1" ]]; then
    if [[ -f "$1" ]]; then
      if [[ $(head -n1 "$1") == "\$ANSIBLE_VAULT;1.1;AES256" ]]; then
        cat "$1" | ansible-vault decrypt 2> /dev/null
        return 0
      fi
      printf 'Reading vault values from file...\n\n'
      IFS="#"
      for v in `grep "\!vault |" -A6 "$1" | sed 's/^--$/#/g' | sed -r 's/^(.*:)/#\n\1/g'`;do
        if [[ "$v" != "" ]]; then
          printf "$v" | grep -o "^.*: " | xargs && printf '  ' && vdecr "$v";
        fi ;
      done
      unset IFS
      return 0
    fi
    local str="$1"
  elif [[ ! -t 0 ]]; then
    local str=$(cat)
  else
    printf 'Interactive mode. Paste encrypted string and press Ctrl-D two times to confirm.\n'
    local str=$(cat)
    printf '\n'
  fi
  printf -- "$str" | sed 's/ /\n/g' | \
  sed '/---\|^.*:\|\!vault\||\|^$/d' | \
  ansible-vault decrypt 2> /dev/null | \
  tail -n1
  printf '\n'
}

Он работает в bash и zsh без каких-либо дополнительных пакетов, кроме самого ansible-vault. Эта функция может принимать входные данные в качестве аргумента со стандартного ввода, в интерактивном режиме или из файла. Он может работать со многими зашифрованными строками в файле. Т.е. если вы передадите ему файл групповых переменных, он проанализирует и расшифрует из него все значения хранилища. Функция проверяет, является ли файл полностью зашифрованным в хранилище, и печатает его расшифрованное содержимое.

  • Для начала проверим, имеем ли мы дело с аргументом, файлом или STDIN не терминал - сделаем его универсальным :-)
    if [[ -n "$1" ]],if [[ -f "$1" ]],[[ ! -t 0 ]]
  • Если аргументом является файл, проверьте, полностью ли он зашифрован или нет.$(head -n1 "$1") == "\$ANSIBLE_VAULT;1.1;AES256". Если он полностью зашифрован, просто сохраните файл cat в формате . Если нет - прочитайте из него значения хранилищаgrep "\!vault |" -A6 "$1"и подавать в vdecr один за другим. grep использует--в качестве разделителя, и он может разбивать переменные с подобными именами при синтаксическом анализе, поскольку длина IFS составляет всего один символ. Итак, сед^--$к#и укажите новый IFS. Если переменные хранилища идут одна за другой без пробела между ними, grep не будет печатать разделитель, поэтому добавьте строку с разделителем между ними.sed -r 's/^(.*:)/#\n\1/g'.xargsпросто обрезает пробелы.
  • $(cat)просто читает стандартный ввод
  • Присвойте значение нашей переменной и начните анализ
  • Замените все пробелы на символы новой строки, так как символы новой строки могут сжиматься при передаче в качестве аргумента, а они нужны хранилищу.
    sed 's/ /\n/g'
  • Затем удалите!vault,|,---, пустые строки и имя переменной (все, что находится между началом строки и двоеточием)
    sed '/---\|^.*:\|\!vault\||\|^$/d'
  • Наконец передайте этоansible-vault decrypt, перенаправляя все ошибки и предупреждения в/dev/nullи возьмем только последнюю строку вывода, которая будет содержать незашифрованный текст.
    ansible-vault decrypt 2> /dev/null | tail -n 1

А затем добавьте его в свой~/.bashrcили~/.zshrc, создайте его и используйте по своему усмотрению:

      cat test.yml | vdecr
vdecr test.yml
vdecr path/to/group/vars.yml
vdecr path/to/encrypted/file
vdecr '!vault |
          $ANSIBLE_VAULT;1.1;AES256
          35346165343065373135616164383132636533366436623739373739613862376563653838313839
          3365393739626664336162353836643333323931626530310a343566643261363532316364383933
          36313462303031626139623666353764316330303862393538353138376564313262373365393735
          6662646438636332330a323061653966626234363530373039343837353062663762373734373235
          3864'
test_string=$(ansible-vault encrypt_string "HiddenText!"); vdecr "$test_string"
ansible-vault encrypt_string "HiddenText!" | vdecr

ИЛИ вы можете просто запуститьvdecr, вставьте строку и нажмите Ctrl-D.

Если вы передаете значение в качестве аргумента, обязательно используйте его в одинарных кавычках, чтобы $ANSIBLE_VAULT не превратился в ничто при помощи bash.
Если значение передается как переменная, укажите переменную.
Имея дело с аргументом, функция работает с! vault |префикс и без него.

Вот дополнительный псевдоним для генерации паролей, зашифрованных с помощью ansible-vault.

      alias genpwdv="ansible-vault encrypt_string $(openssl rand -base64 25 | sed 's/[\/+=]//g' | cut -c 3-20) 2> /dev/null"

Безумный, но элегантный сценарий оболочки для вывода чистого файла yaml с расшифрованными встроенными переменными (предполагается, что у вас установлен ANSIBLE_VAULT_PASSWORD_FILE иустановлен yq v4 ):

      VARS_FILE=path/to/your/vars_file_with_encrypted_vars.yml
yq -P e "$(for v in $(grep '\!vault' $VARS_FILE | cut -d: -f1); do val=$(yq e .${v} $VARS_FILE | tr -d ' ' | ansible-vault decrypt); echo .$v = \"$val\" \|; done) null = null" $VARS_FILE

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

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

Это приличный однострочный вариант использования yq, если у вас есть файл, из которого нужно прочитать переменную:

cat file_with_passwords.yml | yq -r ".var_name" | ansible-vault decrypt --vault-password-file ...

Обращаясь к этому вопросу и ответам здесь, я просто хотел бы добавить быстрый сценарий 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

Еще одно решение с использованиемAnsibleVaultLib:

pip install ansible-vault==2.1.0

      from ansible_vault.parsing import AnsibleVaultLib


password = 'my_best_pass'
vault = AnsibleVaultLib(password.encode())
test_var = vault.encrypt('test')

print(f'decoded: {test_var.decode()}')
print(f'encoded: {vault.decrypt(test_var).decode()}')

Выход:

      decoded: $ANSIBLE_VAULT;1.1;AES256
36653462643432376538383166343333613736373363376331656532326237353664373933616565
3435366262393165393536396431316439383036326364640a366633303130613763393630303837
36376564336565656665633935653734616365626165343332393066396662363937383934323736
3037613133356339330a656333396333656365383237633232396461356431653664356463623731
3633

encoded: test

Для файла типа 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

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

Если у вас установлен ansible, вы можете расшифровать файл (не строку), используя:

ansible-vault view your_vault_filename.yml

Это запросит у вас пароль, и после аутентификации контент будет отображаться расшифрованным.

источник https://www.digitalocean.com/community/tutorials/how-to-use-vault-to-protect-sensitive-ansible-data-on-ubuntu-16-04

Другие вопросы по тегам