-
Notifications
You must be signed in to change notification settings - Fork 126
[macOS] Split Tunnel App Exclusion Binds Excluded Apps to utun (WireGuard Internal IP) Instead of Physical Interface #309
Description
Describe the bug
When an app is excluded from the Windscribe tunnel via split tunneling (Exclusive mode), its outbound connections bind to the WireGuard tunnel interface (utun420, internal peer IP 100.x.x.x) instead of the physical interface (en0, 192.168.x.x). Traffic from excluded apps appears to originate from a non-routable CGNAT address, defeating the purpose of the exclusion entirely.
This has been independently confirmed to break three separate systems (details below).
OS and app information:
- OS: macOS 26.3.1 (Build 25D771280a), Apple Silicon (arm64)
- App version: 2.20.7
To Reproduce
Steps to reproduce the behavior:
- Enable Windscribe with WireGuard protocol and Auto firewall mode (Before Connection).
- Enable split tunneling in Exclusive mode.
- Add any app to the exclusion list (I used the Tapo camera app, selected from Windscribe's own pre-populated app list).
- Open the excluded app and let it establish connections to an external server.
- Inspect the app's connections:
sudo lsof -i -n -P | grep -i tapo- Observe that the excluded app's source IP is the WireGuard internal peer address (
100.x.x.x), not the physical interface IP (192.168.x.x):
Tapo 8696 user 46u IPv4 TCP 100.x.x.x:52168->54.84.94.92:443 (ESTABLISHED)
Tapo 8696 user 52u IPv4 TCP 100.x.x.x:51566->44.198.135.142:443 (ESTABLISHED)
Tapo 8696 user 74u IPv4 TCP 100.x.x.x:52055->13.217.231.62:443 (ESTABLISHED)
- Confirm utun420 is Windscribe's WireGuard tunnel:
sudo lsof | grep utun420
→ windscrib 8422 root 9u unix /var/run/wireguard/utun420.sockThe excluded app's traffic is routing correctly (bypasses the VPN exit node - destinations are the app's cloud servers, not the Windscribe endpoint), but sockets are binding to the tunnel interface instead of the physical interface.
Expected behavior
An app excluded from the split tunnel should bind to the physical interface (en0) and appear to remote servers as originating from the user's real public IP - not from the WireGuard internal peer address.
Debug log or username
Debug log sent from the app on March 23, 2026. Username: CompetitivePterodactylSupporter
Screenshots
N/A - this is a network-level issue confirmed via command-line diagnostics, not a UI bug.
Additional context
What was ruled out
Each of these was verified with packet captures before being closed:
- mDNS / multicast blocking:
tcpdumponen0confirms mDNS (224.0.0.251:5353) flows freely with Windscribe connected. Not the issue. - Routing to other subnets broken:
curlsuccessfully reaches devices on other subnets with Windscribe connected. Routing works. - App exclusion not taking effect: The traffic is bypassing the VPN exit node (destinations are the app's cloud servers, not Windscribe's endpoint). The exclusion works for routing - it just doesn't rebind the source address.
Impact - Three independently confirmed affected systems
- Tapo Security Cameras (cloud relay timeout)
Tapo cameras use a cloud-relay architecture (confirmed via traffic analysis: 100% SSL/TLS, zero direct packets between Mac and cameras). TP-Link's cloud compares the viewer's source IP against the cameras' registered home IP. Because the excluded Tapo app appears from 100.x.x.x (non-routable CGNAT) instead of the real home IP, the cloud classifies the viewer as "remote" and enforces a streaming timeout.
Workaround: Use Tapo on a different device not running Windscribe.
- Apple Continuity Phone Calls (completely broken)
iPhone-to-Mac call relay via Apple Continuity. iPhone and Mac are on the same subnet - no cross-subnet complexity.
- Outgoing calls: Call signalling completes (recipient's phone rings), but the audio relay back to the Mac fails. Mac displays: "Call Failed - make sure iPhone is nearby and on the same Wi-Fi network." The iPhone cannot reach the Mac at
100.x.x.x. - Incoming calls: Mac never rings at all. No notification. The iPhone cannot locate the Mac at its Bonjour-advertised address (
100.x.x.xinstead of the real LAN IP).
Disconnecting Windscribe resolves both immediately.
Workaround: None. Apple Continuity operates at the host macOS level and cannot be excluded or rerouted.
- Wake-on-LAN (broadcast traffic swallowed)
WoL magic packets do not reach LAN devices with Windscribe active, even with "Allow LAN Traffic" ON. Magic packets are broadcast traffic that should never leave the local network.
Workaround: Route WoL through a separate device on the same subnet.
Root cause (per Windscribe's own support chatbot, Garry)
Garry provided this explanation during the initial investigation:
Socket binding happens before the NEFlowMetaData filter executes. macOS assigns the default route interface (utun, set by the VPN) to new sockets before the Network Extension has a chance to divert them to the physical interface.
This is an Apple NE API behaviour - but it is Windscribe's responsibility to work around it in the NEPacketTunnelProvider implementation. The app exclusion feature implicitly promises that excluded apps will behave as if the VPN isn't running. Currently, they don't.
Additional notes
- The Tapo app was excluded using Windscribe's own pre-populated app list - this isn't a misconfigured manual entry.
- This was initially misdiagnosed by Garry (Windscribe's support chatbot) as an mDNS/multicast issue. Packet captures ruled that out entirely.
- A bug report was emailed to hello@windscribe.com on February 25, 2026 per Garry's instructions. No response was received for a month. A follow-up was sent March 22, 2026 with all three affected systems documented.
- This issue affects any excluded app whose remote server cares about the client's source IP, and any local network feature that depends on the Mac advertising its real LAN address. The three systems above are just the ones I've confirmed - the actual blast radius is likely larger.
Does this bug occur in previous versions of the app or is it new to the build version you noted above?
Unknown - I installed Windscribe for the first time at v2.19.7 (February 2026), upgraded to v2.20.7 the same day. The bug has been present in every version I've used. I have no data on versions prior to 2.19.7.