celzero / rethink-app

DNS over HTTPS / DNS over Tor / DNSCrypt client, WireGuard proxifier, firewall, and connection tracker for Android.
https://rethinkfirewall.com/
Apache License 2.0
3.04k stars 155 forks source link

WireGuard-tunneled Apps Are Unable To Resolve Private Domains #1327

Closed cohesive-flight closed 8 months ago

cohesive-flight commented 8 months ago

When an app is routed through a WireGuard tunnel, it's unable to resolve domains that point to a private IP address, despite "Do not route Private IPs" being enabled. It's able to reach it when using the IP directly, just not through its domain name. I've verified that it is using my local DNS server, so I believe this is a bug.

Also, a somewhat related question: how can I make apps within a WireGuard tunnel use the DNS server specified in the WireGuard config while in advanced mode? They use it in simple mode, just not in advanced.

ignoramous commented 8 months ago

how can I make apps within a WireGuard tunnel use the DNS server specified in the WireGuard config while in advanced mode

Can't, as on Android, DNS servers are applied to ALL apps, but WireGuard in Advanced mode allows one to select only a few apps. Hence, the default we stick with is, in Advanced mode, user-set DNS is used.

If in Advanced mode, setting Always-on would have Rethink route user-set DNS (DoH, DNS53, DoT, ODoH, DNSCrypt) through that Always-on WireGuard (if there are multiple, one is chosen at random) if Never proxy DNS (in Configure -> DNS) is also turned OFF.

unable to resolve domains that point to a private IP address, despite "Do not route Private IPs" being enabled

In Simple mode or Advanced mode? What's the domain look like?

Do not route Private IPs doesn't deal with domains resolving to Private IPs for reasons that by looking at a domain name, Rethink can't know if it'll be answered with a Private IP.

And so, only the TLDs that end with .local (assumed to reply with Private IPs) are sent to System DNS regardless of any configuration user might set.

cohesive-flight commented 8 months ago

Can't, as on Android, DNS servers are applied to ALL apps

That's unfortunate.

In Simple mode or Advanced mode? What's the domain look like?

It occurred in both, and the domain was a subdomain of home.arpa (i.e. dashboard.home.arpa).

Do not route Private IPs doesn't deal with domains resolving to Private IPs for reasons that by looking at a domain name, Rethink can't know if it'll be answered with a Private IP.

I don't believe this is accurate. I'm unclear on why, but the issue was due to having "Advanced DNS filtering" enabled. With it disabled and the "Do not route Private IPs" option enabled, apps tunneled through WireGuard are now able to resolve domains that point to a private IP address. This confirms the option does deal with private domains, as all Rethink has to do is verify if the IP address the DNS server replies with falls within the private IP address range.

Though I'd like to ask, what was the use case for it before WireGuard was implemented? Apps that weren't excluded were able to communicate with local services without it enabled, and still are as long as they're not WireGuard-tunneled.

Edit: I recalled you answered this in my other issue #1061

A few folks turn "Do not route Private IPs" ON to specifically block LAN connections with VPN in Lockdown ("Block connections without VPN")

ignoramous commented 8 months ago

dashboard.home.arpa

This must have been sent to System DNS. .arpa won't be resolved by System DNS (it isn't in our "undelegated domains" set). Btw, You can see the server a particular DNS query is sent to in DNS Logs by tapping on the entries in there (which bring up a bottomsheet).

Should we add home.arpa to undelegated domains (domains which are always resolved by System DNS)?

issue was due to having "Advanced DNS filtering" enabled. With it disabled and the "Do not route Private IPs" option enabled, apps tunneled through WireGuard are now able to resolve domains that point to a private IP address

So private domains work now as expected? And it was Advanced DNS filtering causing issue? I can see why that can be. I'll fix it, right away.

cohesive-flight commented 8 months ago

You can see the server a particular DNS query is sent to in DNS Logs by tapping on the entries in there (which bring up a bottomsheet).

It displays two queries: 'IPv4' and 'HTTP Service Binding'. Both are shown to be from my local DNS server and have question marks as their icons.

Should we add home.arpa to undelegated domains (domains which are always resolved by System DNS)?

I don't think that's necessary. It works perfectly fine now with my user-defined DNS proxy within Rethink. Additionally, I've had issues with Rethink crashing when using System DNS alongside WireGuard a few months ago (I recall creating an issue for it and sending logs, but I can't seem to find it), so I'd like to avoid having to use it.

So private domains work now as expected? And it was Advanced DNS filtering causing issue?

Yes, and yes.

I can see why that can be. I'll fix it, right away.

Could you explain how this feature works? And why it'd have an issue with private domains specifically?

ignoramous commented 8 months ago

Could you explain how this feature works?

Advanced DNS filtering substitutes IPs in DNS answers with its own IPs (from 100.64.y.z for IPv4 and 64:ff9b:da19:100::w.x.y.z for IPv6). If more than one domain name (ex: example.net and example.com) resolves to the same IP (say, 192.0.0.1), then both will get different IPs (from the 100.64.y.z range for IPv4) if Advanced DNS filtering is enabled, hence making it trivial to map a given IP with a domain name. Rethink takes care of translating those unroutable IPs (100.64.y.z and 64:ff9b:da19:100::) to real IPs transparently, at connection time.

On Android, DNS resolver is common to ALL apps and identity of the app is hidden from the resolver. But at connection time (TCP/UDP requests), the identity of the app is known. Given that limitation, in the future, we want to extend Advanced DNS filtering to do "just-in-time DNS resolution". That is, vend out these unroutable IPs in response to DNS queries, then at connection time, when the identity of the app is known, choose a DNS server to resolve to a real IP depending on the identity of the app making the connection.

And why it'd have an issue with private domains specifically?

My guess is,

ignoramous commented 8 months ago

It works perfectly fine now with my user-defined DNS proxy within Rethink.

It works because you've setup Rethink to use System DNS. Rethink automatically sends "undelegated" domain names to System DNS but home.arpa isn't part of that list (.local, for example, is).

Additionally, I've had issues with Rethink crashing when using System DNS alongside WireGuard a few months ago (I recall creating an issue for it and sending logs, but I can't seem to find it), so I'd like to avoid having to use it.

Which version was it? We noticed a few undebuggable, hard to reproduce crashes with System DNS in v055b (with or without WireGuard) that we couldn't figure out the root-cause for. Then, we overhauled how System DNS worked in v055c and in v055d and haven't seen this crash since.

I don't think there ever was a System DNS related crash files here on GitHub. If you sent email, probably we did not pay attention to it (we get tonnes and can't reply to them all, but we try to read them at least, and I doubt a crash-related email would have gone unnoticed).

cohesive-flight commented 8 months ago

It works because you've setup Rethink to use System DNS.

It's using "Other DNS", and from there my user-defined DNS proxy that points to my local DNS server. System DNS is the DNS server the phone normally uses, which more often than not is the one defined in your network, correct? It's currently set to my ISP's, not mine, so it shouldn't be possible for any app tunneled through Rethink to resolve my private domains if it was using System DNS.

Which version was it? We noticed a few undebuggable, hard to reproduce crashes with System DNS in v055b (with or without WireGuard) that we couldn't figure out the root-cause for.

I managed to find the issue (#1030). It was version 055a. I doubt it's still an issue now, but I'll try testing it out later.

ignoramous commented 8 months ago

I managed to find the issue (https://github.com/celzero/rethink-app/issues/1030). It was version 055a. I doubt it's still an issue now, but I'll try testing it out later.

This one took us quite a while to fix. It was fun. I'll close the issue.

System DNS is the DNS server the phone normally uses, which more often than not is the one defined in your network, correct?

Yes: One defined by WiFi / Mobile / Android itself (in rare cases) / the "Fallback DNS" as set in Network -> Choose Fallback DNS (in cases where WiFi / Mobile DNSes are not available).

It's using "Other DNS", and from there my user-defined DNS proxy that points to my local DNS server.

Gotcha. I'll resolve this issue then? Feel free to reopen if there's something Rethink must do to handle .arpa domains. We also intend to let users select DNS providers per hostname, but the problem is the UI/UX as the underlying code already supports doing so: