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

VPN-6363: Better LAN exclusions #9674

Merged
merged 25 commits into from
Jul 23, 2024
Merged

VPN-6363: Better LAN exclusions #9674

merged 25 commits into from
Jul 23, 2024

Conversation

oskirby
Copy link
Collaborator

@oskirby oskirby commented Jun 19, 2024

Description

The way we set up LAN exclusions has begun to diverge between platforms, and I think we have some bugs in Linux. Specifically I have found that the IP routing policy of ip rule add table main suppress_prefixlength 0 has basically meant that we defer to the main routing table for all destinations, except the default route. This kindof works, except what we really intended was to send all traffic to the wireguard interface first and then punt traffic back to the main table if it wasn't really supposed to go to the wireguard interface.

To fix this, I think it's about time that we move the routing exclusion logic out of the client and make it a part of the Daemon setup - it has always kinda been this way for iOS anyways so we might as well make it the standard procedure.

Fun fact, it turns out that Android actually has an API for this that would be much better suited to setting up address-range exclusions: VpnService.Builder.excludeRoute()

Reference

JIRA Issue VPN-6363
JIRA Issue VPN-6482
JIRA Issue VPN-5865
Previous PR #9257

Checklist

  • My code follows the style guidelines for this project
  • I have not added any packages that contain high risk or unknown licenses (GPL, LGPL, MPL, etc. consult with DevOps if in question)
  • I have performed a self review of my own code
  • I have commented my code PARTICULARLY in hard to understand areas
  • I have added thorough tests where needed

@oskirby oskirby force-pushed the vpn-6363-better-lan-exclusions branch from 78348ea to ed9ee1b Compare June 19, 2024 15:14
@oskirby oskirby force-pushed the vpn-6363-better-lan-exclusions branch from cb06521 to 8de0b4f Compare July 2, 2024 17:28
@oskirby oskirby force-pushed the vpn-6363-better-lan-exclusions branch from 99a7a82 to 07f5dc9 Compare July 16, 2024 22:43
@oskirby oskirby marked this pull request as ready for review July 16, 2024 22:43
Copy link
Collaborator

@mcleinman mcleinman left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I didn't review the Linux and Windows portions, as I have no context on how we do routing on those platforms. If nobody else with expertise in that area can review this, I can dig in and learn (and review those portions of the PR).

Everything else looks good - just a few questions to make sure I understand it. Thanks - this seems great!

src/cmake/linux.cmake Show resolved Hide resolved
src/daemon/daemon.cpp Show resolved Hide resolved
src/daemon/wireguardutils.h Show resolved Hide resolved
@mcleinman mcleinman self-requested a review July 17, 2024 22:04
Copy link
Collaborator

@mcleinman mcleinman left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This approval should be considered a partial approval. I didn't review the Linux and Windows portions, as I have no context on how we do routing on those platforms. (If nobody else with expertise in that area can review this, I can dig in and learn and review those portions of the PR.)

Thanks for answering all my questions!

src/platforms/windows/daemon/wireguardutilswindows.h Outdated Show resolved Hide resolved

// Permit LAN traffic through the firewall.
if (!WindowsFirewall::instance()->enableLanBypass(addresses)) {
result = false;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we be removing the exclusion route here, given if we end up here that route exist but might be blocked by the firewall?

Once the default-route-suppression rule was removed, it turns out that
we really do need to setup the wireguard routing table to exclude LAN
addresses. This can easily be done using the RTN_THROW route type.

But then once the throw routes are in place, we can't actually reach
the internal Mulvad address space, so we need to add unicast routes
back too.

There is a bunch of duplicated work between the throw and unicast
routes though. So it still results in an ugly looking routing table.
This attempts to make up for the lack of policy-based routing on Windows
by interactively updating the routing table to force non-local traffic
into the VPN tunnel. The gist of the algorithm being deployed here is to
dump the routing table, and then dynamically duplicate any routes which
might try to leak traffic but with a lower metric to force it back into
the VPN anyways.
@oskirby oskirby force-pushed the vpn-6363-better-lan-exclusions branch from 07f5dc9 to 10ca2d6 Compare July 23, 2024 07:02
@oskirby oskirby merged commit a95fa8c into main Jul 23, 2024
116 checks passed
@oskirby oskirby deleted the vpn-6363-better-lan-exclusions branch July 23, 2024 19:17
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

Successfully merging this pull request may close these issues.

3 participants