No TXT record found (using Linode DNS plugin)


#1

My domain is sambidb.com. This is my first ever attempt to get a certificate, and diving into the deep end of the pool by trying to get a wildcard one (I don’t even have a website at the root domain, although I might eventually - I’m currently only running a database webapp on subdomains). My server is a CentOS 7 VPS on Linode.

I read various tutorials, but most of them describe the manual process. Since there is a DNS plugin for Linode, I figured I might as well do the slick Certbot way. The tutorial I primarily followed is this: https://linuxacademy.com/blog/linuxacademy-com/wildcard-certificates-with-lets-encrypt-and-nginx/

I updated certbot, installed python2-certbot-dns-linode, got an API key from the Linode Manager interface and put it in a file with chmod 600, and then ran this command:

certbot -a dns-linode --dns-linode-credentials /root/.certbot/linode.ini --dns-linode-propagation-seconds 60 -i nginx -d "*.sambidb.com" --server https://acme-v02.api.letsencrypt.org/directory

Here is the output:

Saving debug log to /var/log/letsencrypt/letsencrypt.log
Plugins selected: Authenticator dns-linode, Installer nginx
Starting new HTTPS connection (1): acme-v02.api.letsencrypt.org
Obtaining a new certificate
Performing the following challenges:
dns-01 challenge for sambidb.com
Starting new HTTPS connection (1): api.linode.com
Starting new HTTPS connection (1): api.linode.com
Starting new HTTPS connection (1): api.linode.com
Waiting 60 seconds for DNS changes to propagate
Waiting for verification...
Cleaning up challenges
Starting new HTTPS connection (1): api.linode.com
Starting new HTTPS connection (1): api.linode.com
Starting new HTTPS connection (1): api.linode.com
Failed authorization procedure. sambidb.com (dns-01): urn:ietf:params:acme:error:unauthorized :: The client lacks sufficient authorization :: No TXT record found at _acme-challenge.sambidb.com

IMPORTANT NOTES:
 - The following errors were reported by the server:

   Domain: sambidb.com
   Type:   unauthorized
   Detail: No TXT record found at _acme-challenge.sambidb.com

   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.

I looked at my DNS, and indeed, there is no TXT record. I would be happy to make it, but I don’t know the value it needs, and I got the impression from the tutorial that the Linode plugin was supposed to create it for me. (That’s the whole point of making the command wait 60 seconds for propagation, right?) My webapp works fine, so I would think that means that the DNS A record, nginx configuration, etc. are correct. What should I look for? (I tried reading letsencrypt.log, but I don’t know enough to recognize clues in it.)


#2

Linode specifically takes a really long time to propagate DNS changes out to their nameservers (relative to other DNS providers). Last I checked, there’s a note at the bottom of the DNS management page that states:

Changes made to a master zone will take effect in our nameservers every quarter hour.

That means after certbot writes the TXT record to your zone, it needs at least a 15 minute sleep time before it attempts to finalize the order. So up that propagation seconds value to at least 900 and try again. In my own personal testing with Linode, I’d still fail occasionally at 15 minutes and upped my own delay to 17 minutes.


#3

You could check the sync independently of certbot.
As examples:
nslookup -q=txt _acme-challenge.sambidb.com 8.8.8.8
nslookup -q=txt _acme-challenge.sambidb.com 1.1.1.1
(or from any other DNS server IP of your choosing)


#4

I did as you suggested:

certbot -a dns-linode --dns-linode-credentials /root/.certbot/linode.ini --dns-linode-propagation-seconds 1000 -i nginx -d "*.sambidb.com" --server https://acme-v02.api.letsencrypt.org/directory

But I got the same result:

Saving debug log to /var/log/letsencrypt/letsencrypt.log
Plugins selected: Authenticator dns-linode, Installer nginx
Starting new HTTPS connection (1): acme-v02.api.letsencrypt.org
Obtaining a new certificate
Performing the following challenges:
dns-01 challenge for sambidb.com
Starting new HTTPS connection (1): api.linode.com
Starting new HTTPS connection (1): api.linode.com
Starting new HTTPS connection (1): api.linode.com
Waiting 1000 seconds for DNS changes to propagate
Waiting for verification...
Resetting dropped connection: acme-v02.api.letsencrypt.org
Resetting dropped connection: acme-v02.api.letsencrypt.org
Cleaning up challenges
Starting new HTTPS connection (1): api.linode.com
Starting new HTTPS connection (1): api.linode.com
Starting new HTTPS connection (1): api.linode.com
Failed authorization procedure. sambidb.com (dns-01): urn:ietf:params:acme:error:unauthorized :: The client lacks sufficient authorization :: No TXT record found at _acme-challenge.sambidb.com

IMPORTANT NOTES:
 - The following errors were reported by the server:

   Domain: sambidb.com
   Type:   unauthorized
   Detail: No TXT record found at _acme-challenge.sambidb.com

   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.

And looking at my DNS in the Linode interface, I never see any TXT records. Next idea?


#5

Can you test the Linode DNS authenticator API independently of certbot?
Do you see any traffic from your system out to Linode systems?
try:
curl https://api.linode.com/


#6

No, I didn’t, because I don’t even understand what it does. Be kind to me - I’m a newbie.

Apparently there is something wrong with it, as your suggested curl https://api.linode.com/ command returned: {"ACTION":"","DATA":{},"ERRORARRAY":[{"ERRORMESSAGE":"Authentication failed","ERRORCODE":4}]}

That doesn’t sound good, but I have no idea what to do about it.

When I set up the API credentials (or attempted to - apparently I failed), I followed the instructions in the “Credentials” section of this page: https://certbot-dns-linode.readthedocs.io/en/stable/ I used the Linode Manager to generate a key, copied the contents into a file like they said to do:

[root](14:50:55)[/etc/letsencrypt]$ cat /root/.certbot/linode.ini
# Linode API credentials used by Certbot
dns_linode_key = 5rU...[the rest redacted, of course]...LUz

And I dutifully restricted the permissions:

[root](15:05:17)[/etc/letsencrypt]$ ls -la /root/.certbot
total 12
drwx------   2 root root 4096 Nov  1 15:41 .
dr-xr-x---. 10 root root 4096 Nov  2 07:29 ..
-rw-------   1 root root  123 Nov  1 15:41 linode.ini

But I don’t even know how the curl command would know to look in that file for my key. Sorry, I’m out of my league - I’m a programmer, not a server admin.


#7

Actually that is the correct reply for a simple connect with not parameters passed.
So you do have access to api.linode.com - this is good.


#8

I see nothing wrong with this command line request.
Sadly, I don’t know of anyway to troubleshoot their API…
Maybe adding -vvv and reviewing the LE logs thereafter.

OR dive right in to their API and test it directly: https://www.linode.com/api


#9

Like maybe that “code key” requires quotes around it?

And the example shows “certonly”: https://certbot-dns-linode.readthedocs.io/en/stable/
So try:
certbot certonly -a dns-linode --dns-linode-credentials /root/.certbot/linode.ini --dns-linode-propagation-seconds 1000 -i nginx -d “*.sambidb.com” --server https://acme-v02.api.letsencrypt.org/directory


#10

After adding quotes around the key (a shot in the dark, since the plugin doc page that the official certbot doc page point to do not use quotes in their example), the certificate for *.sambidb.com went through!

But after doing my happy dance, I ran the command again for another wildcard certificate I need (different domain, same server - this time including the naked domain in the same cert). I had learned that the default propagation time for the Linode plugin is 960, so I dropped that switch from the command, figuring 16 minutes is long enough. Alas, I got the “no TXT record” error again. I increased the propagation time to 1100 seconds and got a different error:

[root](17:03:32)[/etc/letsencrypt]$ certbot -a dns-linode --dns-linode-credentials /root/.certbot/linode.ini --dns-linode-propagation-seconds 1100 -i nginx -d "kizunadb.com" -d "*.kizunadb.com" --server https://acme-v02.api.letsencrypt.org/directory
Saving debug log to /var/log/letsencrypt/letsencrypt.log
Plugins selected: Authenticator dns-linode, Installer nginx
Starting new HTTPS connection (1): acme-v02.api.letsencrypt.org
Obtaining a new certificate
Performing the following challenges:
dns-01 challenge for kizunadb.com
dns-01 challenge for kizunadb.com
Starting new HTTPS connection (1): api.linode.com
Starting new HTTPS connection (1): api.linode.com
Starting new HTTPS connection (1): api.linode.com
Starting new HTTPS connection (1): api.linode.com
Starting new HTTPS connection (1): api.linode.com
Starting new HTTPS connection (1): api.linode.com
Waiting 1100 seconds for DNS changes to propagate
Waiting for verification...
Resetting dropped connection: acme-v02.api.letsencrypt.org
Cleaning up challenges
Starting new HTTPS connection (1): api.linode.com
Starting new HTTPS connection (1): api.linode.com
Starting new HTTPS connection (1): api.linode.com
Starting new HTTPS connection (1): api.linode.com
Starting new HTTPS connection (1): api.linode.com
Starting new HTTPS connection (1): api.linode.com
An unexpected error occurred:
The server experienced an internal error :: Problem getting authorization
Please see the logfiles in /var/log/letsencrypt for more details.

I reduced the time back to 1000, and it finally succeeded. I don’t think the quotes around the key or the small differences in waiting time are really the issue - it seems that it’s just flaky, and you have to try it several times before you get lucky.

I’ve learned a lot more along the way (waiting 16-17 minutes to see if a command worked will give you a lot of time to read documentation!). Here is some info for people coming along later and reading this:

  • The suggestion of using nslookup to check for the TXT record is not likely to reveal anything unless your timing is perfect, because as soon as certbot tests for it, it removes the record.
  • The certonly suggestion is also a distractor in this case. The Linode docs use that in their example, but they are describing a more manual technique. The nginx installer plugin works like a champ, so there is no need to get the cert first and then manually edit the nginx config files. Once the auth succeeds, certbot will list all the server directives in your nginx config files and ask you which ones you want it to modify, and also ask if you want it to add redirection from HTTP to HTTPS (I can’t imagine anyone not wanting that). That part of the process works smoothly.

#11

That’s a weird internal error from Let’s Encrypt. I think/hope it was probably just a coincidence, and not caused by anything you or Certbot did.