TUN Mode vs System Proxy: How Traffic Interception Actually Works
Most people treat these as "two switches in the settings menu" and flip between them by gut feeling. System proxy works because apps voluntarily read your config and connect through the proxy port; TUN intercepts packets at the network layer whether the app cooperates or not. That single distinction explains the differences in coverage, DNS behavior, and where to look when things break.
Two Mechanisms, Two Layers: Where Each One Actually Operates
To understand the difference, you need to know how many layers a network request passes through between leaving an app and actually reaching the internet. System proxy and TUN mode don't intercept at the same layer — that's the root cause of every behavioral difference you'll notice.
System proxy operates at the application layer. The operating system exposes a "proxy settings" interface; browsers, CLI tools, and some desktop apps read this setting and forward their own requests to the specified proxy port. The forwarding itself is implemented by the app — the OS just stores the config and hands it over to whoever asks.
TUN mode operates at the network layer, more precisely at the IP packet level. When Clash Meta (mihomo) enables TUN, it creates a virtual network adapter on the system and modifies the routing table so the default route points to that adapter. From then on, every outgoing IP packet — regardless of which process sent it — passes through this virtual adapter first, gets handed to the kernel, then to Clash for processing, which decides direct connection or proxy based on your rules.
In short: system proxy is "the setting sits there, and it's up to the app to read it"; TUN is "the route itself has changed, so packets can't dodge it even if they want to."
System Proxy: A Delegation Model Apps Have to Cooperate With
The implementation details vary slightly across operating systems, but the core logic stays the same:
- Windows / macOS GUI — the OS provides a global proxy setting; once the Clash client turns on "Set as system proxy," it writes this config into system preferences, and most browsers and modern apps read it by default.
- Command-line terminals — these look for environment variables like
http_proxyandhttps_proxyinstead. System-level proxy settings usually don't apply to the terminal, so you need to export them separately. - PAC scripts — some clients use a PAC (Proxy Auto-Config) file to decide per-domain whether to proxy. The browser loads this script and routes traffic based on its rules.
This whole setup only works if "the app is willing to play along." If a program hardcodes its connection address, or simply never checks the system proxy setting (common with some games, updater services, and background daemons), the system proxy setting does nothing for it — traffic still goes straight out. That's exactly why turning on system proxy fixes your browser but leaves some other client stuck disconnected: it just wasn't part of the group that "plays by the rules."
System proxy takes effect immediately for newly launched processes, but apps that were already running — and cached their network config at startup — sometimes need a restart to pick up the new proxy setting. When troubleshooting "proxy is on but this one app won't use it," restart that app first before digging into rules.
TUN Mode: A Virtual Adapter at the Network Layer, Catching Everything
TUN mode doesn't need apps to cooperate — it changes the path every packet must take before leaving the device. Roughly, here's what happens once it's enabled:
- The Clash Meta (mihomo) core creates a virtual network interface (commonly named something like
utunorMeta), which the system treats exactly like a real network adapter. - It modifies the local routing table so the default route (or specified subnets) points to this virtual adapter, taking priority over the existing physical adapter's route.
- When the kernel forwards packets according to the routing table, any traffic matching the default route gets sent to the virtual adapter first, where the Clash process reads, parses, and processes it per your rules.
- The processed traffic then goes out through a proxy node or a direct connection, and the response comes back along the same path to the originating process — which never even notices the whole detour.
Because the interception happens at the routing layer, all IP traffic gets caught — no distinction between browsers, CLI tools, or background system services, and none of them need to support proxy settings. That's TUN mode's biggest advantage: it handles the traffic from processes that simply "won't play along."
The trade-off is just as direct: since the virtual adapter touches the low-level network stack, it demands higher privileges (usually admin rights or a driver authorization on Windows, and a system extension or root-level helper service on macOS), and a misconfiguration has a wider blast radius — routing table conflicts, fighting other VPN software for the default route, firewalls blocking virtual adapter traffic. These are all TUN-specific failure modes that system proxy simply never runs into.
DNS Handling: Where the Two Mechanisms Diverge the Most
Whether DNS resolution goes through the proxy or stays local is where the two mechanisms behave most differently — and it's the part that trips up beginners the most.
Under system proxy, DNS requests usually don't pass through Clash at all — it only intercepts TCP/HTTP connections that apps actively initiate. Domain resolution often still happens through your machine's original DNS server, and the resulting IP is what gets used to connect to the proxy. That means the DNS query itself can be exposed to your local network provider, and if local DNS is tampered with or poisoned, the resolved address can be wrong — causing the connection to fail or hit the wrong server entirely.
Under TUN mode, Clash Meta (mihomo) can intercept the DNS request itself, typically via fake-ip: the core assigns a domain a temporary fake IP from a reserved range. When the app connects using that fake IP, Clash recognizes at the network layer which domain it corresponds to, matches it against your rules for proxy or direct connection, and the real resolution happens on the proxy side. That keeps both the DNS query and the subsequent connection entirely within Clash's control, so domain poisoning barely affects the outcome.
| Comparison | System Proxy | TUN Mode |
|---|---|---|
| Interception layer | Application layer, requires app cooperation | Network layer, based on routing table |
| Coverage | Apps that support proxy settings | All IP traffic, process-agnostic |
| DNS handling | Usually resolved locally | Fully intercepted via fake-ip |
| Privilege requirements | Regular user permissions | Admin rights or system service |
| Typical failure points | Some app ignores system settings | Routing conflicts, virtual adapter issues |
Coverage Comparison: What Traffic Slips Through
The most common question in practice is "why does some traffic still bypass the proxy even though it's on?" The answer usually depends on which mechanism you're using.
Typical gaps under system proxy mode:
- CLI tools (
curl,git, package managers) ignore the system proxy setting entirely and only look at environment variables — without setting those separately, they connect directly. - Some desktop clients (chat apps, download managers, game updaters) run their own network stack internally and never check the system proxy setting.
- System-level background services (auto-updates, telemetry reporting) are typically not bound by user-level proxy settings.
Under TUN mode, all of the above scenarios are basically covered, since the routing layer doesn't care which process sent the packet. But TUN mode has its own gaps — if a rule sets a specific subnet (like your LAN) to bypass the proxy, or if the virtual adapter's route priority gets overridden by another networking tool (some VPN clients, virtual machine adapters), traffic can still slip around Clash. Troubleshooting this means checking the routing table and adapter priority, not app-level settings.
Which One to Use: Scenarios and Switching Advice
It's not about which one is "better" — it's about which one matches your current need. A few practical rules of thumb:
- Mostly browsing, with the occasional common tool — system proxy is enough. It's simpler to set up and easier to debug when something breaks, so it's the safer starting point.
- Need to cover CLI tools, games, background services, or anything that doesn't support proxy settings — switch to TUN mode; that's exactly why it exists.
- Already running another VPN or have a history of virtual adapter conflicts — check the routing table first before enabling TUN, so two network interception layers don't end up fighting over the route and causing connection drops.
- Concerned about DNS poisoning or resolution leaks — TUN mode with fake-ip closes that gap completely; system proxy has no control over the DNS query itself.
The two modes aren't mutually exclusive — most clients let you switch anytime. When something behaves oddly in a given scenario, confirm which interception mechanism is active first, then check the comparison table above. That's far more efficient than a blind reinstall or node swap.
The first step in troubleshooting any connection issue is always confirming whether you're running system proxy or TUN — the failure patterns for each are completely different, and getting that wrong wastes every minute you spend digging afterward.
Download the Clash Client
Once you've picked an interception mode, get the client installed and run through the basic setup first.