简体   繁体   English

如何使用 ansible-vault 2.3.0 解密字符串

[英]How to decrypt string with ansible-vault 2.3.0

I have been waiting for ansible 2.3 as it was going to introduce encrypt_string feature.我一直在等待 ansible 2.3,因为它将引入 encrypt_string 功能。

Unfortuately I'm not sure how can I read the encrypted string.不幸的是,我不确定如何读取加密的字符串。

I did try decrypt_string , decrypt (the file), view (the file) and nothing works.我确实尝试了 decrypt_string解密(文件),查看(文件),但没有任何效果。

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

The error I'm geeting is ERROR! input is not vault encrypted data for test.yml我遇到的错误是ERROR! input is not vault encrypted data for test.yml ERROR! input is not vault encrypted data for test.yml

How can I decrypt the string so I know what it's value without the need to run the play?如何解密字符串以便我知道它的价值而不需要运行播放?

You can also do with plain ansible command for respective host/group/inventory combination, eg:您还ansible对各自的主机/组/库存组合使用简单的ansible命令,例如:

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

You can pipe the input then tell ansible-vault to output to stderr and then redirect the stdout to /dev/null since the tool prints Decryption successful .您可以通过管道输入输入,然后告诉ansible-vault输出到stderr ,然后将stdout重定向到/dev/null因为该工具会打印Decryption successful

The /dev/stdin/ part may not be needed in new Ansible versions.在新的 Ansible 版本中可能不需要/dev/stdin/部分。

Something like:就像是:

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

Here is a example:下面是一个例子:

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

I hope they implement a simpler way of doing this.我希望他们实现一种更简单的方法来做到这一点。

Edit: Environment Variables as Input:编辑:环境变量作为输入:

To have a similar behaviour with multi-line environment variables on bash use printf instead of echo要在bash使用多行环境变量具有类似的行为,请使用printf而不是echo

Example (password: 123):示例(密码: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

since whole vault files do not play well with git histories, using vault strings within the variable files is the way to go, it also makes grepping out variables by name much clearer.由于整个 Vault 文件不能很好地与 git 历史记录配合使用,因此在变量文件中使用 Vault 字符串是可行的方法,它还可以更清晰地按名称查找变量。

Here is a simple worked example:这是一个简单的工作示例:

I want to put fredsSecretString: value into vars.yml , (its value is fastfredfedfourfrankfurters but hush, don't let people know !!)我想把 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

To decrypt the value feed the encrypted string back into ansible-vault as follows:要解密该值,将加密的字符串反馈回 ansible-vault,如下所示:

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

Did you try setting the encrypted string as a variable and then using -debug to get its decrypted output?您是否尝试将加密字符串设置为变量,然后使用-debug获取其解密输出?

ie IE

Define your encrypted string as a variable test in your playbook and then do:将加密字符串定义为剧本中的变量test ,然后执行以下操作:

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

in your playbook and then run the playbook:在你的剧本中,然后运行剧本:

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

Here's another way to decrypt strings这是解密字符串的另一种方法

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

The trick here is we're passing a file with an Ansible vaulted secret, mysecret within it too ansible and it's able to decrypt it.这里的技巧是我们传递一个文件与Ansible拱形的秘密, mysecret内太ansible ,它是无法解密它。

NOTE: If you do not have your password to decrypt the Ansible vaulted encrypted secret you can pass that in as well:注意:如果您没有密码来解密 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 extracts the encrypted var value, then will create a temporary file and use it with ansible-vault : 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

Here is what works for me, similar to what Scudelletti does but passing in the vault pass ie这是对我有用的方法,类似于 Scudeletti 所做的,但传递了金库通行证,即

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

The output will be on its own line for convenience, thanks to the trailing && echo .由于尾随&& echo ,为方便起见,输出将在自己的行上。 The permission of my vault pass is 644 if you run into any permission errors.如果您遇到任何权限错误,我的金库通行证的权限是 644。

Hope it helps!希望能帮助到你!

Although, there is no problems showing encrypted string values with ansible debug messages or using ansible cli, there is one more solution that may be convenient for automation needs.尽管使用 ansible 调试消息或使用 ansible cli 显示加密字符串值没有问题,但还有一种解决方案可能会方便自动化需求。 You can utilize python libs from ansible and use them in your code (basically, all this located in ansible.parsing.*)您可以使用 ansible 中的 python 库并在您的代码中使用它们(基本上,所有这些都位于 ansible.parsing.* 中)

1) Provide vault password and generate "vault" with secrets. 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) Load yaml file with AnsibleLoader: 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) If you need to encrypt a new string and update your dictionary: 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) Once complete processing, write back with AnsibleDumper: 4) 处理完成后,用 AnsibleDumper 回写:

with open('new_variables.yml','w') as fd:
    yaml.dump(loaded_yaml, fd, Dumper=AnsibleDumper, encoding=None, default_flow_style=False)

This one command extracts out just the encrypted data and passes it to decrypt.这一命令仅提取加密数据并将其传递给解密。 I like it a bit better, as you don't need to manually extract the data.我更喜欢它,因为您不需要手动提取数据。

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

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

With this you can decrypt a file containing just an ansible vault string:有了这个,你可以解密一个只包含 ansible vault 字符串的文件:

cat encrypted_vault_string | ansible-vault decrypt

output:输出:

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

An ansible vault string looks like: ansible 保险库字符串如下所示:

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

This also works without an intermediate file这也适用于没有中间文件

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

For those who want to define an alias and forget about pipes and temp files, here is a solution which you can adopt:对于那些想要定义别名而忘记管道和临时文件的人,这里有一个您可以采用的解决方案:

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

Example usage:用法示例:

$ 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 answer expands on the comment from @maricn Note, I am using this yq , but any yaml query tool can do.这个答案扩展了@maricn Note 的评论,我正在使用这个 yq ,但任何 yaml 查询工具都可以。 It's the principle of using subshell redirect that matters here (No temp files).使用子shell重定向的原则在这里很重要(没有临时文件)。 Also note, you can add --ask-vault-password .另请注意,您可以添加--ask-vault-password However, using a secret encrypted with GPG is much nicer, since you don't have to type your password every time and this work flow is much better for teams (YMVV and IHMO).但是,使用 GPG 加密的秘密要好得多,因为您不必每次都输入密码,而且这种工作流程对于团队(YMVV 和 IHMO)来说要好得多。 Here is a good tutorial on how to use GPG with ansible-vault .这是一个关于如何将 GPG 与 ansible-vault 结合使用的好教程

Stick this in your .bashrc and enjoy it.把它放在你的.bashrc并享受它。

update更新

I got frustrated with ansible-vault encrypt\\decrypt workflow.我对ansible-vault encrypt\\decrypt工作流程感到沮丧。 So, I created a wrapper for also decrypting strings in the var files.因此,我创建了一个包装器,用于解密 var 文件中的字符串。 Check it out: https://github.com/oz123/ansible-vault-string-helper看看: https : //github.com/oz123/ansible-vault-string-helper

You can copy the encrypted string to a file but you need to only copy the encrypted part and not the other yml parts.您可以将加密的字符串复制到文件中,但您只需要复制加密的部分,而不需要复制其他 yml 部分。

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.也许删除.yml因为这不再有意义。

This is how I am encrypting and decrypting strings inline, additionally for use as environment variables.这就是我如何加密和解密内联字符串,另外用作环境变量。

yq is especially useful here for interpreting yaml input. yq 在这里对于解释 yaml 输入特别有用。

In one line if I were to test encrypt and decypt a string I would do this-在一行中,如果我要测试加密和解密字符串,我会这样做-

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

I'm guessing that those usually interested in this are interested in decrypting environment variables.我猜那些通常对此感兴趣的人对解密环境变量感兴趣。 This is how I implement that use case, where testvar is the encrypted environment variable, and and $vault-id is the path to the key you are using to encrypt/decrypt.这就是我实现该用例的方式,其中 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

For a file like test.yml:对于像 test.yml 这样的文件:

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

the following crude implementation (recomended only for some quick manual action obviously):以下粗略的实现(显然只推荐用于一些快速的手动操作):

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

should work, provided that you have the key that encrypted the data .应该可以工作,前提是您拥有加密数据的密钥

Coming across this question and the answers here, I'd just like to add a quick bash script i cooked together that reads through an entire yaml file hunting for strings that can be decrypted dumping to screen.遇到这个问题和这里的答案,我只想添加一个我一起编写的快速 bash 脚本,它读取整个 yaml 文件,寻找可以解密转储到屏幕的字符串。

It's far from perfect and I'm not the hottest at bash but, hope this helps someone who was in the same situation as me wanting to do a general dump.它远非完美,我在 bash 方面也不是最热门的,但是,希望这可以帮助那些与我想要进行一般转储的情况相同的人。

To use the following script, it is necessary to have your vault password in a file (current working path) called vault_pass , along with yq and jq installed.要使用以下脚本,必须在名为vault_pass的文件(当前工作路径)中包含您的库密码, yq and jq安装yq and jq The file to be parsed should be first argument.要解析的文件应该是第一个参数。 eg ./vault_reader.sh group_vars/production.yml例如./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

I know it's been a while, but it worked for me when I piped it through ansible-vault decrypt without anything else, like this:我知道已经有一段时间了,但是当我通过ansible-vault decrypt而没有其他任何东西时,它对我ansible-vault decrypt ,如下所示:

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

Just in case anyone is interested.以防万一有人感兴趣。 I have ansible version 2.9.26我有2.9.26版本2.9.26

Insane but elegant shell script to output a clean yaml file with decrypted inline vars (assumes that you have ANSIBLE_VAULT_PASSWORD_FILE set and yq v4 installed ):疯狂但优雅的 shell 脚本输出一个干净的 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

Trying to decrypt /dev/stdin , as in ansible-vault decrypt /dev/stdin , or using --vault-password-file=/dev/stdin , like other commenters mention, also fails for me with errors like ERROR! [Errno 2] No such file or directory: '/proc/100/fd/pipe:[12930445]'尝试解密/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]' ERROR! [Errno 2] No such file or directory: '/proc/100/fd/pipe:[12930445]' . ERROR! [Errno 2] No such file or directory: '/proc/100/fd/pipe:[12930445]'

However, --vault-password-file also takes an executable to produce the password on stdout, so you can actually use /bin/cat to pipe in the password:但是, --vault-password-file也需要一个可执行文件来在 stdout 上生成密码,因此您实际上可以使用/bin/cat来输入密码:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM