Manage certificates with ACME clients and the PKI secrets engine
HTTPS with TLS is the defacto standard for all web traffic today and production use cases require this level of security at a minimum.
Challenge
Provisioning and maintaining TLS certificate lifecycle for a large number of use cases presents a considerable operational burden. Manually maintaining certificate lifecycle also introduces issues which can result in downtime if certificates are not properly provisioned or renewed on time.
Solution
Starting with version 1.14.0, the Vault PKI secrets engine supports the Automatic Certificate Management Environment (ACME) specification for issuing and renewing leaf server certificates.
You can use ACME-compliant clients with Vault to help automate the leaf server certificate lifecycle.
The hands-on lab scenario presented here uses the Caddy web server's automatic HTTPS functionality with Vault as its ACME server.
Scenario introduction
You'll learn about the PKI secrets engine ACME functionality by deploying and configuring a Caddy web server and a Vault server. First, you'll observe behavior of the Caddy server when not configured to use automatic HTTPS. Then, you'll enable ACME support in a PKI secrets engine instance and configure Caddy to use Vault as its ACME server to enable automatic HTTPS. After configuring the Caddy server, you'll explore the behavior with requests to the Caddy server.
Personas
The end-to-end scenario described in this tutorial involves two personas:
admin
with privileged permissions to enable and configure Vault and Caddy.user
makes requests to Caddy.
Prerequisites
Vault CLI installed and in your system PATH.
curl CLI installed and in your system PATH.
Docker installed.
jq installed and in your system PATH for parsing JSON responses.
Versions used for this tutorial
This tutorial was last tested 15 Jun 2023 on macOS using the following software versions.
Launch Terminal
This tutorial includes a free interactive command-line lab that lets you follow along on actual cloud infrastructure.
Lab setup
This hands-on lab uses a Docker container environment consisting of a Vault development mode server container and a Caddy web server container.
Create hands-on lab home
You can create a temporary directory to hold all the content needed for this hands-on lab and then assign its path to an environment variable for later reference.
Open a terminal, and create the directory
/tmp/learn-vault-pki
.Export the hands-on directory path as the value to the
HC_LEARN_LAB
environment variable.Create a
learn-vault
Docker network.
Deploy HTTP Caddy container
Your goal for this section is to pull the Caddy server image and deploy an HTTP based container so that you can explore the server in its most basic configuration.
Pull the latest Caddy server container image.
Example expected output:
Create directories for Caddy configuration and data.
Create a simplified
index.html
file in the hands-on lab home directory.Start the Caddy server container.
Confirm that the Caddy server container is up.
Example expected output:
The Caddy server container was configured to publish the HTTP port to localhost. Use
curl
to make an HTTP request to the Caddy server.Example expected output:
Your HTTP request was successful and the response includes hello world.
You have not yet configured the Caddy server to use its automatic HTTPS feature, so an HTTPS request is expected to fail. Try an HTTPS request to observe the result.
Example expected output:
Now that you've explored the Caddy server behavior without HTTPS, go ahead and stop the Caddy container and proceed to deploying the Vault container.
Deploy Vault container
Your goal for this section is to deploy a dev mode Vault server container that you'll use for the hands-on lab.
Note
The dev mode server does not support TLS for non-loopback addresses, and is used without TLS just for this tutorial. Vault should always be used with TLS in production deployments. This configuration requires a certificate file and key file on each Vault host.
Pull the latest Vault Docker image.
Example abbreviated output:
Start Vault server container.
Note
The dev mode server uses an initial root token value that is the literal string
root
. This is used just for the purposes simplifying steps in the tutorial.Confirm that the Vault server container is up.
Example expected output:
Export an environment variable for the
vault
CLI to address the Vault server.Verify Vault server status.
Example expected output:
Authenticate to Vault with the initial root token.
The Vault server is now ready for you to enable and configure the PKI secrets engine.
Enable PKI secrets engine
Your goal for this section is to enable PKI infrastructure consisting of 2 PKI secrets engine instances representing a root CA (pki) and intermediate CA (pki_int) for the learn.internal
domain.
This configuration is based on steps like those in the Build Your Own Certificate Authority (CA) tutorial. You are encouraged to complete the hands-on lab in that tutorial if you are unfamiliar with the PKI secrets engine.
To save time and typing, you can use this example shell script to enable and configure the secrets engines for the hands-on lab.
Use a text editor to write and save this content to the file
$HC_LEARN_LAB/pki/enable_engines.sh
. You may need to first create the pki folder.enable_engines.shNote
The values used here are for just the hands-on lab. You should change the values of
common_name
,issuer_name
,path
, andaia_path
to match your own values when using these commands outside of the context of the hands-on lab.Make the script executable.
Execute the script to enable and configure the secrets engines from within the
pki
folder.Abbreviated expected output:
List the enabled PKI secrets engines.
Example expected output:
The PKI secrets engines are enabled with a basic configuration.
Configure ACME
Now that you've set up a basic PKI infrastructure, you can enable and configure ACME on the intermediate CA mounted at pki_int
with 2 additional steps.
Ensure that the
config/cluster
configuration is present and correct, or ACME won't work.Example expected output:
Note
This configuration must be set on all clusters participating in Enterprise Performance Replication.
Tune the intermediate CA PKI mount at
pki_int
to enable the ACME required headers.Example expected output:
Then, enable ACME functionality on the intermediate CA.
Example expected output:
You have enabled and configured ACME on the PKI secrets engine intermediate CA.
Redeploy Caddy container with HTTPS
Your goal for this section is to deploy a Caddy server container configured to use its automatic HTTPS feature to fetch and use its TLS certificate from Vault.
Caddy is a stateful server and stores its state in
$HC_LEARN_LAB/caddy_data/caddy
; remove the earlier Caddy server's state.Create a Caddyfile to configure the Caddy server. It specifies that Caddy listens on TCP port 443, sets a content root, enables the basic static file server, and defines the Vault server as its ACME CA.
EOF
Confirm that the Caddy server container is up.
Example expected output:
Make an HTTPS request to Caddy
You can now try a request to the HTTPS enabled Caddy server with curl
. You'll need to specify the root CA certificate so that curl
can validate the certificate chain.
Example expected output:
A successful response indicates that Caddy is now using automatic HTTPS with Vault as its ACME CA.
If you get errors such as SSL routines:ST_CONNECT:tlsv1 alert internal error
check that the host name used to test connectivity (in these examples caddy-server
) and the certificate's common name or subject alternative names are an exact match. If you are using openssl s_client
, specify the -servername
option to send the Server Name Indication (SNI) extension matching the domain name on the certificate.
Cleanup
In a terminal session, stop the Caddy server; the container is automatically removed by Docker.
Stop the Vault server; the container is automatically removed by Docker.
Remove the Docker network.
Change to your home directory.
Remove the hands-on lab temporary directory.
Summary
You've learned how to configure the PKI secrets engine to enable ACME, and manage the lifecycle of a Caddy server TLS certificate with Vault.
Next steps
Now that you have an understanding of the basics around ACME with the PKI Secrets engine, you are encouraged to review the Automate Rotation with ACME section of the API documentation. This section contains important notes and caveats, which you should fully understand before implementing ACME with Vault in your use case.
You can also continue your PKI secrets engine learning journey by exploring the Build Certificate Authority (CA) in Vault with an offline Root and PKI Unified CRL and OCSP With Cross Cluster Revocation tutorials.