Encrypting DNS on macOS with unbound and Cloudflare
June 24, 2020 Leave a comment
The DNS protocol traditionally runs over UDP on port 53. This is very fast but totally insecure. DNS queries can be snooped or potentially altered by anyone on the network. In my office, I use a pfSense firewall with the unbound DNS resolver configured to resolve DNS over TLS. That way my ISP neither my ISP nor the local government in Zimbabwe can observe or fiddle with DNS results.
In the olden days when I used to go places, I might use a VPN to secure all of my traffic. This is not always the optimal solutions. Sometimes, I know that all of my sensitive traffic is already encrypted and secure — except for the DNS. And I have had problems where DNS is intercepted by the ISP or hotel for advertising or other purposes. I found this particularly useful when we were staying with family last summer who have Cox Internet that does some goofy thing with DNS interception.
Unfortunately, macOS does not have DNS over TLS or DNS over HTTPS as a built in feature, yet. But I can set up unbound
as a DNS resolver which does support DNS over TLS.
sudo port install unbound
unbound has the following notes: An example configuration is provided at /opt/local/etc/unbound/unbound.conf-dist. A startup item has been generated that will aid in starting unbound with launchd. It is disabled by default. Execute the following command to start it, and to cause it to launch at startup: sudo port load unbound
cd /opt/local/etc/unbound
sudo cp unbound.conf-dist unbound.conf
sudo vi unbound.conf
Find the “# forward-zones” section and insert the following:
forward-zone: name: "." forward-tls-upstream: yes # Cloudflare DNS forward-addr: 2606:4700:4700::1112@853#cloudflare-dns.com forward-addr: 1.1.1.2@853#cloudflare-dns.com forward-addr: 2606:4700:4700::1002@853#cloudflare-dns.com forward-addr: 1.0.0.2@853#cloudflare-dns.com
These are the Cloudflare DNS endpoints for DNS over TLS with malware protection. You can substitute alternate resolvers.
Now, if I want, I can start unbound and change my network config to use localhost as the DNS provider.
sudo port load unbound Password: ---> Loading startupitem 'unbound' for unbound $ sudo lsof -i :53 COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME unbound 85991 unbound 4u IPv6 0xe14e1013ac1fa599 0t0 UDP localhost:domain unbound 85991 unbound 5u IPv6 0xe14e1013da135451 0t0 TCP localhost:domain (LISTEN) unbound 85991 unbound 6u IPv4 0xe14e1013bac68b69 0t0 UDP localhost:domain unbound 85991 unbound 7u IPv4 0xe14e1013bb2dd361 0t0 TCP localhost:domain (LISTEN)
Now, I can change my DNS provider to 127.0.0.1 and my DNS queries will be resolved by my local and cached by my local unbound instance and securely forwarded to Cloudflare over TLS.
This setup can mess with captive portals. You may need to remove the 127.0.0.1 temporarily in order to authenticate to a guest WiFi system through their web page and then turn it back on.