fetzerch/kasserver

Trouble with verification step and certbot, although ACME TXT record shows up

rudelm opened this issue · 12 comments

Hi! I'm using your python script with my all-inkl account and tried to create a wildcard certificate. I'm able to query the API using my credentials and the examples from the api documentation. I'm also able to query manually using kasserver-dns list my-domain.name

I've tried to use kasserver-dns-certbot as auth and cleanup hook and see this output:

Error output from kasserver-dns-certbot:
INFO:kasserver_dns_certbot:Received request for fqdn <my-domain.name> and value '<value>'
INFO:kasserver_dns_certbot:Setting DNS TXT record for domain _acme-challenge.<my-domain.name> to <value>
WARNING:kasserver:Hit flood protection, retrying in 3s

Waiting for verification...
Cleaning up challenges
Error output from kasserver-dns-certbot:
INFO:kasserver_dns_certbot:Received request for fqdn <my-domain.name> and value '<value>'
INFO:kasserver_dns_certbot:Removing existing DNS TXT record for domain _acme-challenge.<my-domain.name> with value <value>
WARNING:kasserver:Hit flood protection, retrying in 3s

Failed authorization procedure. <my-domain.name> (dns-01): urn:ietf:params:acme:error:unauthorized :: The client lacks sufficient authorization :: No TXT record found at _acme-challenge.<my-domain.name>

If I'm fast enough, I'm able to see the added TXT record for _acme-challenge.<my-domain.name> in the KAS DNS menu. However, according to the certbot log the TXT record is missing, when it is checked and the cleanup is immediately triggered.

Do you know if the lets encrypt certificates provided by KAS cause problems in this situation? I see various other TXT records but none contain the _acme-challenge.

Hey, I haven't touched this in a while, so it took a bit to recall how it works 😉
Just gave it a try now (against the stating environment) with certbot, and it's working fine for me. certbot version is 1.8.0.

I'm using the KAS "internal" let's encrypt certificates for a few domains as well and that doesn't seem to interfere.

One test could be if you omit the --manual-cleanup-hook parameter (or just point it to /bin/true) and then check if the DNS entry is persisted. If it's not, then there must be something that automatically removes it.

There's also a history entry in KAS: Tools -> DNS Settings -> History (the right icon next to the domain). Maybe that shows something suspicious?

I've skipped the manual cleanup hook and I see that the entry is added. However, the verification fails of the challenge. I can confirm that kasserver created the TXT record for the domain in the History. However, I've seen that I'm using certbot 0.28.0 from raspbian stretch apt. I've uninstalled the apt package and tried the snap package, which offers 1.8.0.

I'm still seeing the same behavior. The verification always fails. The response from the verification call from certbot looks like this, even when the TXT record is present:

{
  "identifier": {
    "type": "dns",
    "value": "<my-domain.name>"
  },
  "status": "invalid",
  "expires": "2020-10-08T21:22:17Z",
  "challenges": [
    {
      "type": "dns-01",
      "status": "invalid",
      "error": {
        "type": "urn:ietf:params:acme:error:unauthorized",
        "detail": "No TXT record found at _acme-challenge.<my-domain.name>",
        "status": 403
      },
      "url": "https://acme-v02.api.letsencrypt.org/acme/chall-v3/7603359532/KmNcQQ",
      "token": "I7q4Iw....OceFWGsbyieXdz2VM"
    }
  ],
  "wildcard": true
}

Which all-inkl package to you use? I'm using the private plus and I'm trying to create a wildcard cert for a subdomain which is also used for ddns. Maybe that's a problem?

I'm trying to create a wildcard cert for a subdomain which is also used for ddns. Maybe that's a problem?

That seems to be the issue indeed. It fails for me as well here. I guess the reason is that there are two different NS records (dyndns1.kasserver.com and dyndns2.kasserver.com) for the DDNS domains. There's probably a way to debug which nameserver Let's encrypt is trying to contact, but I couldn't figure it out quickly.

The way I solved this is to let the DDNS service update a domain called ddns.<my-domain.name>. And then for each (wildcard)domain you want a cert for, just add a CNAME entry that points to ddns.<my-domain.name>..

I think that is already my current setup:

I've got a domain

  • secured with a lets encrypt cert using KAS

I've got a DDNS entry for that domain

  • which is statically resolved by all-inkl to dyndns1.kasserver.com and dyndns2.kasserver.com

I've got a CNAME entry for *.ddns.<my-domain.name>

  • which points to ddns.<my-domain.name>
  • which already works with a wildcard certificate I've created under my own local trusted CA
  • which I want to replace with the Lets Encrypt cert

I need the wildcard certificate for minio in virtual-host-style requests, as each bucket name will be prepended to the DDNS entry.

However, I've tried this with the same result as before:

  • Create the ddns.<my-domain.name> entry in DDNS KAS menu
  • Create a CNAME entry bucketname.ddns.<my-domain.name> in KAS DNS menu which points to ddns.<my-domain.name>
  • Tried certbot with -d bucketname.ddns.<my-domain.name>, which failed verification again

Do you call certbot with -d bucketname.ddns.<my-domain.name> / any other domain you'll need under ddns.<my-domain.name>? It's neither working for wildcard or for specified domain names.

It seems like you can't create certs for subdomains of your dyndns domain. Probably because of the dyndns.kasserver.com nameserver.

This is the output of my kasserver-dns list my-domain.de:

ID       C Zone                 Name                 Type  Data                      Aux  
XXXXXXXX Y my-domain.de         *                    A     X.X.X.X                       0
XXXXXXXX Y my-domain.de                              A     X.X.X.X                       0
XXXXXXXX Y my-domain.de                              MX    xxxxxxxx.kasserver.com.      10
       0 N my-domain.de                              NS    ns6.kasserver.com.            0
       0 N my-domain.de                              NS    ns5.kasserver.com.            0
       0 N my-domain.de         home                 NS    dyndns1.kasserver.com.        0
       0 N my-domain.de         home                 NS    dyndns2.kasserver.com.        0
XXXXXXXX Y my-domain.de         gitlab               CNAME home.my-domain.de.            0
XXXXXXXX Y my-domain.de         *.gitlab-pages       CNAME home.my-domain.de.            0

Btw: It's also a PrivatPlus account.

ok :(

I've now tried to create a certificate only for the cname entry pointing to a single non-wildcard subdomain of the ddns domain, but still no progress.

So it seems to be rather a limitation of the DDNS and DNS settings provided by all-inkl. As from the history of the DNS settings I can see that kasserver is doing its requests fine. Unless you've got another idea I think the ticket can be closed.

I've now tried to create a certificate only for the cname entry pointing to a single non-wildcard subdomain of the ddns domain, but still no progress.

Can you try to create a cert for anything non related to DDNS? For example for your main domain?
It's strange that it works for me but doesn't work for you. Maybe you could try contacting the All-Inkl support.

I could successfully create a cert for one of my main domains. Guess I'll try and ask the All-Inkl support if letsencrypt certificates can somehow be created with DNS-01 validation for DDNS domains. I'll let you know once I've got an answer.

Ok I've got a response from the support: It's not possible to use the DNS editor in KAS to configure entries for the DDNS domains managed by dyndns1.kasserver.com and dyndns2.kasserver.com. The editor only controls entries for ns5.kasserver.com and ns6.kasserver.com, which explains why kasserver-dns-certbot can create certificates for domains but not the DDNS subdomains.

So I'll probably have to use the http or tls acme challenges, if I want to have a valid certificate. Thanks for your time and support!

OK, that's a pity. What I don't quite see is why the "workaround" that I'm using doesn't work for you.

Why do you need to create an entry for a subdomain of your DynDNS domain. Why can't it be any other subdomain?
See above, my dyndns subdomain is 'home', and I successfully create certs for 'gitlab' as well as '*.gitlab-pages'. 'home' itself is not used for anything else and also has no webservice hosted.

Oh now I understand how your workaround works! My intention was to have all entries clean under the DDNS domain instead of using the CNAMEs. I've created now a letsencrypt cert for *.buckets.<my-domain.name> and a cname from *.buckets.<my-domain.name> to my DDNS domain and will see if this is accepted by my backup software.

yeah looks like its working with that workaround. Thank you for the idea and support 👍