Platform Overview
Each desktop platform uses its native firewall system:| Platform | Firewall | Implementation Location |
|---|---|---|
| Windows | Windows Filtering Platform (WFP) | windows/winfw/ |
| macOS | Packet Filter (PF) | talpid-core |
| Linux | nftables | talpid-core |
All platforms apply firewall rules as atomic transactions. There is no time window where rules are inconsistent or invalid during state changes.
Windows Filtering Platform (WFP)
Windows uses the Windows Filtering Platform, a powerful and flexible firewall architecture introduced in Windows Vista.WFP Architecture
Thewinfw component implements security policies through a sublayer-based design:
Sublayer Types
1. Baseline Sublayer (Highest Weight) The baseline sublayer is weighted highest to see all traffic first:- Contains permit-filters (highest weight within sublayer)
- Contains blocking filters (lowest weight within sublayer)
- Different policies activate different subsets of permit-filters
- All permit-filters have equal weight (order doesn’t matter)
- Blocking filters match all traffic as a catch-all
- All weighted the same, slightly lower than baseline
- Example: DNS-specific sublayer with DNS permit-filters and DNS blocking filter
- Uses the same permit/block design pattern
- Non-relevant traffic passes through unchanged
winfw is deinitialized with blocking policy:
- Highest weight possible
- Contains only blocking filters matching all traffic
- Ensures traffic is blocked until reinitialized
- Active during boot-time before BFE (Base Filtering Engine) starts
- Persists even if BFE is restarted (e.g., during reboot)
WFP Implementation Benefits
- Predictable sublayer weights: Clear hierarchy of rule processing
- Predictable filter weights: Consistent permit-first, block-last pattern
- Short filter conditions: Exact conditions without redundancy
- No logical AND required: WFP doesn’t support AND for same-type conditions; design avoids this limitation
Process-Specific Filtering
Windows allows restricting firewall rules to specific processes:Persistent Filters
When themullvad-daemon service exits, persistent filters may be added if:
- Lockdown mode is enabled, OR
- User didn’t explicitly request shutdown AND either:
- Daemon is in a blocking state (Connected, Connecting, Error), OR
- Auto-connect is enabled
- Block traffic before the service restarts during boot
- Remain active before BFE starts
- Prevent boot-time leaks
windows/winfw/README.md for more details.
macOS Packet Filter (PF)
macOS uses Packet Filter (PF), a stateful firewall originally from OpenBSD.PF Implementation
The Mullvad daemon manages PF rules through anchors:- Anchors: Named rulesets that can be updated atomically
- Atomic updates: All rules are loaded/updated as a single transaction
- State tracking: PF maintains connection state for stateful filtering
PF Rule Structure
Typical Mullvad PF ruleset structure:Process/User Filtering
PF on macOS can filter by user but not by specific process:macOS Boot-Time Limitations
This is a known limitation documented in the known issues.Shutdown Protection
Whenmullvad-daemon exits, it transitions to the Disconnected state to limit leaks during shutdown. However, it maintains blocking firewall rules when:
- Lockdown mode is enabled, OR
- User didn’t explicitly request shutdown AND either:
- Daemon is in a blocking state, OR
- Auto-connect is enabled
Linux nftables
Linux uses nftables, the modern replacement for iptables with better performance and atomic rule updates.nftables Implementation
The Mullvad daemon manages nftables through:- Tables: Top-level container for chains
- Chains: Contain rules that match and act on packets
- Atomic updates: All rules are applied as a single transaction
- Firewall marks: Used to identify tunnel traffic
nftables Rule Structure
Typical Mullvad nftables configuration:Firewall Marks
Linux uses firewall marks to identify privileged tunnel traffic:- Mark
0x6d6f6c65(“mole” in hex ASCII) identifies tunnel establishment traffic - Only processes with elevated privileges can set firewall marks
- Rules allow traffic to VPN server IP only if mark is set
- Prevents unprivileged processes from leaking to VPN server
Packet Forwarding
On Linux, situations that permit incoming or outgoing traffic also allow packet forwarding:Early-Boot Protection
Due to service dependencies,
mullvad-daemon doesn’t start early enough to prevent boot-time leaks. A separate system unit starts during early boot to apply blocking policy until mullvad-daemon takes over.- Starts before network initialization
- Applies blocking nftables rules
- Removed once
mullvad-daemonstarts and applies its rules - Prevents leaks during the boot process
Shutdown Protection
Similar to other platforms, Linux maintains blocking rules on daemon exit when:- Lockdown mode is enabled, OR
- User didn’t explicitly request shutdown AND either:
- Daemon is in a blocking state, OR
- Auto-connect is enabled
ARP Protection
Linux (and Android) by default reply to ARP requests for any local IP on any interface. This can leak the tunnel IP to the local network. Mullvad sets the kernel parameternet.ipv4.conf.all.arp_ignore=2 when a tunnel is active:
Firewall Rule Examples
Here are concrete examples of rules applied in different states:Connecting State
Windows (WFP):Connected State
Windows (WFP):Error State
All Platforms:- Block all traffic
- Allow only the always-allowed exceptions (loopback, DHCP, NDP)
- Allow Mullvad API access
Mobile Platforms
Mobile platforms cannot directly manipulate the system firewall:Android
Android uses the VPN Service API instead of direct firewall access:- App registers as VPN service with the system
- Sets routes
0/0and::0/0to route all traffic through the app - System routes all traffic through the VPN interface
- App can then filter/block traffic at the VPN interface level
- “Block connections without VPN” system setting provides additional OS-level protection
iOS
iOS uses Network Extension framework:- Packet Tunnel Provider extension handles traffic
- Configures routing rules to send all traffic through tunnel
- WireGuard-go handles traffic at the tun interface level
- Cannot directly manipulate iOS firewall rules
Testing Firewall Rules
You can verify firewall rules are active: Windows:Related Documentation
- Leak Protection - How firewall rules prevent leaks
- Tunnel States - What rules are active in each state
- Kill Switch - Always-on protection mechanism
- Architecture - System design and components
Source Code References
- Windows WFP:
windows/winfw/(README) - macOS/Linux:
talpid-core/src/firewall/ - Firewall integration design:
docs/architecture.md