[wireguard-apple] macOS: link-local multicast (mDNS) bypasses tunnel despite AllowedIPs = ::/0
Bryant Eadon <[email protected]> Thu, 1 Jan 2026 11:36:48 -0800
| Newsgroups | com.zx2c4.lists.wireguard |
|---|---|
| Message-ID | <CANDT8hHFj9z9vTraCFhJkebaydggZcD_8WA14Ta9aV3BH8-tkg@mail.gmail.com> |
Hello, I'd like to report a privacy concern with the macOS WireGuard GUI app where link-local multicast traffic egresses the physical interface even when the tunnel is configured to capture all traffic. Environment: - macOS 14.x (Sonoma) - WireGuard for macOS (App Store, current version is 1.0.16) - Full-tunnel configuration Client configuration: [Interface] PrivateKey = <redacted> Address = 10.10.91.2/32, fd96:e7c9:fb3f:91::2/128 DNS = 10.10.0.1, fd96:e7c9:fb3f::1 [Peer] PublicKey = <redacted> Endpoint = <redacted>:51820 AllowedIPs = 0.0.0.0/0, ::/0 PersistentKeepalive = 25 Observed behavior: With the tunnel active, packet capture on the physical interface (en0) shows mDNS queries being transmitted outside the tunnel: - IPv4 mDNS to 224.0.0.251:5353 - IPv6 mDNS to ff02::fb:5353 Services observed leaking include _googlecast._tcp.local, _airplay._tcp.local, _spotify-connect._tcp.local, and _companion-link._tcp.local. Meanwhile, "curl -4 ifconfig.me" correctly returns the VPN exit IP, confirming the tunnel is functional for unicast traffic. Privacy implications: Users configuring AllowedIPs = 0.0.0.0/0, ::/0 reasonably expect all traffic to traverse the tunnel. However, link-local multicast reveals: 1. The client's presence on the local network 2. The client's link-local IPv4/IPv6 addresses 3. Services the client is attempting to discover 4. Device fingerprinting via mDNS query patterns This is particularly relevant when using WireGuard on untrusted networks (hotels, cafes, airports) where the privacy expectation is highest. Root cause (suspected): macOS's mDNSResponder (probably?) binds directly to interfaces and uses link-local multicast addresses (224.0.0.0/24, ff02::/16) which are special-cased by the network stack and don't follow the routing table. Since WireGuard is a Layer 3 tunnel, it cannot capture Layer 2 multicast without explicit firewall rules. A workaround does not appear to be available in the GUI app. On Linux or with wg-quick, this could be mitigated via PostUp rules: PostUp = iptables -I OUTPUT -o %i -d 224.0.0.0/24 -j DROP PostUp = ip6tables -I OUTPUT -o %i -d ff02::/16 -j DROP Or on macOS with pf: block drop quick on en0 proto udp from any to 224.0.0.251 port 5353 block drop quick on en0 proto udp from any to ff02::fb port 5353 However, the macOS GUI app does not support PostUp/PostDown hooks, leaving users without a native solution. Request/Questions: 1. Is this behavior considered expected given WireGuard's Layer 3 design? 2. Would the macOS app consider adding an option to block link-local multicast on non-tunnel interfaces when a full-tunnel configuration is active? 3. Alternatively, could PostUp/PostDown support be added to the macOS GUI app? 4. Would the macOS app consider routing the multicast traffic ? 5. Is there other missing traffic which is NOT handled by the IPV4 / IPV6 config line : "0.0.0.0/0" and/or "::/0" ? I have pcap files available if useful for analysis. Thank you, Bryant