Skip to content
May 16 / Greg

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
[[email protected] 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.

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!

Leave a Comment

 

*