home-assistant / plugin-dns

CoreDNS implementation for Home Assistant
Apache License 2.0
20 stars 15 forks source link

No SERVFAIL and no forwarding multicast names #86

Closed mdegat01 closed 2 years ago

mdegat01 commented 2 years ago

Fixes #85 by responding with an NXDOMAIN if a local.hass.io name is not found in our hosts file. We are authoritative on that domain in networks with supervisor and so there's no reason to keep looking if we can't find it.

Additionally fixes #70. When reviewing the SERVFAILS that occurred when an LLMNR name was looked up (single name, no TLD) I realized that generally only bad things happen if we continue looking up multicast names past the MDNS plug-in. Since the MDNS plug-in asks the host for an answer it will get an answer for any multicast names as long as the host has one. And if the host doesn't its unlikely any of the other potential forwarding servers will either. But trying will likely leak private host names to external resolvers.

There is a risk with this. It is possible to add a dns rewrite entry for something like my-server.local in some DNS servers instead of properly using MDNS. This will no longer resolve after this change for users doing this because systemd-resolved also refuses to forward multicast names to other resolvers. But given what we are doing has caused a CVE and I think we should follow systemd-resolved example and stop at the MDNS plugin as well.

Note that if we cannot reach systemd-resolved (can occur only on an unsupported system) then the MDNS plugin continues to pass the request along as normal. It can't answer any queries in this situation so that is the best it can do.

mdegat01 commented 2 years ago

FYI some more context in the discussion here

KevinCathcart commented 2 years ago

It is worth mentioning this only fixes #70 for dotless domains and .local domains.

If somebody types in a fully qualified local domain name, (such as my device.home.arpa, or device.attlocal.net, or device.mshome.net), and their local dns server is down, we could still leak those domains to cloudflare. But the only way to avoid that would be an option to disable fallback. This is because other than home.arpa, none of those other suffixes are special, so they should not be handled specially by general purpose dns servers, so even running a recursive resolver would leak final hostnames, albeit only to the nameservers for those domains.

But again, it is the best we can possibly do, other than adding an option to disable fallback, or things like letting users specify a blacklist of domains not allowed to fallback.

mdegat01 commented 2 years ago

@KevinCathcart fair point. Fortunately I'm was already working on that 😄 https://github.com/home-assistant/supervisor/pull/3586

agners commented 2 years ago

This is because other than home.arpa, none of those other suffixes are special, so they should not be handled specially by general purpose dns servers, so even running a recursive resolver would leak final hostnames, albeit only to the nameservers for those domains.

There is a list of reserved top-level domains in RFC2606. There have been attempts to extend the list with commonly used (currently not assigned) top level domains. Since those are invalid at the top level, I think it would be quite reasonable to add those to our list as well.

mdegat01 commented 2 years ago

@agners I see your point but that gets tricky. The problem with other reserved TLDs is they require a local DNS server. Like we do need to send those to some resolver its just ideally we should only be sending them to an internal resolver, not an external one.

And unfortunately with those I can't just make a statement like "if the host can't resolve them then no one can". Because the user has a way to add a DNS server just to HA and override the DHCP provided one. Which means it is entirely possible HA can resolve a name with one of those other special TLDs and the host's systemd-resolved can't.

In order to satisfy that request I believe we'd need to identify which resolvers were internal and which were external and only forward requests with those TLDs to internal ones. Which would be a lot more complicated because to my knowledge coredns has no way to do that, you just make a list of resolvers to forward to. Or we offload all DNS work to systemd-resolved (not just MDNS and LLMNR) but Pascal said that created other issues.