Skip to content

Instantly share code, notes, and snippets.

@mojzu
Created January 5, 2022 20:20
Show Gist options
  • Star 7 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save mojzu/b093d79e73e7aa302dde8e335945b2cd to your computer and use it in GitHub Desktop.
Save mojzu/b093d79e73e7aa302dde8e335945b2cd to your computer and use it in GitHub Desktop.
MTLS with Caddy and step-ca

Example docker compose file

version: "3"
services:
  caddy:
    build:
      context: .
      dockerfile: service/caddy/dockerfile
    image: mojzu/dev-caddy:latest
    hostname: caddy
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - caddy_config:/config
      - caddy_data:/data
    restart: "unless-stopped"

  step-ca:
    image: smallstep/step-ca:latest
    hostname: step-ca
    ports:
      - "444:443"
    volumes:
      - step_ca:/home/step
      - ./private/pki:/pki
    restart: "unless-stopped"

  ... other services

volumes:
  caddy_config:
  caddy_data:
  step_ca:

Creating a CA

docker-compose run --rm step-ca bash
step ca init
# Follow instructions, DNS name is DOMAIN, bind address is :443
step ca provisioner add acme --type ACME
# Change ca-url in config/defaults.json to "https://DOMAIN:444" (the public port from docker-compose service)
# Change maxTLSCertDuration in config/ca.json to "8400h" (for client certificates)
# Copy certs/root_ca.crt and certs/intermediate_ca.crt for installing on client devices

Creating client certificates

step ca certificate --offline --not-after 8400h EMAIL --san EMAIL certs/NAME.crt secrets/NAME.key
step certificate p12 secrets/NAME.p12 certs/NAME.crt secrets/NAME.key --ca certs/root_ca.crt --ca certs/intermediate_ca.crt
step certificate inspect secrets/NAME.p12
# Copy certs/NAME.crt, secrets/NAME.key, secrets/NAME.p12 for installing on client devices

Install root and client certificates on devices/in browsers (depends on device/browser)

Caddy configuration file built into mojzu/dev-caddy image, root_ca.crt file copied to /pki/root_ca.crt

(acme_mtls) {
    tls EMAIL {
        ca https://DOMAIN:444/acme/acme/directory
        ca_root /pki/root_ca.crt
        client_auth {
            mode require_and_verify
            trusted_ca_cert_file /pki/root_ca.crt
        }
    }
}

SUBDOMAIN.DOMAIN {
    import acme_mtls
    reverse_proxy http://INTERNAL_SERVICE
}

... other subdomains
@dolmen
Copy link

dolmen commented Jan 6, 2022

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment