How to Use Let’s Encrypt DNS-01 with easyDNS

easyDNS customers can automate Let’s Encrypt certificate issuance and renewal using ACME DNS-01 validation. The easyDNS REST API allows supported ACME clients to create and remove the required _acme-challenge TXT records automatically, including for wildcard certificates.

This article is the hands-on companion to DNS-01 ACME Challenges with easyDNS, which explains how the challenge works and which software supports it. Here we configure the three most widely used ACME clients:

  • Certbot, with the certbot-dns-easydns plugin
  • acme.sh, with its native dns_easydns provider
  • lego, with its native easydns provider

All examples use example.com; substitute your own domain. None of the credential values shown are real.

Before you begin

You need:

  • A domain whose authoritative DNS is hosted at easyDNS. Check with dig NS example.com +short; the answer should be easyDNS nameservers (see easyDNS Nameservers).
  • easyDNS REST API credentials: a user token and an API key. These are issued from the easyDNS control panel under User → Security → easyDNS REST API. Refer to the easyDNS API documentation for the current signup and access process.
  • An ACME client (one of the three below) installed on a host that can reach both the Let’s Encrypt API and https://rest.easydns.net.
  • The credentials must belong to the easyDNS account that holds the zone, so that they have permission to modify its records.

The API endpoint for live zones is https://rest.easydns.net. Each client below needs that value plus the token and key.

Method 1: Certbot with certbot-dns-easydns

certbot-dns-easydns is the DNS authenticator plugin for Certbot, maintained by easyDNS and published on PyPI.

Install

Install the plugin into the same Python environment as Certbot. If Certbot itself was installed with pip:

pip install certbot certbot-dns-easydns

If Certbot was installed via snap, the plugin must be installed as a snap too, or Certbot will not see it. Where no easydns snap is available, install Certbot with pip (in a virtualenv) instead of snap. Confirm the plugin is visible with:

certbot plugins

The output should list dns-easydns.

Create the credentials file

Create an INI file readable only by root, for example /etc/letsencrypt/.secrets/easydns.ini:

dns_easydns_usertoken = your-easydns-user-token
dns_easydns_userkey   = your-easydns-api-key
dns_easydns_endpoint  = https://rest.easydns.net
sudo mkdir -p /etc/letsencrypt/.secrets
sudo chown root:root /etc/letsencrypt/.secrets /etc/letsencrypt/.secrets/easydns.ini
sudo chmod 700 /etc/letsencrypt/.secrets
sudo chmod 600 /etc/letsencrypt/.secrets/easydns.ini

Certbot will warn (and in some versions refuse to run) if the credentials file is readable by other users.

Request a certificate

sudo certbot certonly \
  --authenticator dns-easydns \
  --dns-easydns-credentials /etc/letsencrypt/.secrets/easydns.ini \
  --dns-easydns-propagation-seconds 120 \
  -d example.com \
  -d www.example.com

--dns-easydns-propagation-seconds is how long Certbot waits after creating the TXT record before asking Let’s Encrypt to validate. The plugin’s default is 120 seconds; if validation intermittently fails with “no TXT record found”, raise it (the plugin README suggests 600 or more for safety) rather than changing anything else.

Add --dry-run to test against the Let’s Encrypt staging environment first; it exercises the full DNS flow without consuming production rate limits.

Wildcard certificate

sudo certbot certonly \
  --authenticator dns-easydns \
  --dns-easydns-credentials /etc/letsencrypt/.secrets/easydns.ini \
  --dns-easydns-propagation-seconds 120 \
  -d example.com \
  -d '*.example.com'

Quote the wildcard so the shell does not expand it. This order validates two identifiers at _acme-challenge.example.com, so the plugin creates two TXT values there during issuance.

Renewal

Certbot records the authenticator and credentials path in the renewal configuration under /etc/letsencrypt/renewal/example.com.conf. The standard certbot renew (run by the systemd timer or cron job installed with Certbot) will repeat the DNS-01 flow automatically. Test it with:

sudo certbot renew --dry-run

Use --deploy-hook to reload the service that uses the certificate after a successful renewal, for example --deploy-hook "systemctl reload nginx".

Method 2: acme.sh

acme.sh ships with a native easyDNS provider, dns_easydns, so nothing extra needs to be installed.

Credentials

Export the token and key in the shell that runs acme.sh. On first use, acme.sh saves them to ~/.acme.sh/account.conf and reuses them for renewals, so the variables only need to be set once:

export EASYDNS_Token="your-easydns-user-token"
export EASYDNS_Key="your-easydns-api-key"

Note the mixed-case variable names; acme.sh is case-sensitive about them.

Request a certificate

acme.sh --issue --dns dns_easydns -d example.com -d www.example.com

acme.sh waits for the TXT record to be visible and then asks the CA to validate. If you need a longer wait, add --dnssleep 120 (seconds) to the command.

Wildcard certificate

acme.sh --issue --dns dns_easydns -d example.com -d '*.example.com'

Install and renew

acme.sh keeps certificates under ~/.acme.sh/ and installs a cron job that renews them automatically; renewals reuse the saved easyDNS credentials. Copy the certificate into place for your server with --install-cert so that renewals are deployed too:

acme.sh --install-cert -d example.com \
  --key-file       /etc/ssl/private/example.com.key \
  --fullchain-file /etc/ssl/certs/example.com.fullchain.pem \
  --reloadcmd      "systemctl reload nginx"

By default, current acme.sh versions use ZeroSSL as the CA. To use Let’s Encrypt, add --server letsencrypt to the --issue command, or set it as the default with acme.sh --set-default-ca --server letsencrypt.

Method 3: lego

lego is a Go ACME client and library with a native easydns provider. Because Traefik and a number of other tools embed lego, the same environment variables apply to them.

Credentials

export EASYDNS_TOKEN="your-easydns-user-token"
export EASYDNS_KEY="your-easydns-api-key"

Both variables are upper-case in lego (unlike acme.sh). Optional tuning variables, with their defaults:

Variable Purpose Default
EASYDNS_ENDPOINT API server URL; set to https://sandbox.rest.easydns.net to test against the sandbox live endpoint
EASYDNS_TTL TTL of the challenge TXT record 120
EASYDNS_POLLING_INTERVAL Seconds between DNS checks 2
EASYDNS_PROPAGATION_TIMEOUT Maximum seconds to wait for the record to be visible 60
EASYDNS_SEQUENCE_INTERVAL Seconds between sequential record operations 60
EASYDNS_HTTP_TIMEOUT API request timeout in seconds 30

Request a certificate

lego --email you@example.com --dns easydns -d example.com -d www.example.com run

Wildcard certificate

lego --email you@example.com --dns easydns -d '*.example.com' -d example.com run

Renewal

lego does not install a scheduler; run lego ... renew from cron or a systemd timer. It only renews when the certificate is within the --days threshold (default 30), so a daily run is safe:

lego --email you@example.com --dns easydns -d '*.example.com' -d example.com renew

Add --renew-hook "systemctl reload nginx" (or the equivalent for your service) to deploy the renewed certificate.

Verifying the challenge record yourself

While an issuance is in progress (or after one has failed), you can confirm what the CA sees. First check through your normal resolver:

dig TXT _acme-challenge.example.com +short

Then query one of the domain’s authoritative easyDNS nameservers directly, which is the view that matters for validation:

dig NS example.com +short
dig @<nameserver-from-previous-command> TXT _acme-challenge.example.com +short

A successful lookup returns one or more quoted strings, each a 43-character base64url token, for example:

"gfj9Xq...example-token-value...Rg85nM"

The exact value is generated by the CA for each challenge and changes on every issuance. If the record is present on the authoritative servers but the CA still reports failure, see the troubleshooting section of the DNS-01 overview. An empty answer from the authoritative server means the record was never created or has not been published yet; increase the client’s propagation wait and check the API credentials.

Automatic renewal

The point of ACME is that certificates renew without intervention. Once one of the methods above has worked once, the client should, on each renewal:

  1. request renewal from the CA;
  2. create the _acme-challenge TXT record via the easyDNS API;
  3. wait for the record to be visible from authoritative DNS;
  4. complete validation;
  5. obtain the renewed certificate;
  6. remove the temporary challenge record.

You should not need to create TXT records by hand for renewals. If you find yourself doing so, the saved credentials are missing or the renewal job is running in an environment where the environment variables or credentials file are not available (a common cause with cron, which runs with a minimal environment: use the credentials file approach, or set the variables inside the cron script).

Wildcard certificates with easyDNS

A wildcard certificate covers every single-label subdomain of a name: *.example.com matches www.example.com and api.example.com but not example.com itself, nor a.b.example.com. To cover the apex as well, request both names in the same certificate.

Let’s Encrypt issues wildcard names only through DNS-01, which is why the easyDNS API integration is required. All three clients covered here handle the two-TXT-value RRset that a combined apex + wildcard order produces:

# Certbot
sudo certbot certonly --authenticator dns-easydns \
  --dns-easydns-credentials /etc/letsencrypt/.secrets/easydns.ini \
  -d example.com -d '*.example.com'

# acme.sh
acme.sh --issue --dns dns_easydns -d example.com -d '*.example.com'

# lego
lego --email you@example.com --dns easydns -d example.com -d '*.example.com' run

Related easyDNS resources

Leave a Reply