Own or Public DNS resolver

Is it safe and best practice to use own DNS resolver (like unbound) in 2021 or is it better to use a Public resolver? Don’t consider malware protection. Just DNS.

I use the unbound server built into pfSense and I’ve never thought about potential security risks with it. For me, it’s a practical decision since I can add custom names and DHCP leases can be resolved too.

1 Like
  1. Use pfSense unbound, enable DNSSEC and SSL/TLS.
  2. Add FW rule to redirect all outbound DNS queries to local DNS server

  1. Run DNS spoofability test. GRC | DNS Nameserver Spoofability Test  

The spoofability test is really helpful. It marked my unbound server “Excellent”. Thanks!
I run a docker instance of unbound with Alpine Linux since I don’t have pfsense.

Although I am in favour of running your own resolver, there’s an issue with CDNs (especially Akamai). Try the following test:

  • Resolve a website that is using Akamai edge with your resolver, the resolver of your ISP, and a public DNS resolver.
  • If you get the same address(es) you are good.
  • If not, run a traceroute or a ping to the addresses you will get and check the latency.

In my case, using a public resolver or my resolver resulted to higher ping times (50-60ms) to sites using some CDNs than using my ISPs (10ms).

I managed a work around using rules in my resolver (using bind here) to resolve CDN domains using my ISP’s resolver, the rest of the resolver is done normally. For unbound there’s the EDNS Client Subnet Module

Just my 2c

1 Like

@mtheofy my local resolver gives the same IP as ISP’s and google’s public dns.
Cloudflare gives different results, as they don’t support ECS.
So, for CDN we have a draw: own resolver = public resolver that supports ECS.

1 Like

@Spectre Excellent results. Well done. Makes me want to migrate to unbound (bind supports ECS only with a subscription).

Bingo! There’s a a commercial reason behind ClounFlare’s decision not to support ECS. Unfortunately, many folk decide to use it based on ping RTT.

1 Like

@mtheofy I have used every single public dns. Cloudflare is the only one that has given me dns errors! (on PlayStation and on a streaming box). I consider their services as highly experimental :grin:

If you want, please take some time to share your bind configuration. I haven’t found any decent one yet :+1:t3:

Curious as to how you made this work. A lot of domains (if not, all) served by Akamai have CNAMEs in their replies.

E.g. play.itunes.apple.com has a CNAME *.*.akamai.net that’s served depending upon ECS data.

So I’m really curious as to how you’re able to selectively forward domains like these.

Recursion is done locally, but I am using forward zones for domains operated by CDNs. I am forwarding queries of CDN domains to my ISP’s dns servers.

e.g. play.itunes.apple.com is resolved by my local resolver to the CNAME play-cdn.itunes-apple.com.akadns.net.. My resolver is using a forward rule for akadns.net that forwards any query under that domain to my ISP’s dns server (its location is well known to CDN operators) so I am served with the IP addresses of the closest nodes of the CDN.

Here’s an example of a forward zone in bind:

zone "akadns.net" {
     type forward;
     forwarders { 2a02:587:101:0:195:170:0:1; 
                  2a02:587:101:0:212:205:212:205;
                  195.170.0.1; 
                  212.205.212.205; };
};

I use a list of domains operated by CDNs that I collected. The forward zones are generated automatically through a bash script. A snippet of the list is shown below (txt attachments not allowed)

# Akamai
aka.ms
akagtm.org
akamai.net
akamai.org
akamaiedge.net
akamaihd.net
edgecastcdn.net
edgesuite.net
edgekey.net
....
# Microsoft and Azure
1drv.ms
azureedge.net
azureedge.org
azure-dns.net
azure-dns.com
azure-dns.info
azure-dns.org
cloudapp.net
msedge.net
a-msedge.net
b-msedge.net
c-msedge.net
d-msedge.net
....

PS: If you made it this far, here’s another tip for a bind resolver. You can mirror the root zone ‘.’ so you don’t need to query them to discover the NS servers of TLDs using a special zone. This provides a number of advantage (e.g. reduced dns traffic, reduced noise to the root servers, etc).

zone "." {
    type mirror;
};

Would you know if Unbound’s zones work in the same way as BIND? I’m running Docker w/ Unbound already so that will make things very easy.

The initial query when BIND doesn’t know if it should forward to x zone… is made to a resolver, right? So essentially two queries are made when it matches a forward zone?

How do you manage Cloudfront domains? They support ECS too, with seemingly no CNAMEs for some domains.

E.g. tmdb.org for e.g. returns IPs for the local cache, with no CNAMEs, but images.kitchenstories.io returns a *.cloudfront.net CNAME, so that can be forwarded. Both domains serve content from Cloudfront.

I used unbound briefly in the past but I am not very proficient. Unbound supports both modes of resolving i.e. it can act as a local resolver (walk the DNS tree) or as a simple forwarder (forward all queries to an external resolver).

This depends on your configuration (BIND or Unbound):

  1. As a local resolver. Your dns server will walk the DNS tree querying name server of each domain. e.g. if you resolver needs to resolve play.itunes.apple.com it will first ask the .com NS servers to get the ns of apple.com. Once it gets them and their IP address (one of those is d.ns.apple.com for example) it will ask d.ns.apple.com for the IP address play.itunes.apple.com. If it gets a CNAME to an akamai node, it does the same for the CNAME target using the DNS servers of akamai. Once it gets the IP address it returns the IP address for play.itunes.apple.com to the requestor. This might look slow but it’s extremely fast since there’s caches involved and UDP is used.

  2. As a forwarding server. Your dns server forwards the full query to your configured external resolver (e.g. 1.1.1.2). The external resolver performs the dns walk (see 1 above) and forwards the result to your server.

My approach works because I configured my resolver as a local resolver (point 1 above) with the exceptions of CDN domains which are forwarded to my ISP dns servers. This means that as as soon as the server gets the CNAME to play-cdn.itunes-apple.com.akadns.net instead of doing the dns walk, it acts as a forwarding resolver (point 2) *for .akadns.net including its subdomains and forwards the query play-cdn.itunes-apple.com.akadns.net to my ISPs resolver. My ISP dns servers give me IP addresses which are closer to my network.

All the above sounds too technical but you don’t need to know the theory. For Unbound read the docs for configuring it as a local resolver (not as a forwarding resolver) and read the docs for configuring specific forward zones (i.e. configure a forward-zone: configuration for akadns.net to forward those queries to your ISP dns servers).

Thanks for all that info.

I tried forward zones in Unbound and it works perfectly, except the net query time for forward-zone is quite high, <1000 ms on many occasions.

My ISP uses Google DNS as their upstream, so I can make DoH queries to them directly rather than risk profiling.

You said you get the local cache for Azure? Hmm haven’t really encountered that as yet. Can you shoot me a domain that your ISPs cache serves?

Aside, have you found your ISPs cache to be faster than what, say Cloudflare, a non-ECS resolver provides?