mullvad / mullvadvpn-app

The Mullvad VPN client app for desktop and mobile
https://mullvad.net/
GNU General Public License v3.0
5.12k stars 339 forks source link

Feature request: Per-domain split tunneling #4529

Closed namazso closed 4 months ago

namazso commented 1 year ago

So parts of this request have a couple issues in various states (opened/closed/reopened) here, but not a single one that defines all components of a working user-friendly solution. So I figured I could open one that clearly outlines a solution that can be implemented.

I think the use-case itself is pretty obvious - there might be sites that are geo-restricted, or restricted to specifically your network, disallow VPNs, and a lot of other scenarios that would take too much time to enumerate.

Parts needed for a working solution

SOCKS proxy

The easiest way to split-tunnel on the OS level is per-process, which the Mullvad app already supports. The best solution to have an option to bypass the VPN in a browser-controllable way is to run a local SOCKS proxy as a separate process, and exclude it via the per-process split tunneling. Ideally, this SOCKS proxy would only proxy sites that were selected by the user.

Proxy auto configuration (PAC) script

The best method to seamlessly control what SOCKS proxy a browser uses for what domain is by using a PAC file. An example can be found here: https://superuser.com/a/1302569

Minimalistic HTTP server

Windows 10 and later no longer allows file:// URLs for PAC files, so a HTTP server is needed to host them. This also helps automatically changing contents if the user changes their settings.

UI

Something to enable per-site splitting, and to configure the domains.


As you can see currently setting this up for an end-user is quite complicated. If the Mullvad app could provide this out of the box, it'd be a great UX improvement.

faern commented 1 year ago

To be clear, what you are requesting is per domain split tunneling in a browser? Which is very different from system wide per domain splitting. All internet connected non-browser programs also use DNS to figure out where to go.

Let's say you run slack (just a random example) both in your browser and the standalone desktop app. And you add *.slack.com to the list of excluded domains. Do you expect both the desktop client and the web app to go outside the tunnel, or just the slack instance in the browser?

Doing per domain split tunneling on the entire system is way harder. Multiple domains can resolve to the same IP. So if inside-tunnel.com and outside-tunnel.com resolve to the same IP, do we send the traffic to that IP inside or outside the tunnel? For http that can be figured out via the Host header field. But if the site is using https with encrypted host headers, this becomes impossible.

So the only viable solution is to do this at the browser level. Having the browser determine the exclusion, since it knows which domain each request is destined for.

For your use case, we generally recommend having one excluded browser and one non-excluded browser. And just visit the sites you wish to visit outside the tunnel in the excluded browser. But I agree it could provide some benefit being able to do this in one browser.

namazso commented 1 year ago

To be clear, what you are requesting is per domain split tunneling in a browser?

.. kinda. The primary goal would be that, but Windows does proxies system-wide, for every program that uses WinHTTP or WinINet, so you'd end up doing it for slightly more.

Do you expect both the desktop client and the web app to go outside the tunnel, or just the slack instance in the browser?

I haven't checked if Electron inherits the system proxy settings (as Chrome can do that even though it doesn't use the mentioned APIs), but I'd only expect it to be guaranteed to work with a browser.

For your use case, we generally recommend having one excluded browser and one non-excluded browser. And just visit the sites you wish to visit outside the tunnel in the excluded browser.

Yep, that works, but is quite an annoying experience, especially with external links that you now have to copy-paste over.

faern commented 1 year ago

We don't want to implement something that is going to work very randomly. If an app ending up inside or outside the tunnel depends on what socket libraries they build upon, it's not a good solution in my book. If we implement something we want it to be reliable and consistent.

namazso commented 1 year ago

Hm.. I mean, that's also true for the current solution, the per-process split tunneling is easy to bypass, if you just use the filesystem redirectors like the webdav redirector. Just try excluding explorer.exe and accessing a WebDAV folder like \\live.sysinternals.com@ssl\DavWWWRoot. It's just a tiny bit more of an edge case, but it's the same deal.

And I don't think removing the current split tunneling due to that would make sense.

paperclip-dayo commented 1 year ago

@faern Honestly even having a basic IP/CIDR split tunneling like the Wireguard AllowedIPs one would be a huge improvement to the current split tunnel implementation. It gets very annoying having to constantly toggle split tunnel on the browser on and off since more and more websites blacklist VPNs. Keeping a second browser open 24/7 is not ideal either because it's a waste of the system resources. Ideally allowing users to point to a txt file that contains a list of IPs and ranges to be split-tunneled.

faern commented 1 year ago

It gets very annoying having to constantly toggle split tunnel on the browser on and off since more and more websites blacklist VPNs

How is excluding IP ranges going to solve this? How do you intend to set it up? Manually keeping an up to date list of what IPs belong to certain IPs sounds very cumbersome.

Keeping a second browser open 24/7 is not ideal

Why do you need to keep it open all the time? You should be able to launch it when you need it. Will be a bit different depending on which platform, but definitely doable.

paperclip-dayo commented 1 year ago

Whitelisting IPs would allow me to access certain resources bypassing the VPN. Of course it's far from ideal solution and can be troublesome to keep up with the websites that rely heavily on CDNs but it would be nice still to have more options for split-tunneling purposes even. The better way (for me) would be something similar to the OP's idea of having a dummy proxy running that bypasses the VPN so that a user can use that proxy's IP:port in the app to bypass the VPN, like a SOCKS5 bypassing VPN. I'm just assuming that adding a IP/CIDR whitelist would be an easier solution, but then again I'm not a software dev so I could be totally off the mark with this.

Why do you need to keep it open all the time? You should be able to launch it when you need it. Will be a bit different depending on which platform, but definitely doable.

I agree but it's a matter of convenience. Launching the second browser back and forth is inconvenient just like having to add/remove and app from split-tunnel back and forth. As an isolated thought, it would've been nice to at least have a right-click menu on the taskbar icon which would allow to quickly toggle the split-tunnel for apps, kind of like how standalone Wireguard app does with the "tunnels" list where you can quickly (dis)connect from the server. I could be wrong but I feel like I read that mullvad had plans to do a total rewrite of the app in the future so maybe taskbar quick access menu concept is vaguely on the roadmap somewhere, well, assuming the app rewrite is something that's still being considered :)

faern commented 1 year ago

I'm just assuming that adding a IP/CIDR whitelist would be an easier solution, but then again I'm not a software dev so I could be totally off the mark with this.

It's the other way around. Running a socks proxy excluded from the tunnel is fairly trivial, since we already have per process split tunneling. You can do this today. Just install and run a socks proxy and exclude it from the tunnel.

faern commented 4 months ago

I'm closing this as a duplicate of #2071 since that is older and discuss virtually the same thing. Please continue any discussion about split tunneling based on domains.