DNS Search Domain Ignored on Android

(I edited this on 10/21 to provide more info)

My Use Case

I use ZeroTier to create a VPN which I share with ~15 friends so that they can access services I host, such as game servers and websites. I run my own DNS (Technitium) which only listens on the ZeroTier network.

I have my own domain (example.net) which has a few publicly exposed services. My DNS server has A records that override specific subdomains to point to within the network. For example, foo.example.net is a public service I host, so my DNS server simply forwards this request to Cloudflare (1.1.1.1). bar.example.net is a website behind a reverse proxy, both of which run within my ZeroTier network, so my DNS server has an A record which resolves to the VPN IP of my web proxy.

In my ZeroTier network’s settings, I have set example.net as my search domain and the server is the IP of the Technitium DNS server. This configuration works perfectly for Windows and Linux clients. All DNS traffic goes through their existing connection’s DNS settings and anything relating to example.net is sent to my server. I can verify this by checking the logs of my DNS server and seeing that only requests for my domain are being handled.

In the interest of privacy, I do not want to handle DNS queries for things unrelated to my internal services. To enforce this, my Technitium server simply has no forwarders and so it will timeout and not resolve any domain outside of the example.net zone. This isn’t necessary since the configuration already does not allow this to happen, but I’ve simply done this so that it can be easily identified when a client is incorrectly using my DNS server for whatever reason. Again, for Windows and Linux clients, they understand the search domain and never query my server for things outside of example.net.

The Issue

The TLDR is that Android doesn’t seem to understand the search domain like desktop clients do. It will try to route all DNS through the specified server (my Technitium server) instead of only the requests which match the search domain.

Expectation

With a server and search domain specified in a network’s DNS settings, Android clients should be able to resolve external domains through their existing connection and have domains matching the search domain routed to the specified server, just how it would work for Windows/Linux clients.

Reality / The Issue

When DNS Configuration is set to Network DNS on the ZeroTier One app, all DNS traffic is routed to the specified server regardless of the search domain.

In my specific configuration, this means that my internal services are the only things that resolve. You can now visit my websites like bar.example.net, but not google.com.

Observations

  • Windows and Linux clients are not affected and have the expected behavior.
  • Android clients will route all DNS queries to the server specified in the network’s settings.
  • When my DNS server is specifically queried when doing a request (I’m using the Ping & Net app to accomplish this), the domains will resolve and I will get the expected IP address.
  • Selecting Network DNS during the app’s Add Network process does not make a difference vs. adding the network then switching the DNS settings.
  • Trying Custom DNS instead of Network DNS and specifying combinations of both my DNS server’s IP and known-good public DNS servers like 1.1.1.1 or 8.8.8.8.
    • When my DNS server is set before the known-good server, not even the ZeroTier app can connect to the network.
    • When the known-good DNS server is set before my server, all queries go through the known-good server and my internal domains don’t resolve.
  • Issue always persists on every Wi-Fi network I’ve tried and over cellular.

Steps Taken

  • Turning off Android’s private DNS feature.
  • Toggling Android’s Always-on VPN setting for ZeroTier One.
  • Tested on Samsung’s OneUI and Google’s Android.
  • Searching online for about 5+ hours.

I’m not really sure what the issue is here or if this even is an issue. I’m not finding a lot of information about this but I’ve found two posts about this issue with no replies, so I’m just trying to get some closure on this. Is this a bug? Is this expected? An Android limitation? An upcoming feature/fix?

The main reason I want this feature is because, well, it already works on Windows and Linux (and I believe macOS as well). I’ve effectively been able to create my own mini-web on my ZeroTier network thanks to the search domain feature, so the fact that it’s not working on Android has really been unfortunate as I can’t use my DNS server to resolve hostnames for my privately hosted services. Really just seems like a bug unless Android is limiting this functionality in some way.

Other posts with similar issue:

I’m having the same issue, were you able to figure it out?

I have not been able to figure out what’s going on here. This forum post was kind of my last resort and I was hoping others with more knowledge or experience would let us know what’s going on here. I’m not sure if this is a limitation of ZeroTier, of the Android OS, or if it’s a genuine bug.

Pretty sure this is probably a bug if there is no other explanation. Other apps like tailscale don’t have an issue with domain based split dns on Android.

I have opened a ticket…

https://github.com/zerotier/ZeroTierOne/issues/2400

Feel free to comment as well to bring attention to this issue.

Thanks for opening an issue there. I’m happy to see we’re not the only ones experiencing this. Hopefully some eyes get on this soon so we know what’s going on.

For now, I have resorted to the not-so-pretty solution of having my A records for my internal services on my public DNS nameservers and just doing away with the search domain.