Overview
The ACME protocol (used by Let's Encrypt and other certificate authorities) supports the DNS-01 challenge for domain validation. DNS-01 is the only challenge type that supports wildcard certificates (*.example.com), and it does not require an HTTP server on the target machine.
NexDNS provides native integrations with three popular ACME clients, as well as a generic CLI hook for any client that supports manual DNS hooks.
All ACME integrations require an API token with
records.readandrecords.writepermissions. Create one at nexdns.tech/settings/api-keys.
acme.sh
acme.sh is a pure shell ACME client. NexDNS is supported as a built-in DNS API provider.
Issue a Certificate
export NEXDNS_Token="nxd_xxxxxxxxxxxxxxxxxxxx"
acme.sh --issue --dns dns_nexdns -d example.com -d '*.example.com'
The token is saved to ~/.acme.sh/account.conf after the first run, so you do not need to export it again for renewals.
Renew
Renewals happen automatically via cron. To force a manual renewal:
acme.sh --renew -d example.com
lego / Traefik
lego is a Go-based ACME client that also powers Traefik’s automatic certificate management. NexDNS is supported as a DNS provider.
Standalone Usage
NEXDNS_API_TOKEN=nxd_xxx \
lego --dns nexdns \
--domains example.com \
--domains '*.example.com' \
--email admin@example.com \
run
Traefik Configuration
Add the NexDNS DNS challenge resolver to your Traefik configuration. The following docker-compose.yml example shows a typical setup:
services:
traefik:
image: traefik:v3
command:
- "--certificatesresolvers.nexdns.acme.dnschallenge=true"
- "--certificatesresolvers.nexdns.acme.dnschallenge.provider=nexdns"
- "--certificatesresolvers.nexdns.acme.email=admin@example.com"
- "--certificatesresolvers.nexdns.acme.storage=/letsencrypt/acme.json"
environment:
NEXDNS_API_TOKEN: "nxd_xxxxxxxxxxxxxxxxxxxx"
volumes:
- letsencrypt:/letsencrypt
- /var/run/docker.sock:/var/run/docker.sock:ro
ports:
- "443:443"
volumes:
letsencrypt:
Then use the resolver in your service labels:
labels:
- "traefik.http.routers.myapp.tls.certresolver=nexdns"
- "traefik.http.routers.myapp.tls.domains[0].main=example.com"
- "traefik.http.routers.myapp.tls.domains[0].sans=*.example.com"
certbot
certbot is the official Let's Encrypt client. Use the NexDNS DNS authenticator plugin for automated DNS-01 validation.
Install the Plugin
pip install certbot-dns-nexdns
Create Credentials File
Create ~/.nexdns/certbot-credentials.ini with your API token:
dns_nexdns_token = nxd_xxxxxxxxxxxxxxxxxxxx
Restrict file permissions:
chmod 600 ~/.nexdns/certbot-credentials.ini
Issue a Certificate
certbot certonly \
--authenticator dns-nexdns \
--dns-nexdns-credentials ~/.nexdns/certbot-credentials.ini \
-d '*.example.com'
Docker Usage
docker run --rm \
-v /etc/letsencrypt:/etc/letsencrypt \
-v ~/.nexdns/certbot-credentials.ini:/credentials.ini:ro \
certbot/dns-nexdns certonly \
--authenticator dns-nexdns \
--dns-nexdns-credentials /credentials.ini \
-d '*.example.com'
CLI Hook
If your ACME client supports manual DNS hooks, you can use the NexDNS CLI as a hook script. This works with any client that provides --manual-auth-hook and --manual-cleanup-hook options (e.g. certbot in manual mode).
certbot with CLI Hook
certbot certonly --manual --preferred-challenges dns \
--manual-auth-hook "nexdns acme hook --action create" \
--manual-cleanup-hook "nexdns acme hook --action delete" \
-d '*.example.com'
The hook reads the CERTBOT_DOMAIN and CERTBOT_VALIDATION environment variables set by certbot and creates or removes the _acme-challenge TXT record automatically.
The CLI must be authenticated before using hooks. Run
nexdns auth token nxd_xxxor set theNEXDNS_TOKENenvironment variable.