Files
dns-wildcard-cert/README.md
Chris d46b0664d3
All checks were successful
Build Container / docker (push) Successful in 19m18s
init
2026-01-03 20:00:52 +01:00

4.7 KiB

DNS Wildcard Certificate Generator

A Docker container for easily obtaining wildcard SSL certificates from Let's Encrypt using the certbot-dns-standalone plugin.

How It Works

This uses the dns-standalone authenticator which runs its own DNS server to respond to ACME DNS-01 challenges. You need to configure your DNS to delegate _acme-challenge queries to this container.

Prerequisites

  1. A server with port 53 (DNS) available
  2. DNS configuration to route challenge queries to your server (see DNS Setup below)

DNS Setup

Option 1: Direct NS Record

Point _acme-challenge records to your certbot server using CNAME and NS records:

; For acme.example.com as your certbot endpoint
acme     IN  NS  ns.acme.example.com.
ns.acme  IN  A   1.2.3.4

; For each domain you want certificates for
_acme-challenge.example.com  IN  CNAME  example.com.acme.example.com.

Where 1.2.3.4 is the IP of the server running this container.

Option 2: DNS Proxy/Forwarding

If you already run a DNS server, configure it to forward _acme-challenge queries to the container.

Usage

Quick Start

docker run -it --rm \
  -v "/etc/letsencrypt:/etc/letsencrypt" \
  -v "/var/lib/letsencrypt:/var/lib/letsencrypt" \
  -p 53:53/tcp -p 53:53/udp \
  -e EMAIL="youremail@example.com" \
  -e DOMAINS="-d example.com -d *.example.com" \
  dns-wildcard-cert

Build Locally

docker build -t dns-wildcard-cert .

Environment Variables

Variable Required Default Description
EMAIL Yes - Email for Let's Encrypt registration
DOMAINS Yes - Domain flags (e.g., -d example.com -d *.example.com)
DNS_ADDRESS No 0.0.0.0 IPv4 address to bind DNS server
DNS_IPV6_ADDRESS No :: IPv6 address to bind DNS server
DNS_PORT No 53 Port for DNS server
STAGING No false Use Let's Encrypt staging server (for testing)
DRY_RUN No false Perform a dry run without saving certificates

Examples

Test with staging server first:

docker run -it --rm \
  -v "/etc/letsencrypt:/etc/letsencrypt" \
  -v "/var/lib/letsencrypt:/var/lib/letsencrypt" \
  -p 53:53/tcp -p 53:53/udp \
  -e EMAIL="youremail@example.com" \
  -e DOMAINS="-d example.com -d *.example.com" \
  -e STAGING="true" \
  dns-wildcard-cert

Dry run (no certificates saved):

docker run -it --rm \
  -p 53:53/tcp -p 53:53/udp \
  -e EMAIL="youremail@example.com" \
  -e DOMAINS="-d example.com -d *.example.com" \
  -e DRY_RUN="true" \
  dns-wildcard-cert

Bind to specific IP:

docker run -it --rm \
  -v "/etc/letsencrypt:/etc/letsencrypt" \
  -v "/var/lib/letsencrypt:/var/lib/letsencrypt" \
  -p 1.2.3.4:53:53/tcp -p 1.2.3.4:53:53/udp \
  -e EMAIL="youremail@example.com" \
  -e DOMAINS="-d example.com -d *.example.com" \
  -e DNS_ADDRESS="0.0.0.0" \
  dns-wildcard-cert

Use non-standard port (with DNS forwarding):

docker run -it --rm \
  -v "/etc/letsencrypt:/etc/letsencrypt" \
  -v "/var/lib/letsencrypt:/var/lib/letsencrypt" \
  -p 5555:5555/tcp -p 5555:5555/udp \
  -e EMAIL="youremail@example.com" \
  -e DOMAINS="-d example.com -d *.example.com" \
  -e DNS_PORT="5555" \
  dns-wildcard-cert

Certificate Renewal

For renewal, you can run the same container periodically or use certbot's renew command:

docker run -it --rm \
  -v "/etc/letsencrypt:/etc/letsencrypt" \
  -v "/var/lib/letsencrypt:/var/lib/letsencrypt" \
  -p 53:53/tcp -p 53:53/udp \
  --entrypoint certbot \
  dns-wildcard-cert renew

Certificate Location

Certificates are stored in the /etc/letsencrypt volume:

  • Certificate: /etc/letsencrypt/live/<domain>/fullchain.pem
  • Private Key: /etc/letsencrypt/live/<domain>/privkey.pem

Docker Compose

version: '3.8'

services:
  certbot:
    build: .
    ports:
      - "53:53/tcp"
      - "53:53/udp"
    environment:
      - EMAIL=youremail@example.com
      - DOMAINS=-d example.com -d *.example.com
      - STAGING=false
    volumes:
      - letsencrypt:/etc/letsencrypt
      - letsencrypt-lib:/var/lib/letsencrypt

volumes:
  letsencrypt:
  letsencrypt-lib:

Parameter Changes

Note: The old certbot-dns-standalone parameter format has changed:

Old Format New Format
--authenticator certbot-dns-standalone:dns-standalone --authenticator dns-standalone
--certbot-dns-standalone:dns-standalone-address= --dns-standalone-address=
--certbot-dns-standalone:dns-standalone-ipv6-address= --dns-standalone-ipv6-address=
--certbot-dns-standalone:dns-standalone-port= --dns-standalone-port=

License

MIT