Score:0

Is it possible to have different internal and public DNS with DNSSEC?

in flag

I'm attempting to achieve the following:

  • A public nameserver for my domain which points example.com to a public IP address.
  • A private nameserver for the same domain running within a LAN which instead points clients to a private IP address on the same LAN.
  • DNSSEC enabled.

Achieving the first and last points together is of course comparatively easy so it's getting the private component to work that's the issue.

In terms of my actual setup:

  • I'm using Cloudflare's DNS service, where I have an A record for my domain pointing to a public IP address and DNSSEC enabled.
  • At my registrar, I've added a DS record based on what Cloudflare gives me and configured Cloudflare's nameservers. All of this works fine, as you'd expect.
  • Internally I'm running Pi-Hole (set as the DNS server for clients on my LAN) which is configured with DNSSEC enabled and pointing to a local CoreDNS instance as the upstream resolver.
  • In CoreDNS, I have a zone configured for example.com which is signed with keys generated by coredns-keygen. This has an A record pointing to an internal IP address.
  • I have a second DS record at my registrar based on the key used internally by CoreDNS.

What happens:

  • The general setup works for resolving domains which aren't mine.
  • Pi-Hole responds with SERVFAIL and logs ABANDONED when I attempt to resolve my domain.
  • But, if I point a client directly to CoreDNS (e.g. with dig), I get the response expected with the LAN IP address.
  • Also, if I disable DNSSEC in Pi-Hole, it works fine.

So my questions are:

  • Is what I'm trying to achieve even possible?
  • I'm starting to wonder if having separate DS records at my registrar is wrong, but I don't think I can retrieve the private key Cloudflare is using and nor can I upload custom keys, so I'm not sure how I can use the same keys for public and private.
  • Is there any reason why things seem to work if I point my clients to CoreDNS directly but Pi-Hole is refusing to cooperate?

Thanks!

Patrick Mevzek avatar
cn flag
The following question in the Related column may help: https://serverfault.com/questions/745270/using-dnssec-with-private-tld?rq=1
Patrick Mevzek avatar
cn flag
"I'm starting to wonder if having separate DS records at my registrar is wrong" DNSSEC expects ONE valid path existing to prove chain of trust. Not all. So it is "fine" having extra DS. You can find various TLDs/domains using a "pre-published DS" setup where the DS is published at parent, without the relevant DNSKEY published at child. It works as long as there is ANOTHER DS record with its proper DNSKEY in place. You might want ,from the Pi-Hole to debug further the SERVFAIL. It can be DNSSEC related, or not. If you have EDE it helps, but otherwise try dig with and without `+cd`
Patrick Mevzek avatar
cn flag
A real name would have helped. I guess the problem is more related to your `NS` records. "In CoreDNS, I have a zone configured for example.com which is signed with keys generated by coredns-keygen." But with probably different NS records than the public version of the zone? Which can induces errors on the signatures as the NS rrset will not match anymore.
in flag
Thanks, I'd seen that question, but unfortunately the links in the answer are dead. Also, I do own my real domain so that presumably makes it easier. So having multiple DS records is fine? But when you say DNSSEC expects one path, presumably that means not ONLY one path. If I try dig with `+cd`, I get `NOERROR`, so this issue is definitely related to the checking. "But with probably different NS records than the public version of the zone?" - Ah, yes. I've just tried setting the SOA and NS of the internal zone to the same as the public, no change so far.
in flag
Also going to try and get something more helpful errors from the Pi-Hole. Going to look into if I can get EDE enabled somehow.
Patrick Mevzek avatar
cn flag
"But when you say DNSSEC expects one path, presumably that means not ONLY one path." The resolver takes all the DS it sees, and all the DNSKEY it sees, and if it finds one match (plus all the crypto and dates stuff becoming ok) then it is good to assert the chain of trust is verified (and it goes on with the next level of delegation, and so on). Once a valid path is found, other DS/DNSKEY at the same level are irrelevant, even if they work too.
Patrick Mevzek avatar
cn flag
See §5.3.3 of RFC4035 if it is clearer than my explanation: "Note that it is possible for more than one DNSKEY RR to match the conditions in Section 5.3.1. In this case, the validator can only determine which DNSKEY RR is correct by trying each matching public key until the validator either succeeds in validating the signature or runs out of keys to try." So one match is enough to matter which one (in presence of multiple DNSKEY/DS; remember also that a given DNSKEY even alone can have multiple DS records, for different digests)
in flag
Thanks, that makes sense. I'm still stuck on this unfortunately. All I can see from the logs is that the Pi-Hole forwards the query to CoreDNS, which responds with the A record. The Pi-hole then queries for the DS record, CoreDNS logs a `NOERROR` response, but the Pi-Hole then logs `validation mydomain.com is ABANDONED`. Trying things with `dig` and `drill` querying the CoreDNS server directly, all I can say is that to the best of my understanding the responses look correct. So I have no idea why Pi-Hole is abandoning the validation.
mangohost

Post an answer

Most people don’t grasp that asking a lot of questions unlocks learning and improves interpersonal bonding. In Alison’s studies, for example, though people could accurately recall how many questions had been asked in their conversations, they didn’t intuit the link between questions and liking. Across four studies, in which participants were engaged in conversations themselves or read transcripts of others’ conversations, people tended not to realize that question asking would influence—or had influenced—the level of amity between the conversationalists.