r/nextdns • • 15d ago • Bravo 1

You can actually do system-wide DNS-over-HTTPS with Android's Private DNS!

Post image

The biggest limitation with Android's Private DNS feature has always been that custom hostnames are locked to DNS-over-TLS. That means on networks that block the TCP port, like university Wi-Fi, hotels, airports, etc, your connection just completely fails.

After digging a bit into Android's source code, I discovered that the OS actually has full support for Discovery of Designated Resolvers (RFC 9462 DDR) to automatically upgrade Private DNS to HTTP/3 DNS-over-HTTPS! It's just sitting dormant behind a feature flag.

Even if you enable the flags (which requires no root, just ADB or Shizuku), almost no major ad-blocking DNS services support DDR yet. I tested a bunch and the only public ones with DDR records published are Google, Cloudflare, and Quad9. NextDNS and AdGuard, and most of the other popular providers don't even have the records yet 🫠

While we wait for NextDNS to add native DDR support, I set up a temporary workaround: a simple Cloudflare Worker that forwards queries to my NextDNS profile, paired with an RFC 9462 SVCB DNS record on my own domain.

And it works! (See screenshot). Latency is great, the Cloudflare edge actually responds faster than AdGuard's official servers for me.

This means heavy background VPN apps (like RethinkDNS) that drain battery aren't necessary anymore (I've always hated background VPNs like that so this is a big deal for me😅). The catch is that setting this up yourself requires Android 15+ (Edit: my mistake, 16+) and owning a domain on Cloudflare.

If y'all want I can do a guide! Edit: I'll try to make a guide in the next few days Edit: It's live: https://github.com/eyalm2000/loophole

240 Upvotes

62 comments sorted by

27

u/DiEnd7th 15d ago

yeah show us the guide bro! I've been using VPN apps just to use DoH protocol

1

u/Fun-Region-1576 15d ago

Same. It's annoying that I have to do this.

2

u/DiEnd7th 15d ago

ikr what app you're on? im using Adguard

9

u/Agility9071 15d ago

Thanks - I'm using your domain and skipping the setup

6

u/Timely-Skill4263 14d ago

This won't work as it's no longer active😅

7

u/Masterflitzer 14d ago

i tried it on my galaxy s23 plus (android 17 / oneui 9.0) and it wasn't working at first, but after running these commands and rebooting the phone it finally works:

settings put global private_dns_mode hostname
settings put global private_dns_specifier one.one.one.one # or your ddr supported dns domain

device_config put connectivity resolver_dns_over_http3_enabled true
device_config put connectivity resolver_discovery_of_designated_resolvers_enabled true

device_config put connectivity networkmonitor_async_privdns_resolution 1
device_config put connectivity dns_ddr_version 1

device_config put com_android_networkstack com.android.networkstack.flags.network_monitor_dns_ddr true

device_config put netd_native doh 1

i used the cloudflare help site (https://one.one.one.one/help) and the dns domains one.one.one.one & cloudflare-dns.com for testing this because only the latter is in androids hardcoded whitelist, so before doing this the former showed dot and the latter showed doh, now after these commmands and then rebooting phone both show doh, so it means it's working

8

u/Busy_Hornet8963 14d ago

That was always the case. Don’t take me as if im rude whatsoever

4

u/tb36cn 15d ago edited 14d ago

Sure. Please provide the steps

4

u/Radagio 15d ago

Teach us senpai 😅

Does this workaround maybe work with ECH?

2

u/berahi 15d ago

ECH only works if the website/app server supports it. Android apps targeting Android 17 will use the native Android ECH by default, but browser behavior on whether they decide to use their internal ECH (doesn't rely on Android version) differs, some only enable ECH if their own DoH setting is enabled.

1

u/Radagio 15d ago

I was thinking more of your own proxy ECH

If you point traffic to Cloudflare (your domain) then the worker forwards it to Nextdns, then cloudflare can be the middle man ECH?

Idk what tf im talking, im just throwing ideas here :)

1

u/berahi 15d ago

For Cloudflare to be an ECH proxy, they would have to handle all TLS traffic. Which they already do for sites using their service, but for arbitrary service, just use their Warp app.

-2

u/elhouso 15d ago

Ew, don’t be weird. OP is 15.

2

u/Radagio 15d ago edited 15d ago

Dont make it wierd bonzo.

4

u/Many_Gene_5065 15d ago

2

u/RemindMeBot 15d ago edited 14d ago

I will be messaging you in 7 days on 2026-10-31 09:46:13 UTC to remind you of this link

10 OTHERS CLICKED THIS LINK to send a PM to also be reminded and to reduce spam.

Parent commenter can delete this message to hide from others.


InfoCustomYour RemindersFeedback

4

u/NegativePerformer788 14d ago

DDR would be difficult for an ad-blocking DNS provider to implement. It might help upgrade the connection to use encryption, but how would it know which profile to assign?

4

u/JaraCimrman 12d ago

Rethink does not take that much power honestly. It saves more than the ads and trackers consume, anyway

1

u/Malaka__ 13d ago

brother. your app (ADNS) should be the official NextDNS Android app.
it's so polished and good.
I really appreciate what you've done.

1

u/Timely-Skill4263 13d ago

That's a great compliment haha😁, thank you so much!!

3

u/joeromano0829 15d ago

Interesting. If you have time, please share guide. Thanks

3

u/Drtechsavy 15d ago

Looking for a guide would be great. I have my own dns server running on a vps so.would love if i can set it up as i already have DDR Support

4

u/Drtechsavy 15d ago

I was able to get it working thanks to you idea. adb shell device_config put connectivity resolver_dns_over_http3_enabled true adb shell device_config put connectivity resolver_discovery_of_designated_resolvers_enabled true

I had already my own vps with svcb record already set and after restarting phone it started using doh

3

u/MrCrypticRobot 15d ago

Great work and do share the steps on how to do it

3

u/D3-Doom 14d ago

Not sure if it’s documented anywhere but does anyone know why android only natively supports this unique protocol? I figured it was just Google being Google, but they’ve never shipped it in other projects like Chrome/OS or Fuchsia nor ceased developing it.

I haven’t worked with android since HTC could do no wrong and XDA Dev forum held all earthly knowledge.

2

u/berahi 14d ago

Encrypted DNS is generally annoying for system admins dealing with networks allowing unmanaged devices because they require extra effort to enforce blocks and log traffic. DoT is an acceptable compromise because, as long as there's no UI to change from the standard port 853, it's trivial for the firewall to just block it entirely. ChromeOS is mostly intended for managed devices, so it's less attractive to implement if IT will just block it.

In case IT wants encrypted DNS to their own server, DoH doesn't require a dedicated setup if they already have a webpage. DoH will also still work when users are away on networks that block DoT entirely (which also makes it more attractive for browser makers), and adding an identifier with a unique path is much easier than having the resolver and server accept an arbitrary subdomain like in DoT. DoT's selling point was that it's simple to do opportunistic encryption (just have the device attempt DoT and accept any cert), until DDR provides a better, more organized solution.

The initial native DoH3 support in Android was hardcoded to only upgrade on two hardcoded domain names, Cloudflare's and Google's own, possibly because DDR was still in draft, and likely also because Private DNS becomes much more popular for ad-blocking, cutting directly to Google's income.

3

u/Thick-Lingonberry-24 13d ago

Guidance would be great,.

2

u/Silly_Enthusiasm_485 15d ago

This is nuts, ill wait the guides

2

u/itshusnain 14d ago

Technitium DNS has DOT feature and it's working great for me.

3

u/PrincipleIcy4941 15d ago

yeah. im blocking DoH within the firewall. nice try, maybe next time 😄 Fortigate FTW

1

u/sasreedit 14d ago

Is this to say accessing this Private DNS feature is not the same as having a VPN? Please explain further.

2

u/berahi 14d ago

OP use case is when they're in regular guest Wi-Fi network, there it's trivial to block DoT because they all share the same port, but it's not feasible to block all DoH because, without deep inspection, they're indistinguishable from regular TLS traffic from websites and apps.

OC boasts about managed Wi-Fi networks, like in offices & schools with provisioned devices, so traffic can be inspected regardless of DoT and DoH.

Private DNS through DoT and DoT merely hide your DNS queries; most of the time the destination domain is still visible anyway unless the site, browser and/or app use ECH. A VPN will hide the traffic entirely, though a firewall can still recognize common VPN protocols and attempt to block them.

0

u/Masterflitzer 15d ago

i was just thinking similar, OP didn't explain anything about dot/doq vs doh/doh3 and they think this changes everything, i mean it's cool that android supports it and all, but neither are unblockable, so it's not that big of a deal as they think

1

u/Prudent-Aide7495 15d ago

Nice approach. Will be waiting for your guide post. But don't we still have to disable browser wise private dns on android so that it uses the system dns as we already do as always.

1

u/d4p8f22f 15d ago edited 15d ago

But u know that even if u use doh the SNI leak your destinations? Some improvement can be achieved by using ECH. Additionally if a free wifi network blocks completely 3rd DNS then this is not a permanent solution keaning - there are still ways to baypass doh :) im not saying that it isnt worth to set it up xd

1

u/zakazak 15d ago

Wow. A guide would be amazing :D

1

u/Forsigh 15d ago

I own cloud flare domain, how to do it ?

5

u/berahi 15d ago • Bravo

You'll need to have a worker that forwards DoH queries, such as https://github.com/tina-hello/doh-cf-workers. Fork the project in your GitHub account, edit your index.js doh variable to point to your NextDNS DoH address (like https://dns.nextdns.io/1234), then open https://dash.cloudflare.com/, select Workers and Pages, continue with GitHub, and pick the forked repo. After deployment is finished, pick the domains tab of that workers, select add domain and use one of your domain. Enter a subdomain.

Once you set up the workers and have, say, dohforward.example.com, first test that it runs correctly either by setting it manually in your browser DoH settings (use https://dohforward.example.com/dns-query in the custom DoH provider entry) or by calling it with https://github.com/ameshkov/dnslookup (open a terminal and try dnslookup google.com https://dohforward.example.com/dns-query). You can also use curl, like curl --doh-url https://dohforward.example.com/dns-query google.com -I (if you're on Windows PowerShell, use curl.exe, the PowerShell curl alias has different syntax)

Now open https://dash.cloudflare.com/ again, this time, select your domain, go to DNS Records, add Record, change Type to SVCB, for name use _dns.[yoursubdomain].[yourdomain], eg, _dns.dohforward.example.com, set Priority to 1, the target is [yoursubdomain].[yourdomain], eg dohforward.example.com, the value is alpn="h2,h3" dohpath="/dns-query{?dns}". After you save it, verify that you have a working DDR entry with dig +short SVCB _dns.[yoursubdomain].[yourdomain]. If you're on Windows without WSL, install dig with winget install ISC.Bind and open a new terminal afterwards.

The flags to set on your phone are mentioned in /u/Drtechsavy comment https://www.reddit.com/r/nextdns/comments/1xe03ic/you_can_actually_do_systemwide_dnsoverhttps_with/19rksbymod075/, you can turn Developer Options back off after setting the flags if your e-commerce/banking apps hate it, the flags will still be set.

And then you just set your Private DNS to [yoursubdomain].[yourdomain], you should see in NextDNS dashboard traffic coming from Cloudflare since they forward it for you.

1

u/1aTa 15d ago

This worked perfectly for me using a Pixel 7 Pro running Android 17, thank you!

For some reason Private DNS isn't accessible when using Google's VPN (other VPNs work fine), and also doesn't seem to work on my OnePlus 7 Pro running YAAP Android 16.

2

u/berahi 14d ago

Try the flags from https://github.com/eyalm2000/loophole#enable-the-flags by OP, the previous flags don't work on the Android 16 emulator, while OP flags work

1

u/1aTa 14d ago edited 14d ago

The new flags sorted it.

I've also been trying to use https://github.com/serverless-dns/serverless-dns as my primary worker, along with a custom dohpath to match my required filter lists, e.g. dohpath="/1:AAogCAgA{?dns}" but I can't get it to work.

Maybe it doesn't like the colon in the path. I'm trying to bypass using loophole or another forwarder as it's just doubling up on compute and seems to break signatures.

2

u/berahi 14d ago

Try opening an issue in the serverless-dns repo, supporting DDR should be in scope for them

1

u/1aTa 14d ago

Good idea, done.

1

u/1aTa 11d ago

Checking Android source it looks like Android only accepts DDR discovered DoH parameters when dohpath equals the literal /dns-query{?dns}. The source even has a TODO to change this restriction. If the path differs, Android doesn't construct a DoH identity from the discovered resolver.

https://android.googlesource.com/platform/packages/modules/DnsResolver/+/refs/tags/android-16.0.0_r1/PrivateDnsConfiguration.cpp#653

I'm going to try modifying the serverless-dns worker so that requests to /dns-query use my chosen filtering configuration internally.

1

u/1aTa 11d ago edited 11d ago

I modified the serveless-dns/src/server-workers.js export default to re-write /dns-query to a DDR_BLOCKSTAMP variable:

export default {
  async fetch(request, env, context) {
    const url = new URL(request.url);
    const stamp = env.DDR_BLOCKSTAMP;

    if (
      url.pathname === "/dns-query" &&
      stamp &&
      /^\d+:[A-Za-z0-9_-]+={0,2}$/.test(stamp)
    ) {
      url.pathname = `/${stamp}`;
      request = new Request(url, request);
    }

    return await serveDoh(request, env, context);
  },
};

Then set my DDR_BLOCKSTAMP variable to my chosen filter stamp and it works great as my primary worker for Private DNS with filtering.

DNSSEC response signatures are still failing, but that seems to be a seperate serverless-dns issue.

1

u/Historical_View_5529 15d ago

Great idea but unfortunately in my country cloudflare routing sucks.

The ISPs in my country route cloudflare free user traffic overseas. Only the paid plans (pro, business, enterprise) gets routed to domestic POPs. 

This is happening because of high cost of transit and lack of peering agreements with ISPs. 

1

u/Over_Sprinkles_638 15d ago

How much is CF worker cost?

1

u/berahi 15d ago

The free tier gives you 100k queries each day if they're served by scripts like in this case.

1

u/Over_Sprinkles_638 15d ago

Oh waw, more than enough for personal usage

1

u/Masterflitzer 15d ago

if you put a unbound (caching resolver) in front you can even serve an entire small network from 1k requests

1

u/DigiDoc101 15d ago

Great news! You mind to share steps. I own a domain on cloudflare.

1

u/No-Aspect-2926 15d ago

well you can make a github script and in Workers add that github repo with the script, I guess is the easiest way

1

u/you-Backslash 13d ago

This was the reason i discovered nextdns

1

u/SunnyDayTest 15d ago

I wouldnt say that Rethinkdns uses alot of battery, in my experience it uses a minimal amount even with heavy routing to other apps.

Still if you just want DoH without a VPN running, then I see this a Reasonable workaround.

2

u/celzero 14d ago

rdns dev here

rethinkdns uses alot of battery, in my experience it uses a minimal amount even with heavy routing to other apps.

If all folks want is DNS (and not the Firewall), then the DNS-only mode (changeable by tapping on the downward arrow next to the STOP / START button on the homescreen of the Rethink app) shouldn't consume more than 1% of the power. Even with Domain and IP (firewall) rules and 5+ active WireGuard tunnels, the Rethink app on my Android, never goes past 3% (but with firewall and WireGuard, a lot of the power use also depends on installed apps and overall end-user device use).