HashiCorp Vault as a Certificate Authority (CA) / Vault PKI

PKI (Public Key Infrastructure, public key infrastructure) – a set of tools, distributed services and components, together used to support cryptographic tasks based on private and public keys.

In the previous article, we covered installing HashiCorp Vault on Centos 8 and using PostgreSQL as storage for HashiCorp Vault

Training

Installing the jq utility into the system

$ sudo dnf -y install jq

PKI setup

Logging into the Vault

$ vault login

Activating PKI secret type for root certification authority

$ vault secrets enable 
    -path=pki_root_ca 
    -description="PKI Root CA" 
    -max-lease-ttl="262800h" 
    pki

Create a root certification authority (CA). 262800h = 30 years

$ vault write -format=json pki_root_ca/root/generate/internal 
    common_name="Root Certificate Authority" 
    country="Russian Federation" 
    locality="Moscow" 
    street_address="Red Square 1" 
    postal_code="101000" 
    organization="Horns and Hooves LLC" 
    ou="IT" 
    ttl="262800h" > pki-root-ca.json

We save the root certificate. In the future, it is it that must be distributed in the organization and made trusted.

$ cat pki-root-ca.json | jq -r .data.certificate > rootCA.pem

Publishing URLs for the root CA

$ vault write pki_root_ca/config/urls 
    issuing_certificates="http://vault.example.com:8200/v1/pki_root_ca/ca" 
    crl_distribution_points="http://vault.example.com:8200/v1/pki_root_ca/crl"

Activating PKI secret type for intermediate certification authority

$ vault secrets enable 
    -path=pki_int_ca 
    -description="PKI Intermediate CA" 
    -max-lease-ttl="175200h" 
    pki

Generating a certificate issuance request for an intermediate certification authority

$ vault write -format=json pki_int_ca/intermediate/generate/internal 
   common_name="Intermediate CA" 
   country="Russian Federation" 
   locality="Moscow" 
   street_address="Red Square 1" 
   postal_code="101000" 
   organization="Horns and Hooves LLC" 
   ou="IT" 
   ttl="175200h" | jq -r '.data.csr' > pki_intermediate_ca.csr

We send the received CSR file to the root certification authority, get a certificate for the intermediate certification authority. 175200h = 20 years

$ vault write -format=json pki_root_ca/root/sign-intermediate [email protected]_intermediate_ca.csr 
   country="Russia Federation" 
   locality="Moscow" 
   street_address="Red Square 1" 
   postal_code="101000" 
   organization="Horns and Hooves LLC" 
   ou="IT" 
   format=pem_bundle 
   ttl="175200h" | jq -r '.data.certificate' > intermediateCA.cert.pem

We publish the signed certificate of the intermediate certification authority

$ vault write pki_int_ca/intermediate/set-signed 
    [email protected]

Publishing URLs for an intermediate certification authority

$ vault write pki_int_ca/config/urls 
    issuing_certificates="http://vault.example.com:8200/v1/pki_int_ca/ca" 
    crl_distribution_points="http://vault.example.com:8200/v1/pki_int_ca/crl"

We create a role with which we will issue certificates for servers

$ vault write pki_int_ca/roles/example-dot-com-server 
    country="Russia Federation" 
    locality="Moscow" 
    street_address="Red Square 1" 
    postal_code="101000" 
    organization="Horns and Hooves LLC" 
    ou="IT" 
    allowed_domains="example.com" 
    allow_subdomains=true 
    max_ttl="87600h" 
    key_bits="2048" 
    key_type="rsa" 
    allow_any_name=false 
    allow_bare_domains=false 
    allow_glob_domain=false 
    allow_ip_sans=true 
    allow_localhost=false 
    client_flag=false 
    server_flag=true 
    enforce_hostnames=true 
    key_usage="DigitalSignature,KeyEncipherment" 
    ext_key_usage="ServerAuth" 
    require_cn=true

We create a role with which we will issue certificates for clients

$ vault write pki_int_ca/roles/example-dot-com-client 
    country="Russia Federation" 
    locality="Moscow" 
    street_address="Red Square 1" 
    postal_code="101000" 
    organization="Horns and Hooves LLC" 
    ou="IT" 
    allow_subdomains=true 
    max_ttl="87600h" 
    key_bits="2048" 
    key_type="rsa" 
    allow_any_name=true 
    allow_bare_domains=false 
    allow_glob_domain=false 
    allow_ip_sans=false 
    allow_localhost=false 
    client_flag=true 
    server_flag=false 
    enforce_hostnames=false 
    key_usage="DigitalSignature" 
    ext_key_usage="ClientAuth" 
    require_cn=true

Create a 5-year certificate for the vault.example.com domain

$ vault write -format=json pki_int_ca/issue/example-dot-com-server 
    common_name="vault.example.com" 
    alt_names="vault.example.com" 
    ttl="43800h" > vault.example.com.crt

We save the certificate in the correct format

$ cat vault.example.com.crt | jq -r .data.certificate > vault.example.com.crt.pem
$ cat vault.example.com.crt | jq -r .data.issuing_ca >> vault.example.com.crt.pem
$ cat vault.example.com.crt | jq -r .data.private_key > vault.example.com.crt.key

We work with certificates

View the list of certificates

$ vault list pki_int_ca/certs

Read certificate (output content)

$ vault read pki_int_ca/cert/<serial number>

Revoke certificate

$ vault write pki_int_ca/revoke serial_number=<serial number>

Clear expired / revoked certificates

$ vault write pki_int_ca/tidy 
    safety_buffer=5s 
    tidy_cert_store=true 
    tidy_revocation_list=true

Bash script

For ease of deployment, PKI has prepared a bash script

github

Sidebar