Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Generate reusable non-random but strong password with Ansible from a seed

I have this idea for my Ansible inventory: I want to have only ONE vaulted value, a seed whicht gives birth to all the passwords I need in my inventory.

Something like this:

---

# I only have this to generate randomly, and vault
inventory_seed: "a strong random string" 

# Then all my other password are derived from this seed. 
# I feed the salted seed to a filter that creates a password directly sourced from the string I give him.

# will output, say, `wgSqz$@+SU^nw2;I` everytime I invoke ansible for the same inventory_hostname
machine_root_password: "{{ inventory_hostname + inventory_seed + 'root password' | to_strong_password }}"

# same: dp_password will be the same strong password everytime I invoke ansible
db_password:  "{{ inventory_seed + 'db password' | to_strong_password }}" 

# ... etc. All my inventory-specific passwords (and other keys) are derived from the same seed

This approach would help with the following issues:

  • I have many inventories, but only one set of roles.
  • I have to vault a new password for each and every inventory every time I introduce new passwords in a role.

Also I would expand this to generate keypairs, certificates and so on. Starting up a new inventory would be reduced to only specifying one or two vars instead of dozens.

Does this exist in the (comprehensive) Jinja / Ansible filters?

I am aware of the lookup( 'password', xxx) method, but this is not reproducible: it doesn't take a seed as input to output the same password if the same seed is provided. I also know that this is an often asked question here, but every time the password is saved locally which I don't want.

Will I have to implement this on my own?

How would you expand to generate other sensible but required data (X509 certs, keypairs, etc.)

like image 906
Gui13 Avatar asked Oct 13 '21 09:10

Gui13


People also ask

How do I make an Ansible random password?

Usage of variables like "{{ inventory_hostname }}" in the filepath can be used to set up random passwords per host, which simplifies password management in "host_vars" variables. A special case is using /dev/null as a path.

How do I change my Ansible Vault password?

If you need to change the password of an encrypted file, use the ansible-vault rekey command: ansible-vault rekey encrypt_me. txt.


2 Answers

The solution is to use password_hash which can also be combined with a salt and a seed.

Here are some examples:

# uses a random salt
# -> output changes on each run
{{ 'rootpassword' | password_hash('sha512') }}

# uses a user defined salt
# -> output always stays the same
{{ 'rootpassword' | password_hash('sha512', 'secretsalt') }}

# creates a random numeric salt by using the inventory_hostname as a seed
# -> output is unique for every host and stays the same on each run
{{ 'rootpassword' | password_hash('sha512', 12345 | random(seed=inventory_hostname) | string) }}
like image 57
F1ko Avatar answered Oct 20 '22 04:10

F1ko


Reading your requirements it sound for me like an old fashioned codebook or one-time-pad (OTP). You may find more information @https://crypto.stackexchange.com/.

I want to have only ONE vaulted value ...

Whereby your one vaulted value would be the codebook, which could be in example a very long random string or file (How do I create a 1GB random file?). You could define a character set and make it as long as you like, hundreds of kilobytes. It could also be a huge text file or just a video.

a seed which gives birth to all the passwords

The seed would you be a pointer to a position in that codebook or file and by defining the length you can just read out passwords you like.

like image 1
U880D Avatar answered Oct 20 '22 05:10

U880D