Run manual-auth-hook script only once


#1

Hello,
today I wanted to create a certificate for my duckdns.org domain and also a wildcard certificate for all subdomains.
So far everything works fine and I used a script as a manual-auth-hook to add the TXT-record to my domain.
When creating a certificate for just one domain everything is fine but DuckDNS does something weird. It uses the same TX-record for all its subdomains. which means that I would only need to add 1 record but since I have two domains in my command I get two TXT-records that I would need to add?
And somehow that throws everything off.

When I just run the command a few times it actually works but when I try to renew the certs I get to the same problem.
It works after some trys but that’s basically luck. And when I automate the renewal I don’t want to run the command multiple times until I get the correct return…

My domain is: runnerlights.duckdns.org

I ran this command:

sudo certbot --server https://acme-v02.api.letsencrypt.org/directory -d *.runnerlights.duckdns.org -d runnerlights.duckdns.org --manual --manual-auth-hook /home/homeassistant/Scripts/DuckDNS-TXT/addtxt.sh --preferred-challenges dns-01 certonly

sudo certbot --dry-run renew

It produced this output:

Saving debug log to /var/letsencrypt/log/letsencrypt.log
Plugins selected: Authenticator manual, Installer None
Obtaining a new certificate
Performing the following challenges:
dns-01 challenge for runnerlights.duckdns.org
dns-01 challenge for runnerlights.duckdns.org


NOTE: The IP of this machine will be publicly logged as having requested this
certificate. If you’re running certbot in manual mode on a machine that is not
your server, please ensure you’re okay with that.

Are you OK with your IP being logged?


(Y)es/(N)o: y
Output from LetsEncrypt_DuckDNS_update.sh:
OK
QzrWPGpwsyCQgDLwMOZUJxHWETWBCnzIOMZT7GIHTDw
UPDATED
Output from LetsEncrypt_DuckDNS_update.sh:
OK
IIw4pkAc3AO-lCrnvvaWL-kIzKvce_ub7r-L0JgjfNM
UPDATED
Waiting for verification…
Cleaning up challenges
Failed authorization procedure. runnerlights.duckdns.org (dns-01): urn:ietf:params:acme:error:unauthorized :: The client lac ks sufficient authorization :: Incorrect TXT record “IIw4pkAc3AO-lCrnvvaWL-kIzKvce_ub7r-L0JgjfNM” found at _acme-challenge.r unnerlights.duckdns.org

IMPORTANT NOTES:

  • The following errors were reported by the server:

    Domain: runnerlights.duckdns.org
    Type: unauthorized
    Detail: Incorrect TXT record
    “IIw4pkAc3AO-lCrnvvaWL-kIzKvce_ub7r-L0JgjfNM” found at
    _acme-challenge.runnerlights.duckdns.org

    To fix these errors, please make sure that your domain name was
    entered correctly and the DNS A/AAAA record(s) for that domain
    contain(s) the right IP address.

My web server is (include version):
A Raspberry Pi

The operating system my web server runs on is (include version):
Raspbian Stretch with Kernel 4.14

My hosting provider, if applicable, is:
the DNS hosting is provoíded by duckdns.org

I can login to a root shell on my machine (yes or no, or I don’t know):
yes

I’m using a control panel to manage my site (no, or provide the name and version of the control panel):
No


#2

I don’t know much about DuckDNS, but from the LE side, you do indeed need to validate both records. On most DNS providers, you can add two TXT records for the same FQDN (e.g. two distinct records for _acme-challenge.runnerlights.duckdns.org) without issue, and both would be returned by a DNS TXT query for the same name. LE is smart enough to check that at least one of the returned values matches. Do you know if the issue is that DuckDNS is replacing them instead? That would be a problem and lead to race conditions (as you’ve seen) on the validation step.


#3

acme.sh appears to natively support DuckDNS, you might want to try it or look to it as inspiraiton to work around the weird TXT subdomain behavior.


#4

If you can process the certs independently and also use them independently, you may be able to split them into two separate sequential requests.


#5

The duckdns.org API is really limited — it does not support creating multiple TXT records (in fact, only a single TXT value can be specified, which is then returned for any sub-subdomain under your example.duckdns.org subdomain). Because of this, validating a certificate request which contains multiple names under the same example.duckdns.org domain (including *.example.duckdns.org with example.duckdns.org) will never be possible in a single attempt if using dns-01 for all names.

Your options are:

  1. Just try requesting the certificate multiple times until it succeeds; this can work because successful validations are remembered by the Let’s Encrypt server for some time, therefore on subsequent attempts with the same ACME account the client won’t need to validate names which have been validated on previous attempts.

  2. If you can use the http-01 validation method, you can try to find a client which can use multiple validation methods for a single certificate request (the ACME protocol allows this, but I’m not sure that such clients actually exist); then you can configure that client to validate example.duckdns.org via http-01.

  3. Request separate certificates for example.duckdns.org and *.example.duckdns.org, then use those certificates with SNI (this might be difficult or even impossible with some software, especially if you need those certificates to work on non-HTTPS servers).

  4. Request a separate certificate for example.duckdns.org which you won’t actually use, then request a certificate for both example.duckdns.org and *.example.duckdns.org. You need to be sure that the ACME client actually tries to request those certificates in the specified order (not sure whether certbot can do this, but, e.g., dehydrated processes certificates in the order they are listed in domains.txt). The first certificate request causes the validation for example.duckdns.org to be remembered by the Let’s Encrypt server, then the second certificate request will require only a single validation for *.example.duckdns.org. Remember that the additional certificate will count against the rate limit.


#6

It also depends on what order of operations the ACME client uses when validating multiple names. If it set up and validated one challenge at a time, that would work.

(Certbot sets up all the challenges, validates all of them, and then deletes all of them.)

acme.sh fully supports this.

(Certbot fully supports using multiple validation methods for one certificate, but only one plugin. Since there aren’t plugins that support both DNS and HTTP or TLS validation, that’s not enough here.)