如何使用 ansible-vault 2.3.0 解密字符串
How to decrypt string with 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
我如何才能解密该字符串,以便在不需要 运行 播放的情况下知道它的价值?
您是否尝试过将加密字符串设置为变量,然后使用 -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-vault
输出到 stderr
,然后将 stdout
重定向到 /dev/null
,因为该工具会打印 Decryption successful
。
新的 Ansible 版本可能不需要 /dev/stdin/
部分。
类似于:
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
由于整个 vault 文件不能很好地与 git 历史一起使用,因此在变量文件中使用 vault 字符串是可行的方法,这也使得按名称搜索变量更加清晰。
这是一个简单的示例:
我想把 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
$
您也可以使用简单的 ansible
命令来实现相应的 host/group/inventory 组合,例如:
$ ansible my_server -m debug -a 'var=my_secret'
my_server | SUCCESS => {
"my_secret": "373861663362363036363361663037373661353137303762"
}
尽管使用 ansible 调试消息或使用 ansible cli 显示加密字符串值没有问题,但还有一种解决方案可能更方便自动化需求。您可以利用来自 ansible 的 python 库并在您的代码中使用它们(基本上,所有这些都位于 ansible.parsing.*)
1) 提供保管库密码并生成带有机密的 "vault"。
# 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) 使用 AnsibleLoader 加载 yaml 文件:
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)
这是对我有用的方法,类似于 Scudelletti 所做的,但传递了金库通行证,即
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。
希望对您有所帮助!
这一命令仅提取加密数据并将其传递给解密。我更喜欢它,因为您不需要手动提取数据。
$ grep -v vault test.yml | awk '{=;print}' | ansible-vault decrypt
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
这是另一种解密字符串的方法
$ 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 在这里对于解释 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 是您用于 encrypt/decrypt.
的密钥的路径
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
对于类似 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
应该可以,前提是您拥有加密数据的密钥。
遇到这个问题和这里的答案,我只想添加一个我一起编写的快速 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 | 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
对于那些想要定义别名而忘记管道和临时文件的人,这里有一个您可以采用的解决方案:
function decrypt_ansible_vault_string() {
export FN=
export KEY=
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
这个答案扩展了
注意,我使用的是 this yq,但是任何 yaml 查询工具都可以。此处重要的是使用 subshell 重定向的原则(无临时文件)。
另请注意,您可以添加 --ask-vault-password
。然而,使用使用 GPG 加密的秘密要好得多,因为你不必每次都输入密码,而且这种工作流程对于团队(YMVV 和 IHMO)来说要好得多。这里是 a good tutorial on how to use GPG with ansible-vault.
把这个贴在你的 .bashrc
上尽情享受吧。
更新
我对 ansible-vault encrypt\decrypt
工作流程感到沮丧。因此,我创建了一个包装器,用于解密 var 文件中的字符串。检查一下:https://github.com/oz123/ansible-vault-string-helper
一条线就可以做到
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
您可以将加密后的字符串复制到文件中,但您只需要复制加密部分,而不需要复制其他 yml 部分。
因此您的文件需要更改自:
test: !vault |
$ANSIBLE_VAULT;1.1;AES256
37366638363362303836383335623066343562666662386233306537333232396637346463376430
3664323265333036663736383837326263376637616466610a383430623562633235616531303861
66313432303063343230613665323930386138613334303839626131373033656463303736366166
6635346135636437360a313031376566303238303835353364313434363163343066363932346165
6136
至:
$ANSIBLE_VAULT;1.1;AES256
37366638363362303836383335623066343562666662386233306537333232396637346463376430
3664323265333036663736383837326263376637616466610a383430623562633235616531303861
66313432303063343230613665323930386138613334303839626131373033656463303736366166
6635346135636437360a313031376566303238303835353364313434363163343066363932346136
您将能够使用
进行描述或查看
ansible-vault decrypt --vault-password-file <path to passwordfile> test.yml
ansible-vault view --vault-password-file <path to passwordfile> test.yml
也许删除 .yml
因为那不再有意义了。
我知道这已经有一段时间了,但是当我通过 ansible-vault decrypt
直接通过管道传输时它对我有用,就像这样:
$ echo '$ANSIBLE_VAULT;1.1;AES256
38613538323065373061616466616334306237336461333935393261646131616232643238626635
3336633631366539383039343437306664336165326565650a353233303431613362653838643135
34363763366134393366356339343039313035366164636133326639376334313335316565373330
3435633463313334310a653239313039323135363865313933626464663363656164343662303763
34616663626530656630633839346531653862633332396365396432366234333861' | ansible-vault decrypt
Decryption successful
super-secret-string$
以防万一有人感兴趣。我有 ansible 版本 2.9.26
疯狂但优雅的 shell 脚本输出带有解密内联变量的干净 yaml 文件(假设您有 ANSIBLE_VAULT_PASSWORD_FILE set and yq v4 installed):
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
有了这个,你可以解密一个只包含一个 ansible 保险库字符串的文件:
cat encrypted_vault_string | ansible-vault decrypt
输出:
Vault passsword: <enter password, is not echoed to you>
Decryption successful
< decrypted string here>
ansible 保险库字符串如下所示:
$ANSIBE_VAULT;1.1;AES256
123456789...
123456789...
123456789...
1234
这也适用于没有中间文件
echo -e '$ANSIBLE_VAULT;1.1;AES256\n123456789...789' | ansible-vault decrypt
尝试解密 /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 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
我如何才能解密该字符串,以便在不需要 运行 播放的情况下知道它的价值?
您是否尝试过将加密字符串设置为变量,然后使用 -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-vault
输出到 stderr
,然后将 stdout
重定向到 /dev/null
,因为该工具会打印 Decryption successful
。
新的 Ansible 版本可能不需要 /dev/stdin/
部分。
类似于:
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
由于整个 vault 文件不能很好地与 git 历史一起使用,因此在变量文件中使用 vault 字符串是可行的方法,这也使得按名称搜索变量更加清晰。
这是一个简单的示例:
我想把 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
$
您也可以使用简单的 ansible
命令来实现相应的 host/group/inventory 组合,例如:
$ ansible my_server -m debug -a 'var=my_secret'
my_server | SUCCESS => {
"my_secret": "373861663362363036363361663037373661353137303762"
}
尽管使用 ansible 调试消息或使用 ansible cli 显示加密字符串值没有问题,但还有一种解决方案可能更方便自动化需求。您可以利用来自 ansible 的 python 库并在您的代码中使用它们(基本上,所有这些都位于 ansible.parsing.*)
1) 提供保管库密码并生成带有机密的 "vault"。
# 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) 使用 AnsibleLoader 加载 yaml 文件:
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)
这是对我有用的方法,类似于 Scudelletti 所做的,但传递了金库通行证,即
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。
希望对您有所帮助!
这一命令仅提取加密数据并将其传递给解密。我更喜欢它,因为您不需要手动提取数据。
$ grep -v vault test.yml | awk '{=;print}' | ansible-vault decrypt
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
这是另一种解密字符串的方法
$ 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 在这里对于解释 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 是您用于 encrypt/decrypt.
的密钥的路径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
对于类似 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
应该可以,前提是您拥有加密数据的密钥。
遇到这个问题和这里的答案,我只想添加一个我一起编写的快速 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 | 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
对于那些想要定义别名而忘记管道和临时文件的人,这里有一个您可以采用的解决方案:
function decrypt_ansible_vault_string() {
export FN=
export KEY=
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
这个答案扩展了 --ask-vault-password
。然而,使用使用 GPG 加密的秘密要好得多,因为你不必每次都输入密码,而且这种工作流程对于团队(YMVV 和 IHMO)来说要好得多。这里是 a good tutorial on how to use GPG with ansible-vault.
把这个贴在你的 .bashrc
上尽情享受吧。
更新
我对 ansible-vault encrypt\decrypt
工作流程感到沮丧。因此,我创建了一个包装器,用于解密 var 文件中的字符串。检查一下:https://github.com/oz123/ansible-vault-string-helper
一条线就可以做到
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
您可以将加密后的字符串复制到文件中,但您只需要复制加密部分,而不需要复制其他 yml 部分。
因此您的文件需要更改自:
test: !vault |
$ANSIBLE_VAULT;1.1;AES256
37366638363362303836383335623066343562666662386233306537333232396637346463376430
3664323265333036663736383837326263376637616466610a383430623562633235616531303861
66313432303063343230613665323930386138613334303839626131373033656463303736366166
6635346135636437360a313031376566303238303835353364313434363163343066363932346165
6136
至:
$ANSIBLE_VAULT;1.1;AES256
37366638363362303836383335623066343562666662386233306537333232396637346463376430
3664323265333036663736383837326263376637616466610a383430623562633235616531303861
66313432303063343230613665323930386138613334303839626131373033656463303736366166
6635346135636437360a313031376566303238303835353364313434363163343066363932346136
您将能够使用
进行描述或查看ansible-vault decrypt --vault-password-file <path to passwordfile> test.yml
ansible-vault view --vault-password-file <path to passwordfile> test.yml
也许删除 .yml
因为那不再有意义了。
我知道这已经有一段时间了,但是当我通过 ansible-vault decrypt
直接通过管道传输时它对我有用,就像这样:
$ echo '$ANSIBLE_VAULT;1.1;AES256
38613538323065373061616466616334306237336461333935393261646131616232643238626635
3336633631366539383039343437306664336165326565650a353233303431613362653838643135
34363763366134393366356339343039313035366164636133326639376334313335316565373330
3435633463313334310a653239313039323135363865313933626464663363656164343662303763
34616663626530656630633839346531653862633332396365396432366234333861' | ansible-vault decrypt
Decryption successful
super-secret-string$
以防万一有人感兴趣。我有 ansible 版本 2.9.26
疯狂但优雅的 shell 脚本输出带有解密内联变量的干净 yaml 文件(假设您有 ANSIBLE_VAULT_PASSWORD_FILE set and yq v4 installed):
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
有了这个,你可以解密一个只包含一个 ansible 保险库字符串的文件:
cat encrypted_vault_string | ansible-vault decrypt
输出:
Vault passsword: <enter password, is not echoed to you>
Decryption successful
< decrypted string here>
ansible 保险库字符串如下所示:
$ANSIBE_VAULT;1.1;AES256
123456789...
123456789...
123456789...
1234
这也适用于没有中间文件
echo -e '$ANSIBLE_VAULT;1.1;AES256\n123456789...789' | ansible-vault decrypt
尝试解密 /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