Skip to main content

SSL/TLS Certificates & Encryption

Learn what SSL/TLS is, how it secures applications, and how Pomerium incorporates SSL/TLS to secure connections between its end-users, other Pomerium services, and your internal applications.

What are SSL/TLS certificates?

The Transport Layer Security (TLS) protocol, formerly known as the Secure Sockets Layer (SSL) protocol, is a cryptographic protocol that secures HTTP communications over a computer network.

Private key pairs

TLS relies on private and public key pairs to authenticate users or services, verify digital signatures, and encrypt and decrypt data.

SSL/TLS certificates

TLS certificates enable computer systems to verify your identity and encrypt communication over TLS.

Certificates are issued by a Certificate Authority (CA). The CA, which can be public or private, is a trusted entity that establishes digital identities.

The CA generates and signs a certificate (a digital object) that includes your public key, the certificate issuer, expiration and issuance dates, and other relevant metadata.

Both computer systems (servers and other backend services) and end-users rely on certificates to verify each other’s identity before exchanging information.

TLS Handshake

The TLS handshake is how a client and server verify each other’s identities, determine which cryptographic algorithms they will use to communicate securely over HTTP, and generate session keys to create new sessions.

During the TLS handshake, both parties use their public key for encryption and their private key for decryption. This gives both parties the opportunity to generate and exchange an agreed-upon shared key used to encrypt and decrypt communication in a session.

Mutual TLS (mTLS) authentication

Mutual TLS (mTLS), or mutual authentication, means that both the client and server verify each other’s identities.

mTLS makes it possible to verify end-users, devices, and servers within an organization, which is a core principle for organizations that are serious about implementing a zero- trust security model.

Why Pomerium uses mTLS

Since one of Pomerium's core principles is to treat internal and external traffic impartially, Pomerium uses mutually authenticated TLS ubiquitously.

This enables Pomerium to secure connections between:

  • The end-user and Pomerium
  • Pomerium services (even if the network is trusted)
  • Pomerium and the destination application

Securing all communication with mTLS bolsters security and can help prevent attacks like:

  • Spoofing
  • Credential stuffing
  • Brute force attacks
  • On-path attacks
  • Malicious API attacks

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: