go-acme / lego

Let's Encrypt/ACME client and library written in Go
https://go-acme.github.io/lego/
MIT License
7.83k stars 1.01k forks source link

inwx: local DNS doesn't answer to SOA calls #2228

Closed muebau closed 2 weeks ago

muebau commented 1 month ago

Welcome

What did you expect to see?

Use Traefik with the LetsEncrypt DNS challenge and the DNS provider INWX and a domain ".cloud".

The TXT record should be set correctly. API parameters should be:

domain: <domain>.cloud
type: TXT
content: ...
name _acme....<domain>.cloud

What did you see instead?

There is a problem when the SOA record is not presented as expected.

API parameters get truncated (see domain):

domain: cloud
type: TXT
content: ...
name _acme....<domain>.cloud

Background: I use Traefik behind a OPNsense with a host overwrite for ".cloud". I use the DNS challenge with the DNS provider INWX.

I was able to debug the problem with the INWX support (thank you for 1 hour of your time). We found that the API request is truncated.

Why: The local DNS resolver returns a local IP for .cloud but no SOA record. This leads to the wrong content "cloud" in the variable here: https://github.com/go-acme/lego/blob/321cea51e4388e396bd2602196c2c6d22bb01e0e/providers/dns/inwx/inwx.go#L99

It is later used to create a record at INWX: https://github.com/go-acme/lego/blob/321cea51e4388e396bd2602196c2c6d22bb01e0e/providers/dns/inwx/inwx.go#L122 The log of INWX shows that the request parameter "domain" contains the invalid content "cloud" instead of ".cloud .

The reason is that the code tries to find the first "SOA" answer: https://github.com/go-acme/lego/blob/321cea51e4388e396bd2602196c2c6d22bb01e0e/challenge/dns01/nameserver.go#L148

This seems to go wrong as the local resolver (OPNsense -> Services: Unbound DNS: Overrides) returns a local IP but no SOA record.

I think this setup might occur in some private, local setups where the DNS challenge is used to get a certificate is used but the server is accessed locally.

Is the idea to use the SOA record valid for every scenario?

Traefik uses Lego: https://github.com/traefik/traefik/blob/87db3300d33fd5b74d793cf81d9dbcdba2092837/go.mod#L20

How do you use lego?

Through Traefik

Reproduction steps

  1. configure Traefik with a domain and use the LetsEncrypt DNS challenge with INWX
  2. have a local DNS resolver (OPNsense, Unbound) running to provide a local IP for the given domain
  3. try to get a new certificate for the domain

Version of lego

v4.17.4

Logs

```console ERR Unable to obtain ACME certificate for domains error="unable to generate a certificate for the domains [.cloud]: error: one or more domains had a problem:\n[.cloud] [.cloud] acme: error presenting token: inwx: (2303) Object does not exist\n" ACME CA=https://acme-v02.api.letsencrypt.org/directory acmeCA=https://acme-v02.api.letsencrypt.org/directory domains=[".cloud"] providerName=letsEncrypt.acme routerName=nextcloud@file rule=Host(`.cloud`) ```

Go environment (if applicable)

- Traefik 3.1 - lego v4.17.4 - OPNsense 24.1.10_3 - unbound 1.20.0
ldez commented 1 month ago

Hello,

your problem is related to your DNS configuration, I never use OPNsense or Unbound so I will not be able to provide the way to configure it.

lego tries to find the zone by doing SOA calls, but as you notice, your DNS resolver doesn't answer those calls.

You should allow OPNsense/Unbound to answer those calls with the right information.

muebau commented 1 month ago

OK thank you. I will try.

ldez commented 1 month ago

To explain why lego does SOA calls: the goal is to find the right place to create the TXT records, a user can have domains on several zones, so the automatic detection (through SOA calls) allows to handle that.

Without this detection, only one zone will be handled and should be provided by the user, in the majority of cases this will lead to a failure of the DNS challenge because it will be impossible to create TXT records.

ldez commented 2 weeks ago

I will close this issue but don't hesitate to add your solution as a comment for future OPNsense/Unbound users.