Hashicorp Consul - Vault Cert Management Part 1
- Generate mTLS Certificates using Vault
- Configure Vault's PKI secrets engine
- Configure Vault as Consul's CA
- Generate a Server Certificate
- Configure Consul
Generate mTLS Certificates using Vault
You can use Vault's PKI Secrets Engine to generate and renew dynamic X.509 certificates with consul-template to rotate your certificates. This method enables each agent in the Consul datacenter to have a unique certificate with a relatively short time-to-live (ttl) that is automatically rotated, which allows you to safely and securely scale your datacenter while using mutual TLS (mTLS).
Prerequisites
Consul
Vault
consul-template
(installation)
Configure Vault's PKI secrets engine
In order to communicate with the Vault server, you will need to set the address and token:
export VAULT_ADDR="http://127.0.0.1:8200"
export VAULT_TOKEN="root"
Enable Vault's PKI secrets engine at the pki path:
vault secrets enable pki
Tune the PKI secrets engine to issue certificates with a maximum time-to-live (TTL) of 87600 hours:
vault secrets tune -max-lease-ttl=87600h pki
Configure Vault as Consul's CA
Generate the root certificate and save the certificate in CA_cert.crt
:
vault write -field=certificate pki/root/generate/internal \
common_name="consul.consul" \
ttl=87600h > CA_cert.crt
Careful: The official documentation uses the
common_name
for the default datacenterconsul.dc1
. I use the nameconsul
here and have to change the variableconsul.consul
accordingly. Otherwise the cert verification will fail. This name will be used a couple of times in the following commands - you need to change all of them according to your setup.
This generates a new self-signed CA certificate and private key. Vault will automatically revoke the generated root at the end of its lease period (TTL); the CA certificate will sign its own Certificate Revocation List (CRL):
openssl x509 -text -noout -in CA_cert.crt
Certificate:
Data:
Version: 3 (0x2)
Serial Number:
74:...
Signature Algorithm: sha256WithRSAEncryption
Issuer: CN = consul.consul
Validity
Not Before: Dec 4 10:57:22 2022 GMT
Not After : Dec 1 10:57:52 2032 GMT
Subject: CN = consul.consul
Subject Public Key Info:
Public Key Algorithm: rsaEncryption
RSA Public-Key: (2048 bit)
Modulus:
00:...
Exponent: 65537 (0x10001)
X509v3 extensions:
X509v3 Key Usage: critical
Certificate Sign, CRL Sign
X509v3 Basic Constraints: critical
CA:TRUE
X509v3 Subject Key Identifier:
59:...
X509v3 Authority Key Identifier:
keyid:59:...
X509v3 Subject Alternative Name:
DNS:consul.consul
Signature Algorithm: sha256WithRSAEncryption
1a:...
Configure the CA and CRL URLs:
vault write pki/config/urls \
issuing_certificates="http://127.0.0.1:8200/v1/pki/ca" \
crl_distribution_points="http://127.0.0.1:8200/v1/pki/crl"
Enable the PKI secrets engine at the pki_int
path:
vault secrets enable -path=pki_int pki
Tune the pki_int
secrets engine to issue certificates with a maximum time-to-live (TTL) of 43800 hours:
vault secrets tune -max-lease-ttl=43800h pki_int
Request an intermediate certificate signing request (CSR) and save request as pki_intermediate.csr
:
vault write -format=json pki_int/intermediate/generate/internal common_name="consul.consul Intermediate Authority" | jq -r '.data.csr' > pki_intermediate.csr
Sign the CSR and import the certificate into Vault:
vault write -format=json pki/root/sign-intermediate csr=@pki_intermediate.csr format=pem_bundle ttl="43800h" | jq -r '.data.certificate' > intermediate.cert.pem
Once the CSR is signed, and the root CA returns a certificate, it can be imported back into Vault:
vault write pki_int/intermediate/set-signed certificate=@intermediate.cert.pem
Create a Vault role - a logical name that maps to a policy used to generate credentials:
vault write pki_int/roles/consul-consul allowed_domains="consul.consul" allow_subdomains=true generate_lease=true max_ttl="720h"
Generate a Server Certificate
You can test the pki engine is configured correctly by generating your first certificate:
vault write pki_int/issue/consul-consul common_name="server.consul.consul" ttl="24h" | tee consul_certs.txt
The TTL for this certificate is being set to 24 hours, meaning that this certificate will be valid only for 24 hours.