Wireguard on Mac leaking traffic outside of VPN?

So nettop seems to rely on libpcap, so it captures packets and does not read the state table. I still think that these are open connections and as soon as packets are flowing nettop sees and displays them accordingly.

Try `sudo lsof -i -P | grep LISTEN | grep -E ‘49508|49509’`

Original: https://stackoverflow.com/a/4421674

If the other app is running as root or a system level permission, it could be bypassing the wg interface by accessing the hardware path directly and initializing a connection.

open the wg app, edit the connection. when the config window pops up there is a toggle in the bottom left that says “Block untunneled traffic (kill-switch)” make sure this is checked. if it is then nothing should be leaking as far as im aware.

It’s not that simple. You can read this guide to get started:

If you aren’t comfortable with the command line, launchd, etc. then you need to use a commercial VPN app that already includes a killswitch.

But basically:

Use launchd to start shell script on boot

Shell script enables pf and loads config file

In the config file you will need to allow DHCP etc. on the actual interface and then block everything else.

It will probably take you 2-3 days just to get comfortable writing PF rules. Read this:

The endpoint would be going out the main interface it’s the only thing I could think of.

To figure out what’s happening wireshark should help.

It’s a stupid name yes.

The IP itself is owned by microsoft.

It’s quite possible their program is configured to bypass the OS routing table, it could be something to do with trying to detect people who are using a VPN against policy or something.

Check your routing table (route -n? Not sure I don’t use macs) to see if there’s a more specific route that has been installed, perhaps by the application itself. If there’s a route to 52.122.122.22/32 via your default gateway, then your default route of 0.0.0.0/0 will be ignored in favour of the more specific route.

To prevent this happening you could perhaps add 52.122.122.22/32 to your allowedIPs (which will install a specific route to that IP too), and in any case configure your firewall to disallow any outbound traffic except to the server you are dialing into with wireguard.

Here’s my process: turn on Mac (after being shut down), start Wireguard (now running), open the app in question. Then these connections appear after I’m running the app. They’re connections that only the app uses (it’s the Windows app, and the connections are to Microsoft data centres) so they couldn’t possibly be running before I start Wireguard.

Yeah it just tells me that the app in question is using that port and nothing else

Also, isn’t macos sandboxing all executable code now? Maybe that’s a thing? Its been ages since I’ve used one.

Do you know how I’d be able to check this? I don’t recall granting the app any special permissions.

Interestingly when I try using MullvadVPN instead of the wireguard app, these connections don’t happen. Well, some connections on the “en0” interface show up but they’re all in “Listen” state and looks like no data is transferred, but that could still be a problem if it’s exposing my IP.

Thanks this is helpful and I worked through that and set up the conf better.

As a result, it does seem to have worked at least in some way. Connections work rather than everything being blocked, and I don’t see en0 interface connections receiving data.

However I see a couple things:

Looking at nettop -m tcp, the app still starts some connections on the en0 interface. However the states are all Listen or Synsent, so it looks like the connection is set up and some data is attempting to send. But I’m not sure if this still exposes my details, if the data is received anywhere. No data seems to be received at least which is good, but I don’t know enough to say if this is fully safe.

On nettop -m udp, it does still set up some connections on en0 again. These just have bytes sent, nothing received, so again I don’t know if this is still a security risk.

I’m sure why the block all rule doesn’t fully stop en0 connections being set up, and if the app is just going around the pf rules set up.

Overall, just don’t know if this is secure or not.

Yes, these are some really good points.

For OP:
On macOS viewing the routing table is
netstat -nr -f inet (or inet6 for IPv6)

Thanks for your response.

In the routing table, nothing is listed for that IP with the en0 interface. When I’m running the Windows app and connected, routes appear in that table for the IP in question but they’re all listed with utun8 interface - i.e. that’s expected, they should be using the VPN tunnel.

But regardless, looking in nettop, there are ongoing connections both on the utun8 and en0 interface, even though the latter has nothing in the routing table.

This makes me believe the app itself is hardcoded to ignore VPN or simply bypass it for certain connections.

I used tcpdump to analyse what packets were being sent via en0 to/from that IP, and essentially looks like my computer is communicating with the IP using the NAT STUN protocol over UDP. I’m not an expert here, but chatGPT tells me:

This sheds light on why traffic is being routed via en0, even though it might not show in the routing table as expected. STUN is often used by real-time communication services (e.g., Zoom, Microsoft Teams, Skype, etc.) to ensure low-latency communication and direct connectivity for media streams. This likely explains why you see traffic going via en0 (your local interface) instead of through the VPN (utun8). Applications often try to establish the most efficient path for real-time data, bypassing the VPN when necessary for performance reasons.

I did a bit of testing and confirmed these en0 connections all start appearing when I’m running Microsoft Teams on the remote desktop. So it’s letting me access my remote desktop via VPN, but when I try to do a teams call on the remote desktop, it’s bypassing the VPN to send/receive that data, to reduce latency, which is understandable & expected - the call would be a bit laggy if it was going through the VPN.

But - this is still a security risk for me, and I would prefer to have a laggy call/in general prevent the app just deciding to send traffic outside of my VPN, since I can’t have my security compromised.

Since there is no obvious option in Wireguard for mac to stop this from happening, and no option to prevent this in the Windows app (or even indication that it will happen) I think I need to find some other solution. I don’t think I can apply blanket rules to the IP itself since it looks like there are various IP’s it uses (various microsoft data centres) and I could block the ones I know but there could be more I don’t know about.

So ideally I think I want to find a way to fully block any traffic not on utun8, but I haven’t figured that out yet. Playing with the packet firewall (pf) in macOS and trying to block everything except utun8 has so far just led to everything being blocked and I can’t make any connections. That’s where I’m at…

I can send you my conf file if you want. It’s nuclear though; it blocks DNS because I’m running dnscrypt-proxy and my DNS server is localhost.

Remember, at minimum DHCP will run on the actual interface. There’s also some apple interfaces for airdrop etc. though I block these.

Thanks, this was useful, I’ve made a more detailed response to the parent comment.

Sounds like your application likely has permissions to do things as “root”, it can create whatever packets it wants. You could perhaps run it in a vm or maybe a network namespace and limit it to only be able to talk to the wireguard interface.

Your safest way would be layers of security. If you use the OSX equivelent of iptables

 iptables -A INPUT -s  wgendpoint/32 -j ACCEPT
 iptables -A INPUT -s  0.0.0.0/0 -j DROP
 iptables -A OUTPUT -s wgendpoint/32 -j ACCEPT
 iptables -A OUTPUT -s 0.0.0.0/0 -j DROP

(and same for ipv6). You might need to let some local traffic (arp, dhcp, printers etc) too, perhaps allow your local 192.168.0.0/24 range (or whatever)

OSX has the equivalent

If your application is bypassing the OS’s routing it may install its own firewall rules too which ignore yours though – it has full admin access. It might even use DMA or similar to write packets directly to the network card - I think you might not even see it in wireshark in some cases. You’d either need to run in a sandbox of some sort (VM etc), or block at a separate level on a machine not running the software (i.e. your router)

That would be great if you could please so I can give it a try?

I’m fine with nuclear - when my vpn is running I don’t need anything other than this app to be working.