Setup Hashicorp Vault Quickly For Your Lab
I recently had the need to use Hashicorp Vault with Ansible to store passwords-n-such, and I thought “Oh I’m sure this is simple.” Several hours later I realized “It’s not so simple.”
I’ve put this together to be used in a LAB environment. The install method is good for production, but my configuration certainly is not LOL.
**I designed the playbook to work with Centos7, though I believe it will work with much more**
First is the install playbook that can be found here in my github account.
This playbook will go out and grab vault_1.4.1(which you can update to a different version in the script if you like), download it, unzip it, install it, setup a service file, create a base config file, and start the service. You will really need the “*.j2” template files found in the main folder here.
The install uses(at the time of this writing), the below config file:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | # # This is a sample dev server config. # # !! IT IS INSECURE !! # !! DO NOT USE IN PROD !! # # backend "inmem" {} backend "file" { path = "/mnt/vault/data" } listener "tcp" { address = "127.0.0.1:8200" tls_disable = 1 } listener "tcp" { address = "{{ ansible_host }}:8200" tls_disable = 1 } disable_mlock = true |
The config file makes the server listen on both 127.0.0.1 and whatever IP the Ansible server is using to connect to the server on.
It’s also disabling tls support(which should NOT be used in production; this is me whipping it up for my testing purposes).
It is also using simple file storage which isn’t suggested either. The deploy script will create the folder for the data file and sets permission for the vault user to access it.
Since the next couple of commands require accessing the vault server directly, try setting these env variables to make it easy. If this doesn’t help sort it, just use the “-address http://127.0.0.1:8200” option to your commands.
1 2 | export VAULT_ADDRESS='http://127.0.0.1:8200' echo "export VAULT_ADDR=http://127.0.0.1:8200" >> ~/.bashrc |
Once the deploy script has run the vault needs to be initialized, which is done only a single time. Once you initialize it, it will spit out the root token(used for authentication) and 5 key shards used to “unseal” the vault file.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | vault operator init Unseal Key 1: rZAdDj0KyuwJKZa5/Cxpt3e0G5rjPFHyQgZ/KGwawcol Unseal Key 2: 7wL3eOZumgL36Kf+0i0BoPj7rG6xOYsJNUZpqvKYfirx Unseal Key 3: ZijK5fK7MFRPW90kJ1TRAP8ZznsZYtZ/x8KrX9JcEXWw Unseal Key 4: no7+kdAmn8RdN/h+gULkn076pVhJJYqveVSdak14LVoE Unseal Key 5: hfY07AW9R6abky7JgsIDGmGgkxY6EqjwCe9+8UKkcdQX Initial Root Token: s.fKYto48B80ObQrQkorMoexJv Vault initialized with 5 key shares and a key threshold of 3. Please securely distribute the key shares printed above. When the Vault is re-sealed, restarted, or stopped, you must supply at least 3 of these keys to unseal it before it can start servicing requests. Vault does not store the generated master key. Without at least 3 key to reconstruct the master key, Vault will remain permanently sealed! It is possible to generate new unseal keys, provided you have a quorum of existing unseal keys shares. See "vault operator rekey" for more information. |
If you get an error like this “Error initializing: Put https://127.0.0.1:8200/v1/sys/init: http: server gave HTTP response to HTTPS client”, then try adding the address to the above command:
1 | vault operator init -address http://127.0.0.1:8200 |
The idea of the vault is that it defaults to sealed. You first have to take 3 keys and apply them to the vault to unlock it. In reality you would separate those keys for safety…imagine it like a bank vault where there are 5 keys and it takes three people with keys to unlock it. You can do this manually each time you want to unlock it with:
1 2 3 | vault operator unseal rZAdDj0KyuwJKZa5/Cxpt3e0G5rjPFHyQgZ/KGwawcol vault operator unseal 7wL3eOZumgL36Kf+0i0BoPj7rG6xOYsJNUZpqvKYfirx vault operator unseal ZijK5fK7MFRPW90kJ1TRAP8ZznsZYtZ/x8KrX9JcEXWw |
Technically you should put the vault key on the command line because it shows up in the history, but this is just for lab use.
If you reboot the server the vault will auto seal back up and you have to unseal it again. In production this isn’t such a big deal, but in my lab I’ll have this thing off most of the time, so to make it easier I created a script that is called when the server boots to auto unseal it(/root/unseal_vault.sh):
1 2 3 4 5 6 | #!/bin/bash vault operator unseal -address http://127.0.0.1:8200 rZAdDj0KyuwJKZa5/Cxpt3e0G5rjPFHyQgZ/KGwawcol sleep 2 vault operator unseal -address http://127.0.0.1:8200 7wL3eOZumgL36Kf+0i0BoPj7rG6xOYsJNUZpqvKYfirx sleep 2 vault operator unseal -address http://127.0.0.1:8200 ZijK5fK7MFRPW90kJ1TRAP8ZznsZYtZ/x8KrX9JcEXWw |
You can see in the commands I added the -address command for it use; for some reason it kept trying to use https when it wasn’t specified.
I then changed it to executable:
1 | chmod +x /root/unseal_vault.sh |
I then create the service file(/etc/systemd/system/unseal_vault.service):
1 2 3 4 5 6 7 8 9 10 | [Unit] Description=Unseal the vault [Service] Type=idle ExecStart=/root/unseal_vault.sh TimeoutStartSec=0 [Install] WantedBy=default.target |
After that I reload the daemon and enabled the unseal service:
1 2 | systemctl daemon-reload systemctl enable unseal_vault.service |
I start by logging in:
1 | vault login s.fKYto48B80ObQrQkorMoexJv |
Replace the token here with the root token supplied during initiation.
Now that is out of the way I’ll create a secrets engine with the keyvault command(where keys can be stored):
1 | vault secrets enable -path=secret kv |
The secrets engine name is secret.
I’m now going to populate it with some pairs:
1 | vault kv put secret/2020 password=redhat |
If I want to check the pair I can do:
1 2 | vault kv get -field=password secret/2020 redhat |
When I “put” the keypair in I made it password=redhat, but it could have been pie=apple or taco=delicious. I just made it password= because I figured it would make things simpler in my ansible scripts.
There’s also a test ansible script in the repo above that will poll using the root key I got from initialization:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | [root@ansible1 ansible]# ansible-playbook hashicorp-vault-pw.yml PLAY [test vault] ******************************************************************************************** TASK [register password from vault] ************************************************************************** ok: [localhost] TASK [Return all secrets from a path] ************************************************************************ ok: [localhost] => { "msg": "redhat" } PLAY RECAP *************************************************************************************************** localhost : ok=2 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 |
You will likely need to adjust your firewall to allow TCP/8200 in since this is the port the Vault API uses for access.
Adding To Ansible Automation Platform 2.X
First, here’s the quick documentation on configuring a machine credential for this, though it is not specifically talking about vault.
Setup a “HashiCorp Vault Secret Lookup” credential:
You can see I specify the URL of the server including the port used, then enter my access token, and last I’m using API v1.
Next I setup a machine credential that will access the hashicorp vault info setup above. Notice I hardcoded a username, but I want to do the lookup on the password. Instead of entering something in the password field I click the little key icon:
Once the key is clicked it will popup a screen that allows me to choose the vault lookup credential I just created:
I now put in my path to secret. This is vault named secret and keyvault named 2020.
After that I specify the key name; in my case I just named the key “password”.
After I click test it should popup a message saying everything passed. After that I simply click OK.
I can now use this machine credential as I would any other machine credential.
Conclusion
There’s an awesome tutorial on hashicorp vault I would highly recommend you spending 45 minutes to go through; it really gives you everything you need to start quickly playing with vault.
I hope this was helpful; good luck and happy vaulting!