Как расшифровать строку с помощью 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
Это запросит у вас пароль, и после аутентификации контент будет отображаться расшифрованным.