Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

DNS traffic can leak outside the VPN tunnel on Android #136

Open
3 tasks done
Mr-Hitchens opened this issue May 8, 2024 · 15 comments
Open
3 tasks done

DNS traffic can leak outside the VPN tunnel on Android #136

Mr-Hitchens opened this issue May 8, 2024 · 15 comments

Comments

@Mr-Hitchens
Copy link

Mr-Hitchens commented May 8, 2024

We are happy to answer your questions about the code or discuss technical ideas.

Please complete the following checklist (by adding [x]):

  • I have searched open and closed issues for duplicates
  • This isn't a feature request
  • This is not a report about my app not working as expected

Source: https://mullvad.net/en/blog/dns-traffic-can-leak-outside-the-vpn-tunnel-on-android

I am assuming PROTON is also vulnerable to this problem. How are you addressing this problem?
As PROTON hasn't updated F-Droid in nearly 5 weeks (Google play is up to date) I'm using a VPN that has addressed this issue as a temporary fix.
Is F-Droid not updated because F-Droid has a much more stringent gateway than Google and your app didn't pass inspection or something worse?

@Red00488
Copy link

Red00488 commented May 11, 2024

GrapheneOS latest OS release, currently in the Beta channel, implements a new feature for blocking DNS leaks by third party VPN service app implementations. The ProtonVPN app is reportedly having issues with the new feature.

GrapheneOS has stated "We'll give it another couple days of testing. Unless our users find an issue with another VPN app, we'll likely ship this to the Stable channel instead of cancelling the current change. We can't hold back an important improvement based on a single app which appears to be buggy."

https://grapheneos.social/@GrapheneOS/112422961319281582

@edthedev
Copy link

I'll be happy to help test any patch for this, if needed. When the Stable branch of GrapheneOS hits my phone, I imagine I'll have this issue.

@mateusz-markowicz
Copy link
Contributor

GrapheneOS latest OS release, currently in the Beta channel, implements a new feature for blocking DNS leaks by third party VPN service app implementations. The ProtonVPN app is reportedly having issues with the new feature.

We did some investigation into GrapheneOS issue and it'll be followed-up here:
GrapheneOS/os-issue-tracker#3442 (comment)

@thestinger
Copy link

It's still in our Beta channel and we don't plan to move it to Stable until we resolve this compatibility issue. It's strange that it only seems to be happening with Proton VPN and it doesn't imply that it's a bug in Proton VPN but it COULD be one where it was depending on a leak happening before. We aren't sure what's wrong yet.

@mateusz-markowicz
Copy link
Contributor

@thestinger we managed to reproduce it with some minimal generic VPN app, so it doesn't seem to be anything specific about the client itself. What seems to make the difference is the range our DNS server IP belongs to (10.2.0.1, it's not a public IP and it's accessible only via the tunnel) - if we change it to some public IP like 1.1.1.1 problem goes away - and maybe that's the usual setup for other VPNs (I didn't check that yet, so just speculating) and reason why they are not affected

@flawedworld
Copy link

@mateusz-markowicz do you think you could push this minimal app source code please?

My very vague and speculative hunch is that when the VPN is down, and the killswitch is set in the OS, you have a route for 10.2.0.0/24 in routing rules (or some other range where the DNS server is within it), and due to the VPN being down, and the DNS server being within that range, the OS drops all of that traffic, and there is some form of issue then occurring where it would normally fallback to using OS/user provided DNS server and this is what is breaking atm.

@mateusz-markowicz
Copy link
Contributor

@flawedworld I'll try to provide the source tomorrow (I'm off for today), but important to note that we observe this behavior on current GrapheneOS beta regardless of whether kill-switch is on or not and DNS starts failing only after VpnService.Builder.establish() when VPN is actually up - we see successful WireGuard handshakes preceding failing DNS queries.

@mateusz-markowicz
Copy link
Contributor

@flawedworld see https://github.com/mateusz-markowicz/minvpn-dns-issue/blob/master/app/src/main/java/proton/example/vpn/WireGuard.kt. We do there HTTPS call just before opening the tunnel (it works) and then a moment after opening a tunnel. If config will have our DNS (10.2.0.1) second call will fail. With some public DNS it'll work fine. @guandalf will contact you about the config

@thestinger
Copy link

See https://grapheneos.org/releases#2024073100. It should be resolved now in a way we won't have to revert.

@thestinger
Copy link

We have a fairly good idea why the behavior you saw was happening and leaving out enforcement for apps not configuring DNS should avoid the issue even though it was not caused by the app not configuring DNS. There's a code path which handles apps setting a netid that's not allowed which gets routed via the VPN DNS if it's configured instead, otherwise it leaks. We believe this code path not having the check will resolve the Proton VPN compatibility issue.

@thestinger
Copy link

We could try adding a toggle for blocking leaks when DNS isn't configured by the VPN which would likely be compatible with Proton VPN if we made it only check in that netid error path for the default network leak case instead of the forcing it via VPN case which has no reason to be blocked since it's forcing it through the VPN anyway. It's odd that Proton VPN would ever trigger this code path and that might be an Android bug that gets covered up by the error handling with no real consequence.

@thestinger
Copy link

Our Alpha testers are reporting compatibility issues with Proton VPN again, but not any other VPN apps so far.

@guandalf
Copy link

guandalf commented Aug 8, 2024

Hey @thestinger, which channel was the "mild" fix released on? I am on beta and could not reproduce the previous issue. Could you point me to the results of the findings of the Alpha testers? TY

@thestinger
Copy link

You can see our changelog at https://grapheneos.org/releases#changelog or through the Info app in the OS. The releases in Alpha, Beta and Stable are the same production releases. 2024080200 was the initial release with the relaxed fix we were successfully able to ship to Alpha, Beta and then Stable without having to revert it. This blocks connecting to non-VPN DNS. It does not block trying to connect to VPN DNS outside of the VPN, although if the VPN sets private addresses it won't normally get routed past the initial router. It's still problematic. We know how to fully prevent it since that's exactly what we did with our initial attempt in May, but that causes compatibility issues with Proton VPN.

You'll no longer be able to detect DNS leaks for sites/services because it does prevent using anything other than VPN DNS, but doesn't yet make sure that can't leak outside the tunnel. VPN DNS leaking outside the tunnel is rarer than what was happening before but it can still happen if it starts the process of doing a query and the VPN tunnel goes down. It should really enable leak protection there, but as I said it breaks Proton VPN. Proton VPN appears to depend on certain strangeness happening because it's written in a way that it appears to depend on an OS bug or something like that.

@thestinger
Copy link

Our strict DNS leak blocking approach was shipped again in the 2024102400. This time around, we included a fix for an Android error handling code path which is required to avoid breaking Proton VPN. Proton VPN triggers the fallback path by using a network it's not allowed to use for DNS queries which the OS sets to use the VPN tunnel when available. However, it was not routing it properly and it was being blocked as a leak with our strict DNS leak blocking. There are no more unicast DNS leaks in GrapheneOS as far as we're aware. The final fix is here:

GrapheneOS/platform_system_netd@7148a01

We also fixed all forms of multicast packet leaks from apps or generated by apps from the kernel separately from this.

All of these issues still impact standard Android, including with Android 15.

Our community discovered the unicast network DNS leaks but we found it also impacted the VPN DNS which is what our stricter DNS leak blocking takes care of. The same community member also found the multicast packet leaks from apps, but we found there were additional leaks from the kernel via system calls causing it to generate traffic.

Aside from this, we're working on doing similar leak blocking for other issues we discovered with mDNS on the local network, stricter inbound leak blocking and an eBPF filter bypass by selecting specific interfaces. We should have everything fully taken care of soon. There were a lot more issues than just unicast DNS leaks which are solved in GrapheneOS.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

7 participants