Set up mTLS
Set up mTLS with Pomerium
This guide covers how to generate and set up TLS certificates suitable for working with Pomerium.
Tools and resources:
- LetsEncrypt: a public CA that issues free certificates trusted by major browsers; other private or public CAs are also fine
- mkcert: a free tool for generating self-signed certificates ideal for testing purposes
- Google Domains: a domain name registrar you will use to set up your wildcard domain and certificate validation. You can use other registrars as well (some even support automatic renewal)
- Acme.sh: an Automated Certificate Management Environment (ACME) client you will use to fetch your wildcard certificate. Any LetsEncrypt client that supports wildcard domains would work.
There are countless ways to build and manage your public-key infrastructure. Although we hope this guide serves as a helpful baseline for generating and securing Pomerium with certificates, you should modify these instructions to meet your own organization's tools, needs, and constraints.
In a production environment you will likely use your corporate load balancer or a key management system to manage your certificate authority infrastructure.
Set up DNS
Set a CNAME record for the wildcard domain you will use with Pomerium.
Enable per-route TLS certificate automation
Pomerium can retrieve, manage, and renew certificates for you (for free) using LetsEncrypt. To enable certificate automation, you must allow public traffic on ports 80
and 443
.
To use Pomerium’s autocert configuration setting, set autocert
to true
in your configuration file:
autocert: true
See the Autocert and Autocert Directory settings for more information.
Generate a self-signed wildcard certificate
In production, you would use a public CA like LetsEncrypt to generate your wildcard certificate. For a local proof of concept or development, you can use mkcert to generate a locally-trusted, self-signed development certificate with any name you like.
For the purposes of this guide, create a wildcard certificate using the domain *.localhost.pomerium.io
, which we’ve pre-configured to route to localhost.
-
Install mkcert.
- Go
- Homebrew
go install filippo.io/mkcert@latest
brew install mkcert
-
Bootstrap mkcert's root certificate into your operating system's trust store.
mkcert -install
-
Create your wildcard domain.
*.localhost.pomerium.io
is a helper domain we've hard-coded to route to localhost:mkcert "*.localhost.pomerium.io"
Sign wildcard certificate
With your wildcard domain set at *.localhost.pomerium.io
, use acme.sh to create a certificate signing request with LetsEncrypt.
#!/bin/bash
# acme.sh : https://github.com/Neilpang/acme.sh
# curl https://get.acme.sh | sh
# NOTA BENE:
# if you use a DNS service that supports API access, you may be able to automate
# this process. See https://github.com/Neilpang/acme.sh/wiki/dnsapi
echo "=> first generate a certificate signing request!"
$HOME/.acme.sh/acme.sh \
--issue \
-k ec-256 \
-d '*.corp.example.com' \
--dns \
--yes-I-know-dns-manual-mode-enough-go-ahead-please
read -p "press any key once you've updated your TXT entries"
$HOME/.acme.sh/acme.sh \
--renew \
--ecc \
-k ec-256 \
-d '*.corp.example.com' \
--dns \
--yes-I-know-dns-manual-mode-enough-go-ahead-please
LetsEncrypt will respond with the corresponding TXT
record needed to verify your domain.
It may take a few minutes for the DNS records to propagate. Once they do, run the following command to complete the certificate request process:
acme.sh --signcsr --csr /path/to/mycsr/csr --dns dns_cf
Here's how the above certificates signed by LetsEncrypt correspond to their respective Pomerium configuration settings:
Pomerium Config | Certificate file |
---|---|
CERTIFICATE | $HOME/.acme.sh/*.corp.example.com_ecc/fullchain.cer |
CERTIFICATE_KEY | $HOME/.acme.sh/*.corp.example.com_ecc/*.corp.example.com.key |
Your end users will see a valid certificate for all domains delegated by Pomerium.
LetsEncrypt certificates must be renewed every 90 days.
Resources
Certificates, TLS, and Public Key Cryptography is a vast subject we cannot adequately cover here. If you are unfamiliar with these topics, the following resources may be helpful:
- Why HTTPS for Everything? The US government's CIO office has an excellent guide covering HTTPS and why future government sites will all be HTTPS.
- Is TLS Fast debunks the performance myth associated with HTTPS.
- Use TLS covers why TLS should be used everywhere; not just for securing typical internet traffic, but for securing service communication in both "trusted" and adversarial situations.
- Everything you should know about certificates and PKI but are too afraid to ask