Ansible vault wrapping script with GPG - ansible

I was tring to find the most secure way of using ansible vault in a docker env and the option of keeping the password as plain text in a file seems not so good so i saw a post about protecting the plain text file with gpg, now it all works great except that the gpg file is asking for its password randomly and it is on a docker container so it does not help :(
Here is how i set this up:
gpg-wrapper.sh -
#!/bin/sh
VAULT_PW_FILENAME="/base/vaults/vault.gpg"
gpg --quiet --batch --use-agent --decrypt $VAULT_PW_FILENAME
ansible.cfg -
vault_password_file = /base/vaults/gpg-wrapper.sh
encrypted like this:
gpg -c vault #which created the vault.gpg file
Is there another way for it ? a better one? or a way to keep gpg to ask the password once?
Thanks!

Related

How to avoid ask-vault-pass parameter on Ansible

I would like to do something like
ansible-playbook myPlaybook.yml -i myHostFile
instead of
ansible-playbook myPlaybook.yml -i myHostFile --ask-vault-pass
Your requirement is not clear. Following my comments, this answer is a specific example of how to secure your vault passwords inside your gnome linux session keyring using the vault-keyring-client.py script provided by ansible community contribs (hoping it will give you some ideas of how to fix the problem in your specific case).
Make sure you have the required dependencies to run the script
pip install keyring
Install the contrib script somewhere in your path (the given path is just an example, use one suited to your situation)
cd $HOME/bin
curl -o vault-keyring-client https://raw.githubusercontent.com/ansible-community/contrib-scripts/main/vault/vault-keyring-client.py
chmod 0700 vault-keyring-client
Create your vault id passwords in your session keystore using the script. The password is asked interactively and stored. You can see them browsing the login keyring after launching seahorse (i.e. "Passwords and keys").
vault-keyring-client --set --vault-id yourid1
vault-keyring-client --set --vault-id yourid2
Configure ansible to use that script for those ids. If an encrypted content is found without an id, they will be tried in order. You probably want to define a default id to encrypt the content. Add the following lines to your .bashrc (or whatever shell you use...)
export ANSIBLE_VAULT_IDENTITY_LIST=yourid1#$HOME/bin/vault-keyring-client,yourid2#$HOME/bin/vault-keyring-client
export ANSIBLE_VAULT_ENCRYPT_IDENTITY=yourid1
Encrypt some content
# using the default encrypt vault-id
ansible-vault encrypt somefile
ansible-vault encrypt_string "somestring"
# using an other vault-id than default
ansible-vault encrypt --encrypt-vault-id yourid2 somefile
ansible-vault encrypt_string --encrypt-vault-id yourid2 "somestring"
You can now use any playbook or adhoc command in need of a configured vault password from your openned session without having to provide it interactively
ansible-playbook -i your_inventory your_playbook
ansible-playbook -i your inventory somehost -m debug -a "msg={{ some_encrypted_var }}"

How to pass ansible vault password as an extra var?

I have the ability to encrypt variables using another mechanism(Azure pipeline secret feature), so I would like to save an ansible-vault password there(in Azure pipeline) and pass it to playbook execution as an extra var.
May I know if it can be done so?
An example of what/how I'm expecting is
ansible-playbook --extra-vars "vault-password=${pipelinevariable}"
Vault password cannot be passed as an extra var. There are several ways to provide it which are all covered in the documentation:
Providing vault password section in the general vault documentation.
Using vault in playbooks
Very basically your options are:
providing it interactively passing the --ask-vault-pass option
reading it from a file (static or executable) by either:
providing the --vault-password-file /path/to/vault option on the command line
setting the ANSIBLE_VAULT_PASSWORD_FILE environment variable (e.g. export ANSIBLE_VAULT_PASSWORD_FILE=/path/to/vault).
There is much more to learn in the above doc, especially how to use several vault passwords with ids, how to use a client script to retrieve the password from a key store...
Although this doesn't use extra vars, I believe it fulfills what you were trying to do:
Optional/one-time only: ask for the password and set it as an environment variable:
read -s ansible_vault_pass && export ansible_vault_pass
Now use that variable in your ansible command:
ansible-playbook your-playbook.yml --vault-password-file <(cat <<<"$ansible_vault_pass")
Credits for, and explanation of the <(cat <<<"") technique are in this other StackOverflow answer: Forcing cURL to get a password from the environment.
May I know if it can be done so?
Not familiar with Ansible Vault, but you have at least two directions based on the documents shared by Zeitounator.
1.Use a CMD task first to create a vault-password-file with plain-text content. (Not sure if the vault-password-file can be created in this way, it might not work.)
(echo $(SecretVariableName)>xxx.txt)
Then you may use the newly created xxx.txt file as input of ansible-playbook --vault-password-file /path/to/my/xxx.txt xxx.yml.
2.Create a corresponding vault-password-file before running the pipeline, add it to version control. (Same source repo of your current pipeline)
Then you can use ansible-playbook --vault-password-file easily when the vault-password-file is available. Also you can store the password file in private github repo, fetch the repo via git clone https://{userName}:{userPassword}#github.com/xxx/{RepoName}.git, copy the needed password file to the directory where you run the ansible-playbook commands via Copy Files task. This direction should work no matter if direction 1 is supported.

Need to assign gpg decrypted filename to a variable

I'm using below command(non -interactive mode of gpg) to decrypt my file:
gpg --yes --batch --passphrase=Abcdefgh1$ kbc.text.gpg
The file it will decrypt will be kbc.text. Now, in my script I need to assign name of this decrypted file to a variable which I need to use further. For that, I'm using below command:
tmp=gpg --yes --batch --passphrase=Abcdefgh1$ kbc.text.gpg
However, when I run this, I get below error:
script2.sh: line 2: --yes: command not found
Any way to implement this and avoid this error. Any help will be appreciated.

Using ansible-vault in "interactive mode" via bash script

I really love using ansible-vault on the command-line to encrypt/decrypt files easily. For example if I have a plaintext file called ~/fizzbuzz.foo with the following contents:
bupo
I can use this tool like so:
ansible-vault encrypt ~/fizzbuzz.foo
New Vault password: 123
Confirm New Vault password: 123
Boom -- encrypted! When I vi ~/fizzbuzz.foo now:
$ANSIBLE_VAULT;1.1;AES256
36663138613666623730653164333138343133383233313562363733346461663334393932393461
6535316532366130316237633633663565663366323162660a666630613738363035343663353132
33383530653235393431633231313765656135626538353163323366363039633836613265383332
3762666261326466370a643164393166346634343636346634383039356665646531353062303765
3734
I'd like to use this in a bash script where I pass the encryption/decryption password in as a script argument:
#!/bin/bash
# do some stuff
ansible-vault -i "bar" encrypt ~/fizzbuzz.foo
# do some more stuff
However I don't see anything like an interactive (e.g. -i) argument/mode for ansible-vault. The best I could find was a way of using an env file for storing passwords for the ansible-playbook utility but I played around with ansible-vault and couldn't find a similar behavior for it.
Any ideas?
you need to create the vault password file first, here is how:
openssl rand -base64 512 |xargs > vaultkeyfile
i am creating the vault file at local directory, but probably you want to place it to another one, like ~/.ansible_vault/ for example.
then to create/encrypt/decrypt the file, you use:
for new file:
ansible-vault create testfile.txt --vault-password-file=vaultkeyfile
for encrypting existing file:
ansible-vault encrypt testfile.txt --vault-password-file=vaultkeyfile
for decrypting:
ansible-vault decrypt testfile.txt --vault-password-file=vaultkeyfile
when executing the above, you will notice it doesn't ask for password.

Simple way to encrypt and decrypt a backup file in bash

I need to encrypt a backup file gzip.
I performed the following operation.,
tar -Pzcvf $dir/*.xml >/dev/null | gpg --yes --batch --passphrase PaSsW0rD -o "$bpath/$bfile".tar.gz
But it is failing with the following error.,
gpg: processing message failed: Unknown system error
I just need a simple passsord protected backup file. Any other alternative solutions are also welcome.
Thanks in advance
Option 1
Doing it your way :
tar -zcvf your_tar_file_name.tar.gz "$dir"/*.xml && gpg --symmetric --cipher-algo AES256 your_tar_file_name.tar.gz
Note that I do not wish to preserve absolute names, so I have stripped the P option from tar. The default output file in this case is your_tar_file_name.tar.gz.gpg.
To decrypt and get the files back you may do :
gpg -o my_tar_file.tar.gz -d your_tar_file_name.tar.gz.gpg && tar -xzf my_tar_file.tar.gz
This uses a symmetric encryption scheme, ie, we could use the same password to decrypt the file. The above command will ask you to enter the password for encryption and confirm it.
If you wish to do asymmetric encryption using gpg have a look at this tutorial.
Option 2
You may also use aescrypt
Download aescrypt from here
Once installed you may use the straight-forward GUI to encrypt the file.
If you need the command line tool, you could use the aescrypt command like below:
tar zcvf your_tar_file_name.tar.gz "$dir"/*.xml && aescrypt -e -p yourstrongpassword your_tar_file_name.tar.gz
Here e is for encryption and p is for password. The output will usually be stored in your_tar_file_name.tar.gz.aes.
You could decrypt the your_tar_file_name.tar.gz.aes file using
aescrypt -d -p yourstrongpassword your_tar_file_name.tar.gz.aes
Here d is for decryption.

Resources