acmesh-official / acme.sh

A pure Unix shell script implementing ACME client protocol
https://acme.sh
GNU General Public License v3.0
39.16k stars 4.95k forks source link

Report bugs in NLnetLabs NSD dns api #2245

Open plantroon opened 5 years ago

plantroon commented 5 years ago

This is the place to report bugs in the NLnetLabs NSD API.

If you experience a bug, please report it in this issue.

Thanks!

arsh0r commented 5 years ago

I had to add the following in dns_nsd_add(): _debug "Running $Nsd_Command" if eval "$Nsd_Command"; then oldserial=$(grep -Eho "[0-9]{10}" "$Nsd_ZoneFile") #hopefully the serial is the only 10-digit number around newserial=$(date "+%Y%m%d%H") _info "Updating serial from $oldserial to $newserial" sed -i "s/$oldserial/$newserial/g" "$Nsd_ZoneFile" _info "Successfully updated the zone" return 0 else _err "Problem updating the zone" return 1 fi

with no change in the serial the zonefile wasn't updated on on my second nameserver

plantroon commented 5 years ago

I will think about how to implement this. Because I sign with DNSSEC and have a separate script for that which I use for Nsd_Command and it already increases the serial number - so I didn't catch this bug.

arsh0r commented 5 years ago

You are right. Maybe it is best to implement this in the Nsd_Command script. Otherwise it would try to change the serial multiple times it you want to issue for more subdomains or wildcard.

edit: Well, sadly $Nsd_Command is run for each subdomain on addition of the TXT records and also on removal.

plantroon commented 5 years ago

There is no generic enough way to increment the serial number. I would have to use awk to process the zone file and that is forbidden per DNS API Dev Guide. Using sed, I wasn't able to reach a desirable result. Especially because the serial number can have any number of digits and can be on any line part of the SOA record. Most Unix tools are line-based and while there are multi-line options, I couldn't figure out how to match every possible case. Do you have any advice on how to do this?

Basically you have to take care of this in custom scripts, which people using NSD usually already have. Mine increments the serial and signs the zone with DNSSEC and then reloads nsd (which also notifies slave nameservers).

arsh0r commented 5 years ago

I also think there is no general approach, but in my zonefile the serial is the only 10-digit number around. I just changed it to "newserial=$(expr "$oldserial" + 1)" because it needs to be updated on addition and removal of the TXT records. I find it a bit unfortunate that the Nsd_Command function are called for each domain (for wildcard it will be two calls for example.com and *.example.com on addition and removal of the TXT record, so DNS zonefile is updated four times) and not just one after the addition/removal of all needed TXT records, but this, i think, can only be solved on acme.sh side and not dnsapi.

snimmagadda commented 4 years ago

There is no generic enough way to increment the serial number. I would have to use awk to process the zone file and that is forbidden per DNS API Dev Guide.

I am wondering if awk prohibition is limited to processing api response alone. A few dns scripts do use awk for other purposes. I just ran into this dns_nsd.sh limitation as Let's Encrypt could pick up any authoritative server for querying TXT records and failing to notify secondary nsd servers with an updated serial number would result in NXDOMAIN errors during validation.

The code and an explanation of choosing which authoritative servers for validation are explained in these links... https://github.com/letsencrypt/boulder/blob/409f1623e6369ed1902fd704d577df1657878abd/bdns/dns.go#L237:L238 https://community.letsencrypt.org/t/dns-servers-used-by-letsencrypt-for-challenges/32127/10

PR #3198 along with Nsd_Command="nsd-control reload && nsd-control notify" removes this limitation for me.

Neilpang commented 4 years ago

I am wondering if awk prohibition is limited to processing api response alone. A few dns scripts do use awk for other purposes.

No, don't use awk anywhere.

snimmagadda commented 4 years ago

I am wondering if awk prohibition is limited to processing api response alone. A few dns scripts do use awk for other purposes.

No, don't use awk anywhere.

Ok. I will retract the PR and think of solving it another way. As a new user and not so experienced at POSIX shell, I am curious why awk is forbidden. I re-read DNS API Dev guide but it didn't provide any hints.

schrodyn commented 1 year ago

Not sure if this is the right place to ask. Apologies in advance.

I am looking for help with NSD dnsapi & acme.sh. I have multiple domains and I wish to issue a single certificate that has a wildcard for each domain. E.g.:

I cannot find documentation on how to achieve this with the NSD dnsapi because the configuration is only for a single zonefile for a single domain.

Is this kind of issuing possible? Thank you.

plantroon commented 1 year ago

Not sure if this is the right place to ask. Apologies in advance.

I am looking for help with NSD dnsapi & acme.sh. I have multiple domains and I wish to issue a single certificate that has a wildcard for each domain. E.g.:

  • *.domain_a.com
  • *.domain_b.com
  • *.domain_c.com

I cannot find documentation on how to achieve this with the NSD dnsapi because the configuration is only for a single zonefile for a single domain.

Is this kind of issuing possible? Thank you.

This seems to be exactly what you're after (and as far as I understand it is supported directly by nsd regardless of used dns api): https://github.com/acmesh-official/acme.sh/wiki/How-to-issue-a-cert#3-multiple-domains-san-mode--hybrid-mode

Try it out and report back

schrodyn commented 1 year ago

Thanks, plantroon. I read that but I don't understand how to configure a zonefile per domain. Do I not need to configure which zone files to update as per the docs? https://github.com/acmesh-official/acme.sh/wiki/dnsapi#76-use-nlnetlabs-nsd

plantroon commented 1 year ago

Ah sorry, I see the problem now. To preserve compatibility, I'd try adding Nsd_ZoneDir. Could you maybe share what your directory with zonefiles (zonesdir from nsd config) looks like?

Like my /srv/dns/zones: somedomain.net.zone plantroon.com.zone

Is this a common format to rely on? I have it like that

Then we could simply address the files as the script has the full domain name and zonesdir from env variable (which is later saved to the domain's config in acme.sh)

I'll get back when I have it (this evening or tomorrow) - the fix is easy, but testing it takes more time xD

schrodyn commented 1 year ago

I did a quick trial with acme.sh --test and it fails as I expected, updates to the zone file for each other domain are not visible because the records are only added to domain-a.com.

I didn't realise NSD_ZoneDir was an option! :O I will try that now. Happy to share configs so I'll come back with those after testing.

schrodyn commented 1 year ago

Oh, did you mean you can add the option for Nsd_ZoneDir? That would be great. So currently for a single zone I have a file like domain-a.com.letsencrypt which I include in the main zone file.

/usr/local/etc/nsd/zones/forward/unsigned/domain-a.com

$INCLUDE /usr/local/etc/nsd/zones/forward/unsigned/domain-a.com.letsencrypt

/usr/local/etc/nsd/zones/forward/unsigned/domain-b.com

$INCLUDE /usr/local/etc/nsd/zones/forward/unsigned/domain-b.com.letsencrypt

It would be great if I could place each of these into a directory like /usr/local/etc/nsd/zones/forward/unsigned/letsencrypt/ E.g.:

Then have an option for the NSD dnsapi to find these based on names.

plantroon commented 1 year ago

So sorry I only got around to this now. I have no domains to test this on - I just realized that my freenom domains are dead and I have no way to verify if anything I change works.

For now here is a prototype that could work. The code should be really easy to understand and debug. I will only do a PR once it's confirmed working and the code is good enough (or better than what I wrote long ago xD).

If I manage to save my freenom domains somehow (I even had paid domains with them, silly me, luckily only unimportant ones), I'll be able to test this in the next weeks. Maybe I could use subdomains, but I didn't want to reconfigure my nsd since I didn't touch it in very long (bcos it works, with DNSSEC and everything :))

I also try to use separate certificates for unrelated services, though I understand that sometimes one wants to have everything in one certificate for use with non-web services without SNI.

A sidenote, there are multiple requests for a similar feature. #799, #1278, #3779, #3988