Skip to main content

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

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.

Certificate wildcard domain

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.

  1. Install mkcert.

    go install filippo.io/mkcert@latest
  2. Bootstrap mkcert's root certificate into your operating system's trust store.

    mkcert -install
  3. 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.

pomerium add a text entry to your dns records

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

pomerium valid certificate

pomerium certificates A+ ssl labs rating

caution

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: