Mullvad VPN integrates directly with the native firewall on each desktop platform to enforce strict security policies. All firewall changes are applied as atomic transactions, ensuring no time window exists with inconsistent or invalid rules.Documentation Index
Fetch the complete documentation index at: https://mintlify.com/mullvad/mullvadvpn-app/llms.txt
Use this file to discover all available pages before exploring further.
Overview
The firewall integration is platform-specific:- Windows: Windows Filtering Platform (WFP)
- macOS: Packet Filter (PF)
- Linux: nftables
- Android/iOS: VPN Service API / Network Extension (no direct firewall access)
Windows - WFP Integration
Implementation
The Windows firewall is implemented inwindows/winfw/ and uses the Windows Filtering Platform (WFP) API.
Source: talpid-core/src/firewall/windows/mod.rs
Architecture
winfw organizes filters into sublayers with specific weights:
Baseline Sublayer
- Highest weight to process all traffic first
- Contains permit-filters (highest weight within sublayer)
- Contains blocking filters (lowest weight within sublayer)
- Permit-filters “lift” matched traffic to next sublayer
- Blocking verdict is final - matched traffic is dropped
Specialized Sublayers
- DNS sublayer: Filters DNS traffic (port 53)
- Endpoint sublayers: Handle relay and API endpoints
- All weighted slightly lower than baseline
- High-weighted permit-filters for whitelisted traffic
- Low-weighted blocking filters as catch-all
Persistent Sublayer
When the daemon exits while a blocking policy should remain:- Created with highest possible weight
- Contains blocking filters only
- Persists across BFE restarts and reboots
- Ensures traffic blocked until daemon reinitializes
- Active before BFE service starts during boot
windows/winfw/README.md
Key Functions
Hyper-V Leak Protection
Windows implements additional rules to prevent Hyper-V (WSL) traffic leaks:- Uses WMI to enumerate Hyper-V virtual switches
- Adds blocking rules for virtual adapters
- Can be disabled via
TALPID_FIREWALL_BLOCK_HYPERV=0
talpid-core/src/firewall/windows/hyperv.rs
Process Restrictions
WFP rules restrict which processes can communicate with the VPN endpoint:- Connecting state: Only
mullvad-daemon.exeor root processes - Connected state: Only tunnel interface or root processes
- Uses binary path matching on Windows
- Prevents unprivileged programs from fingerprinting endpoint
docs/security.md:174-182
macOS - PF Integration
Implementation
The macOS firewall uses the Packet Filter (PF) system. Source:talpid-core/src/firewall/macos.rs
Architecture
Anchor System
- Creates anchor named
mullvad - Anchor contains filter rules, NAT rules, and scrub rules
- Atomic rule updates via
pfctl::AnchorChange - Preserves/restores PF enabled state
Rule Types
Filter Rules:- Pass rules (allow traffic)
- Drop rules (block with
returnordropaction) - All rules can have
quickflag for immediate verdict
- Force traffic through VPN interface
- Fixes Apple services bypassing tunnel
- Masquerade non-loopback, non-LAN traffic to tunnel IP
- Disabled on unaffected macOS versions
talpid-core/src/firewall/macos.rs:26-45
Scrub Rules:
- Reassemble packet fragments
- Ensures complete transport headers for filtering
State Management
PF retains connection states even after rules removed:- Clears connection states on policy changes
- Preserves VPN endpoint connections
- Preserves in-tunnel allowed traffic during multihop
- Preserves LAN traffic when allowed
- Flushes all states when toggling split tunneling
talpid-core/src/firewall/macos.rs:102-213
Process Restrictions
PF rules restrict endpoint access to root user:- Uses
usercondition matching UID 0 - Only root processes can reach relay endpoints in blocking states
- Prevents unprivileged leak attempts
talpid-core/src/firewall/macos.rs:582-598
Debugging
SetTALPID_FIREWALL_DEBUG to enable rule logging:
pass- Log allowing rules onlydrop- Log blocking rules onlyall- Log all rules- Rules logged to
pflog0interface - View with:
tcpdump -netttti pflog0
talpid-core/src/firewall/macos.rs:60-69
Linux - nftables Integration
Implementation
The Linux firewall uses nftables with thenftnl library.
Source: talpid-core/src/firewall/linux.rs
Architecture
Table and Chains
Creates an inet table namedmullvad:
| Chain | Hook | Priority | Policy | Purpose |
|---|---|---|---|---|
prerouting | PreRouting | NF_IP_PRI_CONNTRACK + 1 | Accept | Mark incoming relay traffic |
input | In | 0 | Drop | Filter incoming packets |
output | Out | 0 | Drop | Filter outgoing packets |
forward | Forward | 0 | Drop | Filter forwarded packets |
mangle | Out | NF_IP_PRI_MANGLE | Accept | Mark split tunnel traffic |
nat | PostRouting | NF_IP_PRI_NAT_SRC | Accept | Masquerade split traffic |
talpid-core/src/firewall/linux.rs:286-315
Atomic Updates
All rule changes are atomic:- Create table (if not exists)
- Delete table (clear existing rules)
- Re-create table with new chains
- Add all rules in single batch
- Verify table exists in kernel
talpid-core/src/firewall/linux.rs:145-151
Firewall Mark
Uses firewall markfwmark for traffic classification:
- Marked packets can bypass tunnel (split tunneling)
- Applied to relay endpoint traffic
- Applied to split-tunneled process traffic
- Prevents reverse path filter issues
talpid-core/src/firewall/linux.rs:104-106
Process Restrictions
nftables rules restrict endpoint access:- Uses
meta skuidto match root user (UID 0) - Alternatively uses
meta markmatchingfwmark - Only root or marked traffic reaches endpoints in blocking states
talpid-core/src/firewall/linux.rs:786-811
Kernel Parameters
When establishing tunnel, sets kernel parameters:src_valid_mark
- Enables fwmark consideration for reverse path filtering
- Prevents strict
rp_filterfrom blocking relay traffic - Disable via
TALPID_FIREWALL_DONT_SET_SRC_VALID_MARK=1
docs/README.md:168-174
arp_ignore
- Reply to ARP only for IPs on receiving interface
- Prevents ARP probing of in-tunnel IP (CVE-2019-14899 mitigation)
- Disable via
TALPID_FIREWALL_DONT_SET_ARP_IGNORE=1
talpid-core/src/firewall/linux.rs:186-196
Debugging
SetTALPID_FIREWALL_DEBUG=1 to add packet counters:
talpid-core/src/firewall/linux.rs:73-77
Common Firewall Rules
All platforms implement these rules:Always Allowed
- Loopback traffic - Always permitted
- DHCP client - UDP 68→67 (v4), UDP 546→547 (v6)
- DHCP server (when Allow LAN) - UDP 67→68 (v4)
- NDP (Neighbor Discovery Protocol):
- Router solicitation (type 133)
- Router advertisement (type 134) from
fe80::/10 - Redirect (type 137) from
fe80::/10 - Neighbor solicitation (type 135)
- Neighbor advertisement (type 136)
docs/security.md:87-106
LAN Access (when enabled)
Allows traffic to/from: Private networks:10.0.0.0/8172.16.0.0/12192.168.0.0/16169.254.0.0/16(link-local IPv4)fe80::/10(link-local IPv6)fc00::/7(ULA)
224.0.0.0/24(local IPv4)239.0.0.0/8(admin IPv4)255.255.255.255/32(broadcast)ff01::/16throughff05::/16(IPv6 multicast)
docs/security.md:107-127
Policy-Specific Rules
Connecting State
- Allow tunnel endpoint (IP:port:protocol)
- Allow API endpoint (root only)
- Block all DNS except to relay (if multihop)
- Allow in-tunnel traffic (if created)
- Allow LAN (if enabled)
docs/security.md:166-189
Connected State
- Allow tunnel endpoint
- Allow DNS to relay or custom servers only
- Block all other DNS
- Allow all tunnel interface traffic
- Allow LAN (if enabled)
docs/security.md:194-208
Blocked State
- Allow API endpoint (root only, if specified)
- Block all DNS
- Allow LAN (if enabled)
docs/security.md:221-234
API Access
All platforms allow API traffic in all states:- Connected: API traffic goes through tunnel
- Other states: API bypasses firewall
- Windows: Only
mullvad-daemon.exeand problem report tool - macOS/Linux: Only root processes
docs/security.md:133-144
Mobile Platforms
Android
Uses VPN Service API instead of firewall:- Routes
0.0.0.0/0and::/0through app - Applies in connecting, connected, and error states
- System “Block connections without VPN” provides OS-level enforcement
- Exempt traffic: connectivity checks, NTP, hotspot
docs/security.md:32-62
iOS
Uses Network Extension packet tunnel:- Packet tunnel process handles all traffic
- Routing rules force all traffic through tunnel
- Delegates to
wireguard-gofor tun interface - Local network always accessible
docs/security.md:71-76