DNS-01 Clarification on renewal process

Please fill out the fields below so we can help you better. Note: you must provide your domain name to get help. Domain names for issued certificates are all made public in Certificate Transparency logs (e.g. crt.sh | example.com), so withholding your domain name here does not increase secrecy, but only makes it harder for us to provide help.

My domain is: wozsites.com.au (but also various others)

I ran this command: certbot renew --preferred-challend dns-rcf2136 -d wozsites.com.au

It produced this output: Haven't done it yet, I just have a question

My web server is (include version): Nginx 1.22.0

The operating system my web server runs on is (include version) Almalinux 8.6:

My hosting provider, if applicable, is: I am, me and my two pet rabbits

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): Nope, all done with text files and nano.

The version of my client is (e.g. output of certbot --version or certbot-auto --version if you're using Certbot): 1.22.0

Yesterday I used DNS to verify the domains and that worked fine. The _acme-challenge TXT record has been done without issue.

The question I have is about renewal in a few months time. Will the existing _acme-challenge remain the same or will a new one be used. Does the challenge text change at every renewal?

Thanks in advance.


1 Like

Yes, the value of the _acme-challenge.(domain) TXT record changes.

One quirk ... successful validations are cached for 30 days from initial validation. So, you may have the illusion the value did not have to change if you tried again right now but that's just due to this cache.


Thanks @MikeMcQ

I had a sneaking suspicion it might change each time and will now have to figure out how to automate it. Previously I've stopped my Nginx process, run renew (which was done via http) and restarted Nginx.

I look forward to hours of screwing around with it. At least I have a few months to figure it out.

Thanks again for your fast responce.



Various ways to automate DNS challenge.

But, why not just use HTTP challenge and keep nginx running. You only need DNS challenge for wildcards and I don't see any in your cert history (at crt.sh).

If you don't like the idea of certbot nginx plug-in modifying your nginx conf you can use http webroot authentication. Like:

sudo certbot certonly --webroot -w (nginx root value for domain) -d (domain1) -d (domain2) --deploy-hook (command to reload nginx)

I will look into the webroot option. My understanding, which is limited, is that certbot needs to be listening on port 80. That is why I stop Nginx, run 'certbot renew' and then start Nginx. I don't want it screwing with my config files but if there is a way to get around that and not stop Nginx I'd be ok with it.


Ah, only if you choose the standalone method which is for rare situations.

Otherwise, an HTTP challenge can use your existing, running, web server to satisfy the challenge. The webroot example is briefly like:

  1. certbot makes magic file under -w (webroot path) folder
  2. certbot tells Let's Encrypt server what to look for
  3. LE Server makes http request for that magic file
  4. if certbot learns from LE server it worked, then cert is retrieved and magic file removed
  5. For nginx, only a reload is needed for it to pickup the new cert.

Hopefully clarity was not lost with brevity :slight_smile:

You can try webroot in test mode just adding --dry-run to the command example I showed above


Ok, I see where there might be a problem.

I have half a dozen domains, all of which are on different linux servers. Nginx is configured as a reverse proxy cache and receives traffic on port 80 or 443 and then passes it to an appropriate IP Address within my network. Certbot has no access to each of those servers and neither does the internet directly.

What you have suggested would work fine if there were any actual domains on the Nginx box.

I also have a different server dedicated to DNS, which I guess is why I originally tried that path because all domains DNS requests are answered by a single server.

Does that make sense or am I confusing things for myself. :slight_smile:

Webroot should work in that scenario. nginx is terminating the ssl connection (port 443) so needs a cert for that. As long as that nginx can respond to port 80 requests it can satisfy the http challenge.

Are you also doing https within your network to the backend servers? If so, do those use certs from a public CA or just self-signed certs? On a private secure network often just http is used.

I am imagining an nginx (in pseudo-code) like this. Close enough?

   listen 80;
   server_name domain1;
   redirect to https://domain1
   listen 443 ssl;
   server_name domain1;
   proxy_pass backend1;
   sslcert defs

(repeat above for other domains)


Yes, you have it exactly right. All port 80 for domains is redirected to 443 and passed to different backends.

All certificates are on the Nginx box, but now as I think about it I guess I could configure a local folder for each domain and Nginx could serve it. Hmm, I'm now thinking about it more.

You could make your port 80 look more like this. This would process the http challenge right in http block and redirect all else. I might have some minor typos - I just quickly copy/pasted/tweaked this from a working server.

The root value here is used as the -w value in the certbot webroot command.

    server {
        listen 80;
        server_name   apex1.com www.apex1.com;
        access_log off;

        location /.well-known/acme-challenge {
           root /your/path/for/challenges;
           access_log  /var/log/nginx/access80.log;   # optional
        location / {
           return 301 https://$host$request_uri;


That now makes perfect sense and I should have thought about it. I got my head so wrapped up in making DNS work that I completely discounted HTTP without shutting down Nginx.

I'll give it a try and see how it goes.

Thanks again for your valuable help.



IMHO, the easiest way to do this with Nginx is via a proxypass.

You can invoke Certbot with --standalone --http-01-port=8001 to run Certbot on port 8001 (or anything else) in standalone mode. Then you just proxy the acme directory onto that port. LetsEncrypt must talk to the server on Port80, but Certbot can run on any port. Standlone mode just has Certbot spin up it's own webserver. I typically define this in a macro, and include it on every server block.

Then you define a post-hook to gracefully restart nginx. No downtime, no messing with the filesystem.


This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.