Where System Proxy Ends and TUN Mode Begins
SECTION / PROXY VS TUNA system proxy is an OS-level setting. In practice it writes a set of proxy addresses into the system or an app's runtime environment (environment variables like HTTP_PROXY / HTTPS_PROXY, or Windows' WinINet/WinHTTP settings, or macOS Network preferences). Only when a program actually reads that configuration and routes its own traffic to the proxy port does it count as "going through the proxy." It's a **cooperative** form of forwarding — whether the proxy takes effect depends entirely on whether the target program plays along.
TUN mode works completely differently. When Clash Meta (mihomo) enables TUN, it creates a virtual network adapter on the system (backed by the Wintun driver on Windows, or a utun/tun0 device on macOS/Linux) and points the system's default route at that virtual adapter. From then on, every IP packet that passes through the network layer — regardless of which process sent it or whether that process even knows a proxy exists — is intercepted by the virtual adapter first and handed to the Clash core for rule-based processing. This is a **forced takeover at the network layer**, with no cooperation from any program required.
In short: system proxy controls "whether traffic is willing to go through," while TUN mode controls "traffic goes through me no matter what."
TUN mode isn't a "beefed-up" replacement for the system proxy — it's a separate forwarding path entirely. Most clients let both coexist, but when both are enabled at once, watch for the routing table overriding itself. It's generally best to pick one or the other to keep troubleshooting simple.
Traffic That Only TUN Mode Can Proxy
SECTION / WHO NEEDS TUNIn the following scenarios, a system proxy simply won't work — only TUN mode covers them:
- UDP-based protocols. The system proxy mechanism is built around HTTP/HTTPS (TCP-based). Many online games, VoIP calls, and some video-conferencing apps use UDP directly and never read the system proxy configuration.
- CLI tools and background services. Many CLI tools (package managers, some build scripts) and system daemons don't check proxy environment variables at all, or need an extra --proxy flag to use one — fiddly to configure and easy to miss.
- Apps with hardcoded socket connections. Some desktop and mobile apps call low-level socket APIs directly, bypassing system proxy settings entirely — common in some messaging and cloud-sync tools.
- ICMP and other non-standard protocols. ICMP-based traffic like ping and traceroute, along with some P2P protocols, also fall outside what a system proxy can handle.
- Traffic inside VMs and containers. The host's system proxy usually doesn't propagate to virtual machines or containers automatically, whereas TUN mode intercepts at the host's routing layer and, combined with the right network mode settings, can cover this traffic too.
If you notice an app "still connecting directly even with the proxy on," it's most likely one of the cases above — and enabling TUN mode is the most direct fix.
How to Enable TUN on Each Platform, and What Permissions It Needs
SECTION / PLATFORM SETUPBecause TUN mode has to create a virtual adapter and modify the system routing table, all three major platforms require elevated permissions — though the specifics differ.
On Windows, creating a virtual adapter relies on the Wintun driver. Mainstream clients (Clash Verge, derivatives of Clash for Windows) install this driver automatically on setup or the first time TUN is enabled. Steps:
- Run the client as administrator (right-click → "Run as administrator," or enable "Launch with admin privileges at startup" in settings).
- Find the TUN mode toggle in the settings panel and turn it on. The first time, Windows will prompt for driver installation or network adapter authorization — click Allow.
- If Windows Defender Firewall blocks the virtual adapter's outbound rules, manually allow the relevant network category for that driver in the firewall settings (usually choosing "Private network" the first time the prompt appears is enough).
Not running the client as administrator is the most common reason TUN mode fails to enable on Windows — it typically shows up as the toggle flipping back off right after you turn it on.
On macOS, creating a utun device requires root privileges or a system network extension authorization. Modern clients mostly use a System Extension to avoid entering a password every time:
- The first time you enable TUN mode, macOS shows a "System extension blocked" prompt.
- Go to System Settings → Privacy & Security → Network Extensions, find the client's extension entry, and allow it.
- Some clients still use the traditional method, requiring you to authorize "run core with administrator privileges" in settings — after entering your system password once, the background process holds the permission long-term.
If you enable TUN but don't see an entry in the Network Extensions list, the system's security policy likely blocked the installation — try restarting the client or the system and enabling it again.
On Linux, creating a tun0 device requires CAP_NET_ADMIN. The simplest approach is running the core process as root, or granting that capability to the binary directly:
sudo modprobe tun
sudo setcap cap_net_admin=eip /path/to/mihomo
The advantage of using setcap is that you don't need to launch the entire client as root — only the core process gets network-management privileges, which better follows the principle of least privilege. GUI clients (some GTK/Qt-based wrappers, for instance) usually have an "Authorize TUN" button in settings that runs the exact command above under the hood.
TUN mode gives a client the ability to take over all system routing. Only obtain clients from official channels and verify the download source — never grant administrator rights or CAP_NET_ADMIN to a program from an unknown source.
DNS Behavior: fake-ip, Hijacking, and Routing Loops
SECTION / DNS BEHAVIOROnce TUN mode is enabled, DNS queries are intercepted by the virtual adapter too — and this is where things most often go wrong. Your config usually needs to explicitly declare a DNS hijacking and resolution strategy:
tun:
enable: true
stack: system
dns-hijack:
- "any:53"
auto-route: true
auto-detect-interface: true
dns:
enable: true
fake-ip-range: 198.18.0.1/16
nameserver:
- 223.5.5.5
- 1.1.1.1
dns-hijack forces all outbound DNS requests on port 53 to be intercepted and handled by the Clash core, preventing traffic from bypassing the rules and connecting directly to a censored or otherwise unreliable DNS server. fake-ip mode assigns each domain a fake IP within a private address range; apps see this fake IP, and the core only swaps in the real outbound address once the connection is actually established. The benefit is that rules can match by domain name without waiting on the real DNS resolution result.
Common troubleshooting angles:
- DNS leaks. If DNS requests from direct traffic aren't being intercepted (for example, the browser is still using the OS's native DNS), check whether dns-hijack covers the right port, and whether your OS network settings have a fixed DNS server manually specified that's conflicting.
- Routing loops. Under TUN mode, the connection to the proxy server itself must not be routed back through the TUN adapter, or you'll get a "proxy connecting to itself" infinite loop. Clients usually avoid this through auto-detect-interface or explicit process exclusion rules — when configuring manually, always make sure this option is enabled.
- Conflicts with VPN clients. Running TUN mode and another VPN app at the same time means both are fighting over the default route, which shows up as one of them intermittently failing. It's best not to run both at once.
Confirming TUN Mode Is Actually Working
SECTION / VERIFICATIONAfter enabling TUN mode, verify it in the following order rather than trusting the toggle's on/off state alone:
- Check that the virtual adapter exists. On Windows, open "Network Connections" and look for a new adapter named something like "Mihomo" or "Clash." On macOS/Linux, run ifconfig or ip addr to check for a utun / tun0 device.
- Check the default route. Use route print on Windows, or netstat -rn / ip route on macOS/Linux, to confirm the default route points to the virtual adapter rather than the physical one.
- Test with a tool that ignores the system proxy. For example, run curl in a terminal without any proxy flags, or ping a domain from the command line that your rules say should be proxied, and see whether it takes the expected route.
- Check the client's connection log. Most clients label each connection's inbound type in the "Connections" or "Logs" panel. Connections under TUN mode are usually tagged TUN rather than HTTP/SOCKS — a reliable way to confirm which path is actually in effect.
If all of the above checks out but a specific app still isn't being proxied, it's most likely bound to a fixed network interface at the OS level or using a custom DNS resolver. Troubleshoot that program's own network settings rather than continuing to adjust the Clash config.