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

IP handling policy: bind to all interfaces (to bypass VPN) (RFC 8828) #750

Open
WofWca opened this issue Dec 26, 2024 · 0 comments
Open

Comments

@WofWca
Copy link
Member

WofWca commented Dec 26, 2024

Summary

Implement a way to bind to all network interfaces, and thus bypass system-wide VPN.

Currently, for example, on Windows, if you're connected to a WireGuard VPN with the "block untunneled traffic (kill-switch)" disabled, Pion will only collect server-reflexive candidates that correspond to the VPN server's IP address, whereas in Chromium with "IP handling policy" set to "default", it will also gather server-reflexive candidates with your real IP address (so you'll get 2 server-reflexive candidates with different public IPs) (this can be tested on this page).

As a more concrete example of what I'm talking about:

  1. Disable your VPN.
  2. curl https://api.ipify.org. You'll get your ISP-assigned public IP address
  3. Enable your VPN.
  4. curl https://api.ipify.org. You'll get your VPN's public IP address.
  5. Find your PC's private IP address in your router's network (usually 192.168.1.2).
  6. curl --interface 192.168.1.2 https://api.ipify.org.
    You'll get your ISP-assigned public IP again, which means you just bypassed the VPN!

RFC 8828 touches on this:

for some users, the purpose of using a VPN is for anonymity.
However, different VPN users will have different needs, and some VPN
users (e.g., corporate VPN users) may in fact prefer WebRTC to send
media traffic directly -- i.e., not through the VPN.

So, it would be nice to somehow have a way to tell Pion to collect such ICE candidates.

I do not know whether we want to mimic the browser API (a toggle with 4 values), or somehow augment the current API (considering that we already have SetInterfaceFilter and SetIPFilter).

Motivation

My particular use case is bypassing a system-wide VPN. It's for this project: https://github.com/WofWca/snowflake-generalized. I want to set up a WebRTC-based TCP (or UDP) tunnel on the client's machine, and then connect a VPN client to localhost, the local part of the tunnel. Of course, the WebRTC connection should not be routed through the VPN, because it goes the other way.

Browsers already implement this, with the "IP handling policy" feature. Chromium apparently bypasses VPN by default, unlike Gecko. In both Gecko and Chromium, browser extensions can be used to control the value of the setting, see webRTCIPHandlingPolicy.
The WebRTC browser spec also references RFC 8828.

Describe alternatives you've considered

  • We do already have SetInterfaceFilter and SetIPFilter, for granular control, however, this is not it, because this does not control whether server-reflexive candidates get collected on non-default interfaces (and they do not get collected).
    But, perhaps for the implementation of this feature, those functions can be somehow utilized, maybe with some adjustments.
  • Let Pion users configure this manually somehow, maybe it's possible with, say, SetICEUDPMux. However, I assume this would require a lot of manual setup.

Additional context

FYI RFC 8828 is a bit broader than just "bypass VPN". It also goes the other way and can be about "more privacy", by only exposing public addresses, but this particular case is already possible in Pion, with SetIPFilter (and, for example, Snowflake utilizes it).

This feature is not to be confused with ICETransportPolicy, which is about only exposing TURN candidates.

As a keyword, I'll mention the so called "kill-switch" feature that some VPN clients (including WireGuard for Windows) have, which is specifically designed to prevent what this issue is describing, i.e. bypassing the VPN and utilizing direct Internet access.

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

No branches or pull requests

1 participant