Let's Encrypt DNS Token#
A towel is excellent preparation for interstellar travel, but it will not renew your server's certificate. We provide a small DNS key so your ACME client can do that job while your server stays on its private network.
What it does#
HTTP-01 requires Let's Encrypt to reach your server over HTTP from the internet, so it cannot validate a server accessible only on your private network.
DNS-01 proves control by writing a TXT value at _acme-challenge.<name> instead.
Let's Encrypt wildcard certificates also require DNS-01.
The token lets your ACME client manage challenge values for one chosen record.
Publish the record first#
- Open Domains > (domain name) > DNS.
- For a certificate for
wifi.ornek.com.tr, add a TXT record at_acme-challenge.wifi.ornek.com.trwith the value"vt-acme-placeholder". - If your company uses change management, complete the change request and wait for the record to be published. You only need to do this once.
The token can never delete this placeholder. Challenges come and go; the towel stays put.
Create a token#
- Go to Domains > (domain name) > DNS and click Token on the TXT row.
- Enter a label that identifies the server.
- Choose 90 days, 1 year, or 2 years, then create the token. You need
dns.managepermission. - Save it in a credentials file on your server that only the authorized user can read.
One appearance only
The token is shown once and cannot be retrieved after you close the dialog.
The list keeps only a hint such as vtacme_ab12…wxyz.
Replace vtacme_... below with your actual token.
With lego#
Use this command with lego v5 (verified with 5.5.2):
PDNS_API_URL=https://veriteknik.com/api/acme-dns \
PDNS_API_KEY=vtacme_... \
PDNS_TTL=120 \
lego run --accept-tos --email you@example.com --dns pdns -d wifi.ornek.com.tr
Earlier editions of the galaxy
lego v4 puts the subcommand last: lego --accept-tos --email you@example.com --dns pdns -d wifi.ornek.com.tr run.
Use the same PDNS_* environment variables.
Renew with the same lego run command and --renew-days 30.
This systemd example checks twice a day and assumes lego is installed at /usr/local/bin/lego.
Add --path /var/lib/lego to your initial issuance command too, so renewal uses the same account and certificate files.
-
Create
/etc/lego/acme-dns, owned byrootwith permissions0600:PDNS_API_URL=https://veriteknik.com/api/acme-dns PDNS_API_KEY=vtacme_... PDNS_TTL=120 -
Create
/etc/systemd/system/lego-renew.service:[Unit] Description=Renew ACME certificate [Service] Type=oneshot EnvironmentFile=/etc/lego/acme-dns ExecStart=/usr/local/bin/lego run --renew-days 30 --accept-tos --email you@example.com --dns pdns -d wifi.ornek.com.tr --path /var/lib/lego -
Create
/etc/systemd/system/lego-renew.timer:[Unit] Description=Check ACME certificate twice daily [Timer] OnCalendar=*-*-* 00,12:00:00 RandomizedDelaySec=3600 Persistent=true [Install] WantedBy=timers.target -
Run
sudo systemctl daemon-reloadandsudo systemctl enable --now lego-renew.timer.
Configure the application using the certificate to load the renewed files as well.
For lego v4, use lego --accept-tos --email you@example.com --dns pdns -d wifi.ornek.com.tr --path /var/lib/lego renew --days 30 in the service command, with the common options first and renew --days 30 last.
With acme.sh#
These settings were verified with acme.sh v3.1.6:
export PDNS_Url=https://veriteknik.com/api/acme-dns
export PDNS_ServerId=localhost
export PDNS_Token=vtacme_...
export PDNS_Ttl=60
acme.sh --issue --dns dns_pdns -d wifi.ornek.com.tr
Configure your account to use Let's Encrypt; add --server letsencrypt to the command if needed.
The cron job enabled during acme.sh installation handles renewal automatically; check that it is installed and configure certificate installation and application reloads.
Wildcard and apex together#
For ornek.com.tr and *.ornek.com.tr, publish _acme-challenge.ornek.com.tr and create a token for that record.
Use -d ornek.com.tr -d '*.ornek.com.tr' as the domain arguments.
Both challenges write to the same name, which is supported up to 10 ACME values per name.
A token created for wifi.ornek.com.tr cannot write the apex challenge record.
What if a token is stolen?#
A stolen token may let someone obtain certificates for its target name and *.name.
For example, the wifi.ornek.com.tr token can be used for certificates for wifi.ornek.com.tr and *.wifi.ornek.com.tr.
An attacker who can intercept traffic could use such a certificate to impersonate your server.
The token cannot write other names, record types, or zones, and cannot read the rest of the zone; it can only read its scoped TXT record.
Lock it down with CAA#
CAA is a DNS record that controls which certificate authority may issue a certificate.
Add these records at the target name, wifi.ornek.com.tr in this example:
wifi.ornek.com.tr. CAA 0 issue "letsencrypt.org; accounturi=https://acme-v02.api.letsencrypt.org/acme/acct/<account-number>; validationmethods=dns-01"
wifi.ornek.com.tr. CAA 0 issuewild "letsencrypt.org; accounturi=https://acme-v02.api.letsencrypt.org/acme/acct/<account-number>; validationmethods=dns-01"
- Find your Let's Encrypt account URL in the
urifield of lego'saccounts/.../account.json, or inACCOUNT_URLin the output of acme.sh's--register-account. - Replace the example account URL with your production account URL. Staging accounts have a different URL.
- Publish the records through the normal DNS workflow, including a change request if your company requires one.
This restriction requires the matching Let's Encrypt account key as well as the DNS token. CAA lookup walks up the DNS tree and uses the first record set it finds; placing the restriction at the zone apex could affect unrelated certificates your company obtains from other authorities.
Keep an eye on the galactic noticeboard
Track your domain's Certificate Transparency records at crt.sh and configure alerts with a CT monitoring service. An unexpected certificate deserves a closer look.
Rotate and revoke#
- Create a new token for the same record.
- Update the server configuration and verify that the new token works.
- Revoke the old token in the panel.
Expiry notices go to the creator and company members with dns.manage permission at 30 and 7 days before expiry.
A creator who has left the company no longer receives notices.
Revoked or expired tokens cannot renew certificates.
Troubleshooting#
| Symptom | What to check |
|---|---|
401 {"error":"Unauthorized"} |
The token may be incorrect, revoked, or expired; the domain may have moved to another account or its ownership may be ambiguous. Check the panel. |
422 rrset outside token scope: <name> <type> |
Match the command's -d argument to the token's target name. |
422 Only ACME challenge values (43-character base64url) can be written with this token: ... |
Use the ACME client instead of trying to add an arbitrary value manually. |
422 At most 10 ACME challenge values are allowed at this name |
Reduce the number of challenges at this name. |
429 Rate limit exceeded / Too many concurrent writes for this token |
Wait a few minutes and stop repeated or parallel attempts. |
404 Could not find domain '<zone>.' |
Check that the zone matches the token scope. The endpoint also returns 404 when the feature is disabled. |
| 403 | Requests with an Origin header are rejected; use the server's ACME client instead of a browser. |
| Let's Encrypt cannot see the record | Check DNS propagation; for lego, increase PDNS_PROPAGATION_TIMEOUT. |
One captain per name
Two servers renewing the same name at the same time can overwrite each other's challenge values. Assign one ACME client to each name.
The propagation check waits up to 25 seconds for ns1/ns2 and notify always returns 200; that response alone does not prove propagation succeeded. The client's own propagation check must complete too.