Skip to main content

Hashicorp Consul - Vault Cert Management Part 1

Shen Zhen, China

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).

Generate mTLS Certificates using Vault

Prerequisites

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 datacenter consul.dc1. I use the name consul here and have to change the variable consul.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.

Configure Consul