I recently enrolled in the Android developer preview programme and got hold of the Android P (9 beta) OTA image for my Nokia 7 Plus phone, and while discovering what’s new, I found a new advanced option under network settings called ‘Private DNS’ that got my attention. This led to me finding an article from Erik Kline describing this new feature in Android 9, which to my surprise supports DNS-over-TLS (RFC 7858).
Last year we wrote about the experiments in the Go6lab with DNS-over-TLS where we set up a recursive DNS resolver listening on port 853 and serving DNS answers to queries encrypted with TLS. This setup was useful if your local DNS resolver was Unbound or Stubby, and since then I’ve been using Stubby as my local DNS client on MacOS with the Unbound DNS server at the Go6lab (privacydns.go6lab.si) as a recursive resolver for encrypted DNS queries without any issues.
So armed with the information from Erik, I decided to test out the Android implementation.
First thing was to turn on the setting and test it with the ‘privacydns.go6lab.si’ server which worked fine. Enabling ‘log-queries’ on the Unbound server quickly revealed that DNS queries are reaching the server and being properly resolved. Since ‘privacydns.go6lab.si’ port 853 is openly reachable from the Internet – you can test it as well.
Encouraged with this success, I thought of adding this functionality to the Go6lab recursive resolvers that I use on a daily basis, but this time it needs to listen on the standard DNS port 53 and as well as port 853 for DNS-over-TLS queries. Since we are running recursive resolvers in Go6lab on Unbound software, this was not a difficult task.
I had to install certbot, obtain a Let’s Encrypt certificate for the host, and add 5 new lines of configuration to unbound.conf…
interface: 0.0.0.0@853
interface: ::0@853
interface: 0.0.0.0@53
interface: ::0@53
ssl-service-key: “/etc/letsencrypt/live/recursive1.go6lab.si/privkey.pem”
ssl-service-pem: “/etc/letsencrypt/live/recursive1.go6lab.si/fullchain.pem”
ssl-port: 853
To make sure it’s also listening on port 53, I added the two lines ending with @53 as a precaution.
After rebooting the Unbound server, setting the ‘Private DNS’ setting on my phone to ‘recursive1.go6lab.si and briefly setting the ‘log-queries’ setting to ‘yes’, the first queries started to appear in the query log.
I was not sure whether queries were coming in over port 53 or 853, and therefore whether they were encrypted or not, so I used tcpdump to capture the traffic from the IPv6 address of my phone.
As we can see, traffic is flowing to and from port 853, indicating that our DNS traffic is being encrypted. Examining the tcpdump capture file with Wireshark reveals this is actually TLS 1.2 traffic and that the content of the packets is encrypted.
Most excellent I thought, but the problem is that with a pre-set ‘Private DNS’ server I would have issues when outside of the Go6lab network (or without a VPN connection back into it) as our DNS recursive resolvers are not reachable from outside to prevent DDOS attacks.
Well there’s a setting in ‘Private DNS’ that says ‘Automatic’ which is pretty opportunistic, and after switching this on, the phone tries to send the DNS query to port 853 and falls back to port 53 if there’s no answer. Observing this through tcpdump confirmed the automatic setting does exactly what is expected – it figures out whether DNS-over-TLS is working on our recursive resolvers and starts using it. This option doesn’t validate server names or hashes, but it makes sure it can negotiate TLS 1.2 (and probably also validates the certificate chain that’s provided). However, in ‘Strict Mode’, the system does additionally validate the hostname where this is entered.
The great aspect of automatic mode is that it does not lock you into one pre-set DNS resolving server, but uses whatever is provided when connecting to a different network. And it’s been confirmed by the user of a Pixel phone that this option is also present in the release version of Android 9 Pie, so this functionality will probably stick around in future versions of Android.
Implementation of this new privacy and security feature by the good people at Android is a big boost for making encryption the norm on the Internet, and opens the opportunity for network operators, DNS operators, VPN providers and everyone else running recursive DNS resolvers to quite easily add this functionality. Whoever connects to your network with Android 9 will automatically start using encrypted DNS service and will make sniffing of the queries at the transport layer a little bit more difficult for eavesdroppers.
With Unbound this is pretty simple – and in my next blog post we’ll be looking into how to enable DNS-over-TLS in Bind and some other DNS servers.
There are already few public recursive DNS resolvers currently supporting DNS-over-TLS on port 853 – Cloudflare on 1.1.1.1, Quad9 on 9.9.9.9, and also CleanBrowsing. But we’re also appealing to network operators and anyone who operates a recursive resolver to please add this functionality to your server. It won’t hurt as regular DNS clients will not even notice it, but for those whose operating systems can take advantage of port 853, it will benefit them a lot.
For more information about why DNS-over-TLS is important, the DNS Privacy Project has a good problem statement on its website, along with an explanation of the technical solutions.
Further Information