Vault: PKI Made Easy
Disclamer
Well, not quite PKI Made Easy, but definitely a bit more fun!
I’ve done all this work on OSX, but I believe the Linux setup should be very similar.
Vault 0.3 was the version used.
Containerize all the things
Last week I was tinkering with Docker and wanted to get Hashicorp Vault running on a container, this was mainly a plan to trick myself into learning more about Vault.
The Docker stuff went pretty well and you have available a public container to prove it, check it out at:
hashicorp-vault on a container
Regarding the plan, it worked flawlessly and I’ve got really interested in the application.
So, what’s Vault?

Vault secures, stores, and tightly controls access to tokens, passwords, certificates, API keys, and other secrets in modern computing. Vault handles leasing, key revocation, key rolling, and auditing. Vault presents a unified API to access multiple backends: HSMs, AWS IAM, SQL databases, raw key/value, and more. (source)
I’m not going into depth about how the application works and all the features it provides, firstly because I just started playing with it and secondly the documentation does a very good job on that.
Instead I’ll talk about what I’ve learned regarding the PKI backend configuration and usage.
These are the points I’ll cover:
- Install Vault
- Configure Vault
- Generate a Root Certification Authority (CA) and Intermediate CA
- Create a PKI backend
- Configure the PKI backend
- Issue a couple of server certificates
- Issue a Certificate Revocation List (CRL) on Vault
- Revoke a certificate
- Vault using TLS
Setup
Create the following vault.conf file:
Create and run the following setup script on the same path as the vault.conf file:
You now should have a running instance of Vault using the /tmp/vault/vault.conf configuration.
Initialize Vault
cd /tmp/vault
vault init > credentials.txt
# check if initialized
curl http://127.0.0.1:8200/v1/sys/init
# keep your credentials safe
cat credentials.txtUnseal Vault
Vault is protected by M-of-N so you’ll need to run the unseal command 3 times using a different key each time to open it.
The M of N feature provides a means by which organizations employing cryptographic modules for sensitive operations can enforce multi-person control over access to the cryptographic module. (source)
vault unsealExport the Root Token
This will authenticate your vault client against the Vault server.
export VAULT_TOKEN=use-your-generated-root-tokenCheck the current mount points
vault mountsMount the PKI backend
vault mount pki
vault mounts
vault path-help pkiGet your hands on a CA certificate
You’ll need a CA for the next steps. Don’t have one?
Here you go (thank me later):
dummy_ca
You should never use a Root CA to issue client/server certificates, if it’s compromised you’re screwed! Instead, generate an intermediate CA and if that one it’s compromised just revoke it and issue a new one, keeping the Root CA offline.
With your certificates generated, now build a certificate bundle with the Intermediate CA certificate and Intermediate CA key.
export DUMMY_CA=/PATH/TO/dummy_ca
cat $DUMMY_CA/pki/intermediate/certs/intermediate.pem > \
/tmp/vault/ca_bundle.pem
# vault does not accept encrypted keys
openssl rsa -in $DUMMY_CA/pki/intermediate/private/intermediate.key >> \
/tmp/vault/ca_bundle.pemConfigure the PKI backend
Carefully read the documentation regarding the API endpoints /pki/config/, /pki/roles and /pki/issue/
vault write pki/config/ca pem_bundle="@/tmp/vault/ca_bundle.pem"
vault write pki/roles/test-dot-local allow_any_name="true" \
allow_subdomains="true" allow_ip_sans="true" max_ttl="420h" \
allow_localhost="true" allow_ip_sans="true"
vault write pki/issue/test-dot-local common_name=localhost \
alt_names="vault.test.local,*.vault.test.local" \
ip_sans="127.0.0.1,192.168.1.77" > /tmp/vault/localhost.certs
vault write pki/issue/test-dot-local \
common_name=sheep.test.local > /tmp/vault/sheep.certsSplit the localhost.certs into a separated key and certificate files:
localhost.pemlocalhost.key
Split the sheep.certs into a separated key and certificate files:
sheep.pemsheep.key
Test the CRL
This shouldn’t return any revoked certificates yet.
curl -v http://127.0.0.1:8200/v1/pki/crl/pem
* Trying 127.0.0.1...
* Connected to 127.0.0.1 (127.0.0.1) port 8200 (#0)
> GET /v1/pki/crl/pem HTTP/1.1
> Host: 127.0.0.1:8200
> User-Agent: curl/7.43.0
> Accept: */*
>
< HTTP/1.1 200 OK
< Content-Type: application/pkix-crl
< Date: Sun, 15 Nov 2015 12:14:40 GMT
< Content-Length: 0
<
* Connection #0 to host 127.0.0.1 left intactRevoking a certicate
To revoke a certificate you first need its Serial Number.
export SHEEP_SN=$(openssl x509 -in /tmp/vault/sheep.pem -text | \
grep -A1 "Serial Number" | grep -v "Serial Number" | \
awk {'print $1'})
curl -v -X POST http://127.0.0.1:8200/v1/pki/revoke \
-H "X-Vault-Token: $VAULT_TOKEN" \
-d '{"serial_number":"'$SHEEP_SN'"}'Test the CRL
curl -v http://127.0.0.1:8200/v1/pki/crl/pem > \
/tmp/vault/crl.pem
openssl crl -inform PEM -in /tmp/vault/crl.pem -textYou should see the revoked Serial Number.
Vault with TLS
This bit took me quite a while to figure out.
The documentation doesn’t mention how to do it.
The Vault server doesn’t send the Intermediate CA certificate with the leaf certificate to the vault client, this way you can’t just trust the Root CA, you’ll need to trust the Intermediate one… ¯\_(ツ)_/¯
I even tried providing a ca_bundle with the Root CA certificate in it, but no luck.
Then there was was the issue of finding out how to provide a truststore to the vault client…
# enable the truststore
export VAULT_CAPATH=$DUMMY_CA/pki/intermediate/certs/intermediate.pemUncomment the lines tls_*_file and comment out tls_disable on vault.conf
pkill vault
vault server -config="/tmp/vault/vault.conf" &
export VAULT_ADDR=https://127.0.0.1:8200
vault unsealIf it doesn’t give you a TLS error, you’re golden! You can check the certificate the server is using and the chain if he sends it, with:
openssl s_client -showcerts -connect 127.0.0.1:8200That’s it, that’s all
This blog post only scratches the surface of what Vault is capable of. I’m currently looking into High Availability and there’s still many other backends to try out, but I hope I’ve piqued your curiosity.
Big thanks to Hashicorp for releasing such amazing open source products.
Leave a comment