iOS 15 - Tailscale overrides local DNS when using exit nodes

On an iOS device running iOS 15 and Nextdns (iOS client), which I can confirm is working correctly by visiting test.nextdns.io and seeing that it’s connecting to Nextdns servers via DoH.

With “Override local DNS” disabled in the Tailscale admin panel, and MagicDNS nameserver set to 1.1.1.1 (Cloudflare), Tailscale still appears to be overriding local DNS in certain situations:

  1. Start out with Tailscale disconnected - visit test.nextdns.io to confirm Nextdns DoH is working as expected.
  2. Connect to Tailscale and revisit text.nextdns.io - Nextdns DoH still working correctly.
  3. Connect to an exit node and revisit test.nextdns.io - DNS is no longer being done over Nextdns
  4. Visit dnsleaktest.com - confirm DNS is happening over Cloudflare and not Nextdns DoH as expected.

As far as we can see that is a behavior change in iOS:

macOS & iOS: VPN Conflict

When a VPN is connected, the Encrypted DNS profile is ignored in favor of the DNS server advertised by the VPN with no option to change this behavior. The DNS profile is still shown as active in the OS settings, which is confusing for the user.

We believe that Encrypted DNS should be part of the traffic going through the VPN as it is the case on other platforms. If you agree, please submit your feedback to Apple using Feedback Assistant.

Status: reported, probably won’t fix

The NextDNS iOS app worked by implementing itself as a VPN and relying on a behavior in iOS that allowed two VPNs to be functional: one supplying DNS settings, the other supplying connectivity. Apple changed that behavior, only one VPN can be active and supplies both DNS and connectivity.

Thanks for that. I’m not sure this quite covers the issue I’m seeing though, because it only happens when a Tailscale exit node is selected. When just connected to Tailscale but not an exit node, ios still views this as a VPN being active, but Nextdns still works as expected.

The exit node itself is also running the Nextdns cli, and there’s nothing about the config of the exit node that would make it use Cloudflare for DNS. Seems the only reason it’d be using cloudflare is because the Magicdns nameserver is set to 1.1.1.1 - i.e. dns is being determined by magicdns rather than the exit node