DefGuard / client

Best WireGuard desktop client with Multi-Factor Authentication
129 stars 13 forks source link

MacOS Client does not create valid Routes #281

Closed arcreigh closed 2 weeks ago

arcreigh commented 3 months ago

Client version 0.4.0 (Intel Based Mac) MacOS: 12.7.1

On a native wireguard app installation correct routes are created on tunnel standup, such as your default route out to the tunnel.

default link#21 UCSg utun7

However when looking at the routes created when Defguard is spun up no such routes are created. Instead we have invalid routes such as the following.

0/1 utun7 UScg utun7 192.168.0.2 192.168.0.2 UH utun7 128.0/1 utun7 USc utun7

No "normal" default route has been created and instead a routing loop is created. The client stands up 2 routes to cover the default range rather than just using a default route and states traffic coming from the tunnel goes back out over the tunnel...

I would expect a proper default route be installed for traffic on the laptop to go over the tunnel however this does not occur.

I am using hotspot off of my phone and would expect that interface gets a default route instead of this odd split route behavior.

teon commented 3 months ago

@arcreigh to have a default route through the VPN one must define it - if it's not defined - then only the routes in the AllowedIPs are routed.

What do you have in AllowedIPs?

arcreigh commented 3 months ago

@arcreigh to have a default route through the VPN one must define it - if it's not defined - then only the routes in the AllowedIPs are routed.

What do you have in AllowedIPs?

0.0.0.0/0 is in AllowedIPs not a split tunnel situation.

Additionally, since this is 0.0.0.0/0 it should create a default route rather than 2 distinct routes for 0.0.0.0/1 and 128.0.0.0/1 And those routes should be sourced from an appropriate interface not from the tunnel interface.

arcreigh commented 3 months ago

Native Wireguard application routes. This is an unedited config taken directly from DefGuard portal.

Screen Shot 2024-08-19 at 1 40 15 PM

Defguard Routes.

Screen Shot 2024-08-19 at 1 41 39 PM

Defguard implementation of WireGuard routes.

Screen Shot 2024-08-19 at 1 43 05 PM
arcreigh commented 3 months ago

Another note this is utilizing the iPhone hotspot feature built into MacOS.

arcreigh commented 3 months ago

Native WireGuard App version: 1.0.16 (27) [current version from app store] Go backend version: 1e2c3e5a

teon commented 3 months ago

@moubctez i agree that we need to detect 0.0.0.0 in WireGuard-rs and change default route - this is the same case as ipv6 where default route is lacking.

moubctez commented 3 months ago

@arcreigh We followed wireguard-tools > wg-quick, see https://git.zx2c4.com/wireguard-tools/tree/src/wg-quick/darwin.bash#n356. (Some explanation: https://serverfault.com/questions/312860/why-openvpn-use-network-0-0-0-0-netmask-128-0-0-0-as-a-default-route).

arcreigh commented 3 months ago

@moubctez I understand the logic behind the decision. But from a networking standpoint it doesn't make sense to do so unless you have a reason to send half of the default one direction and the other half in another direction. In this scenario it is much more efficient to just use your standard 0.0.0.0/0 default route and filter it via the interface simplifying your implementation by only having to manage 1 route instead of 2.

The bigger issue at play here is that the current implementation does not correctly specify the source interface for these routes making the DefGuard client unusable on MacOS.

If you decided to stick with the split default you'd still need to fix the source interface on the 2 routes.

The routes define utun7 (wireguard) as the source and the destination interface causing a routing loop. Because of this behavior traffic coming into the clients tunnel from DefGuard Server will be routed back to the DefGuard Server instead of to the OS, the DefGuard server will then send it back as it should as the destination is the Client (rinse and repeat until packet TTL expires).

This also fails to send any traffic out the tunnel. The work around is to just use the native wireguard application which does correctly define the interfaces on the routes and they (Wireguard team) also opted for a single 0.0.0.0/0 route instead of the split routes.

Juoper commented 1 month ago

Same problem here, native mac client isn't working for me, wireguard profile is working

arcreigh commented 2 weeks ago

@moubctez @teon

With the recent updates traffic is now correctly sourced from an appropriate interface on the macOS client.

We still see 2 /1 routes instead of a single default route though which still does not make sense from a networking standpoint.

I do need to fix up some unrelated issues around the docker installation regarding traffic not being appropriately NATd to the underlying hosts network interface.

An argument could be made here that this should be a configuration option within the defguard server UI.

There are some environments where preserving the client IP address is important from an auditing and firewall policy standpoint.

This becomes even more important should defguard as a whole decide to implement zero trust / SASE based controls.

teon commented 2 weeks ago

@arcreigh of course two /1 route make sense, as we are omitting the 127 localhost network which should not be "default routed".

We are planning to do ACLs then we will have auto NAT setup.

arcreigh commented 2 weeks ago

@arcreigh of course two /1 route make sense, as we are omitting the 127 localhost network which should not be "default routed".

We are planning to do ACLs then we will have auto NAT setup.

Your 2 /1's cover the 127 space. Having them split like they are currently is not excluding the 127 space at all.

Default behavior of any VPN is to force all traffic over the tunnel. Keep in mind that you have filtered the routes by network interface, the 127 space is on a loopback interface and can safely be excluded based on how the current configuration is.

There are absolutely scenarios where split tunnel configurations are warranted in the cases where the destination network doesn't have the bandwidth to handle all traffic such as host updates etc. but in secure environments all traffic MUST go through the tunnel through security inspection points, (IDS/IPS/Forward Proxies/Firewalls)

Additionally 127.0.0.1 is local to the device so the host will not attempt to route that to another network as it is local to itself.

@teon

teon commented 2 weeks ago

@moubctez can you jump into discussion? @arcreigh does have a point.

moubctez commented 2 weeks ago

Currently, there have to be 2 split routes (/1) as macOS won't allow to add another default route. Native WireGuard uses system Network Extension, which is planned for Defguard in the future, and that should solve the (all-traffic) routing problems.

arcreigh commented 2 weeks ago

Currently, there have to be 2 split routes (/1) as macOS won't allow to add another default route. Native WireGuard uses system Network Extension, which is planned for Defguard in the future, and that should solve the (all-traffic) routing problems.

Good to know! This was what I was missing, I am a network engineer first and foremost not a dev but do like to share as much networking knowledge as I can in the hopes that developers can begin to see that side of the fence more :)