The short answer: use system proxy for browsers, and TUN for full-device coverage
System proxy and TUN mode are not two different proxy protocols. They are two ways to hand local connections to the Clash or Mihomo core. The rules, policy groups, and current operating mode still determine whether traffic connects directly and which node it uses. The real difference is where traffic enters the core and which apps are included.
If you mainly browse the web or use desktop apps that support system proxy settings, system proxy is usually the better starting point. It starts quickly, requires fewer permissions, and is easy to undo. Enable TUN when command-line tools, game launchers, some store clients, or UDP apps ignore the system proxy.
| Use case | Preferred option | Why |
|---|---|---|
| Everyday browsing in Chrome, Edge, or Safari | System proxy | Browsers usually read the operating system proxy settings, keeping the setup simple |
| Terminal, Git, and package managers | Configure a proxy in the tool or use TUN | Many command-line programs do not automatically read the desktop system proxy |
| Games, UDP, and store clients | TUN mode | Captures TCP and UDP at the IP layer for broader coverage |
| Only a few apps should use the proxy | System proxy | Apps that do not use the system proxy generally keep their original connection path |
| Centralized DNS handling and traffic routing | TUN mode | DNS hijacking, Fake IP, and routing rules can work together as one system |
| Corporate VPNs, virtual machines, or complex routing | Start with system proxy | After TUN changes the routes, it is more likely to conflict with another virtual network interface |
How system proxy works: apps hand connections to a local port
When system proxy is enabled, the Clash client points the operating system's HTTP, HTTPS, or SOCKS proxy to a listening port on the local machine. A common setup uses mixed-port: 7890, allowing one port to accept both HTTP and SOCKS5 connections. Older configurations may use port: 7890 and socks-port: 7891 separately. These ports are entry points between local apps and the proxy core, not ports on the remote node.
An app must read and follow the system proxy settings for its connection to enter Clash. Chrome, Edge, Safari, and many desktop apps built on system networking frameworks typically do so. After an app connects to 127.0.0.1:7890, the core reads the destination domain or address and uses DOMAIN-SUFFIX, IP-CIDR, rule providers, and the final rule to choose DIRECT, REJECT, or a proxy policy group.
How to verify that system proxy settings were applied
- On Windows 11, open Settings → Network & Internet → Proxy and check that the manual proxy server points to
127.0.0.1and the port shown by the client. - On macOS, open System Settings → Network → your current network → Details → Proxies, then check the Web Proxy and Secure Web Proxy entries.
- In ClashX, use the menu bar icon to check the Set as System Proxy status and confirm that the current configuration is running.
- When using a Mihomo GUI client, also check the mixed port under Settings → Clash Settings. Menu names may vary slightly between client versions.
Why the browser works but the terminal does not
Command-line tools such as curl, Git, npm, and pip do not handle system proxy settings consistently. Some versions read environment variables, while others require separate configuration. For a temporary test, set HTTP_PROXY, HTTPS_PROXY, and ALL_PROXY in the current terminal and explicitly point them to the local port:
export HTTP_PROXY=http://127.0.0.1:7890
export HTTPS_PROXY=http://127.0.0.1:7890
export ALL_PROXY=socks5h://127.0.0.1:7890
curl -I https://example.com
The h in socks5h tells the SOCKS proxy to resolve domain names, reducing discrepancies caused by resolving them locally first. In Windows PowerShell, use $env:HTTPS_PROXY="http://127.0.0.1:7890" to set the variable for the current session. Temporary variables stop affecting new sessions after the terminal is closed.
How TUN mode works: a virtual network interface receives IP traffic
TUN mode creates a virtual layer-3 network interface and uses the routing table to direct matching IP packets to it. The Mihomo core reads the source address, destination address, and transport protocol from each packet, reconstructs the connection, and then applies proxy rules. Apps still see ordinary network connections, so they do not need to understand HTTP or SOCKS proxies or read the system proxy settings.
This is why TUN can cover more programs. Game launchers with their own network stack, command-line programs that ignore system proxy settings, and UDP-based apps can all enter the TUN capture path. However, “TUN enabled” does not mean “every packet goes through a remote node.” LAN addresses, excluded routes, DIRECT rules, process rules, and client settings can all change the final path.
Basic TUN configuration in Mihomo
mixed-port: 7890
mode: rule
tun:
enable: true
stack: mixed
auto-route: true
auto-detect-interface: true
dns-hijack:
- any:53
dns:
enable: true
enhanced-mode: fake-ip
listen: 0.0.0.0:1053
fake-ip-range: 198.18.0.1/16
nameserver:
- https://1.1.1.1/dns-query
auto-route automatically adds the required routes, auto-detect-interface attempts to identify the actual outbound network interface, and dns-hijack sends matching DNS requests on port 53 to the core's DNS module. stack: mixed is a common Mihomo choice that combines the system stack with userspace processing. Support for system, gvisor, or mixed varies by operating system, core version, and client, so similarly named options from other cores should not be copied directly.
Coverage comparison: TCP, UDP, LAN, and process matching
TCP vs. UDP
System HTTP proxy settings are primarily designed for TCP-based HTTP and HTTPS connections. SOCKS5 can support UDP, but only when the app explicitly supports SOCKS5 UDP forwarding; the operating system's regular web-proxy toggle does not automatically send all UDP traffic to a SOCKS port. Voice chat, real-time games, QUIC, and some DNS requests may therefore bypass the system proxy.
TUN sees both TCP and UDP at the IP layer, making it better suited to scenarios that require consistent handling of both transport protocols. Even then, the remote node protocol must support UDP forwarding, and the active node in the policy group must have UDP enabled. If UDP connections still fail after matching a rule, check the node protocol, server configuration, and network MTU instead of repeatedly toggling TUN.
LAN devices and private addresses
Printers, NAS devices, and router admin panels commonly use 192.168.0.0/16, 10.0.0.0/8, or 172.16.0.0/12. After enabling TUN, retain DIRECT rules for the LAN and confirm that automatic routing does not send these ranges to the wrong interface. Common rules can be placed before proxy rules:
rules:
- IP-CIDR,10.0.0.0/8,DIRECT,no-resolve
- IP-CIDR,172.16.0.0/12,DIRECT,no-resolve
- IP-CIDR,192.168.0.0/16,DIRECT,no-resolve
- IP-CIDR,127.0.0.0/8,DIRECT,no-resolve
- MATCH,PROXY
If the corporate intranet also uses these private ranges, routing by subnet alone is not enough; the corporate VPN interface must also have the correct route priority. When the public internet works but internal hostnames do not, compare the routing table before and after enabling TUN instead of changing the proxy node immediately.
How reliable are process rules?
In TUN mode, the core can attempt to identify the process that opened a connection on supported platforms and match PROCESS-NAME or PROCESS-PATH. Process identification depends on system permissions, app sandboxes, child-process models, and the core implementation. A browser's network service may run in a separate process, while container traffic may appear only under the host-side process. For important routing decisions, rely primarily on domains, IP addresses, and rule providers, using process rules as a supplement.
DNS comparison: when is the domain resolved?
With system proxy, DNS behavior depends on the app and proxy type. A browser may enable encrypted DNS itself, or resolve through the operating system before connecting to the resulting IP; a SOCKS5 client may instead send the domain to the proxy. If the domain has already become an IP before entering Clash, the core may be able to match only the destination IP, while domain-rule visibility depends on sniffing and mapping state.
TUN is often used together with the Mihomo DNS module, DNS hijacking, and Fake IP. Fake IP mode returns temporary addresses from a reserved range, commonly 198.18.0.0/16 by default, then restores the original domain through its mapping. This lets domain rules continue to work when an app connects only to an IP and reduces inconsistencies between local and proxy DNS paths.
Fake IP is not the same as remote DNS
Fake IP is a mechanism in which the local core maintains domain mappings. The upstream query still depends on nameserver, proxy-server-nameserver, rule-specific DNS settings, and the current proxy configuration. The node server's domain also needs a working resolution path; otherwise, you can create a circular dependency in which the node must be reached before its address can be resolved.
- If a webpage reports a certificate name error, check whether another program rewrote DNS and whether the Fake IP mapping is still valid.
- If LAN devices cannot be reached by hostname, add the relevant domains to the Fake IP filter list or configure dedicated DNS for LAN domains.
- When an app has built-in DoH, hijacking ordinary port 53 traffic may not capture those queries. Check the browser's Secure DNS settings and whether the expected rules are matching.
- If many domains fail briefly after waking from sleep, reload the configuration and flush the operating system DNS cache before deciding whether to recreate the TUN interface.
Comparing permissions, compatibility, and performance overhead
Permission requirements
System proxy usually needs only to modify the current user's network proxy settings. TUN must create a virtual network interface, change the routing table, or call a system network extension. Windows may require administrator approval, macOS may require approval for a network extension or helper service, and Linux commonly needs CAP_NET_ADMIN, root access, or capabilities granted to the process by systemd.
Grant permissions only to a client whose source and version you have verified. If the TUN switch immediately turns itself off, check the client service status and core logs first; if interface creation failed, then check system permissions. Reinstalling configuration files repeatedly usually will not fix driver, service, or capability-authorization problems.
Coexisting with VPNs, virtual machines, and containers
Corporate VPNs and TUN can both create virtual interfaces and write default routes. The software started later may change route priority, causing connection loops, broken intranet access, or traffic to leave through the wrong interface. A common order is to connect the corporate VPN first, then start Clash TUN, and use auto-detect-interface or the client's interface setting to confirm the actual exit. If company policy prohibits route changes, system proxy is the safer choice.
WSL2, Docker Desktop, Parallels, and VMware maintain their own virtual subnets. Host-side TUN does not necessarily cover all traffic inside a virtual machine, and the VM may treat the host as its gateway. Check the default routes on the host, virtual interface, and guest separately; do not judge only from the host browser's results.
Performance depends on the environment
TUN adds virtual-interface I/O, protocol-stack processing, and rule evaluation. The theoretical path is longer than an app connecting directly to a local proxy port, but for everyday web browsing the difference is usually smaller than remote-node latency. The figures below are a comparison from one fixed setup, not a guarantee for all devices: Windows 11 24H2, Mihomo 1.19.8, Ryzen 7 7840U, wired gigabit networking, 10 consecutive tests using the same node and rules.
| Metric | System proxy median | TUN mixed median |
|---|---|---|
| Time to first byte | 46.8 ms | 47.6 ms |
| Single-connection download | 286 Mbps | 274 Mbps |
| Idle core memory | 78 MB | 91 MB |
| CPU during sustained transfer | 7.4% | 9.1% |
In this sample, TUN added about 0.8 ms to the first packet and reduced download throughput by about 4.2%. Remote-node load, encryption protocol, NIC offloading, and MTU can cause much larger swings. On low-power devices, sustained-transfer CPU usage and temperature matter more than a single peak speed-test result.
Choose and troubleshoot step by step: change one switch at a time
Option 1: verify system proxy first
- Start the client and load the configuration. Confirm that the local mixed port is
7890or the actual value shown in the UI. - Select rule mode and pin the policy group for the test domain to a working node.
- Enable system proxy, open the test page in a browser, and watch the connection log for the domain and policy name.
- If the browser works, test the terminal, store client, or target app separately and note which programs do not appear in the log.
- Only when there is a confirmed coverage gap should you disable the system-proxy test and enable TUN. Avoid running both paths at once, which makes diagnosis harder.
Option 2: check four areas after enabling TUN
- Check the log for successful TUN interface creation and for permission, routing, or device-occupancy errors.
- Check the default route and actual outbound interface, making sure the proxy-server connection is not sent back into TUN and trapped in a loop.
- Check the DNS log to confirm that queries enter the Mihomo DNS module and match the expected domain rules.
- Test TCP, UDP, LAN addresses, and wake-from-sleep recovery separately. A single webpage loading successfully is not enough.
Common symptoms and fixes
| Symptom | Check first | Recommended action |
|---|---|---|
| All network access stops after enabling TUN | Permissions, default route, and interface detection | Review interface-creation logs and select the correct outbound network adapter |
| Websites work but the game cannot connect | UDP support and node capability | Confirm rule matching, node UDP support, and MTU |
| The public internet works but the NAS is unreachable | Private-subnet routing | Add LAN DIRECT rules and check route priority |
| Traffic is still affected after disabling system proxy | Residual proxy settings | Restore the proxy settings in system preferences and exit related clients |
| TUN stops working after connecting to a corporate VPN | Startup order and virtual interfaces | Redetect the outbound interface; use system proxy instead if necessary |
| Some domains repeatedly fail to resolve | DNS interception chain and Fake IP | Remove duplicate DNS interception and check upstream DNS and filter settings |
The final choice: base it on app coverage, not “mode strength”
System proxy is better for browsers and desktop apps that explicitly support proxy settings. It has less impact on the routing table, works well as a daily default, and makes it easy to verify whether nodes and rules are working. If you use a terminal tool only occasionally, set its environment variables separately instead of enabling TUN all the time.
TUN is better when you need UDP coverage, support for programs that ignore system proxy settings, complex DNS routing, or unified handling across different types of apps. It does not make the node faster; it provides a more complete traffic entry point. In return, you must manage permissions, virtual interfaces, DNS, and routing conflicts.
A practical setup is to keep system proxy enabled and use TUN when needed. During the initial deployment, get system proxy, node selection, and rule matching working first, then enable TUN to expand coverage. When something breaks, inspect the traffic entry point, DNS, routes, rules, and node capabilities in that order. This is more effective than repeatedly switching among global mode, rule mode, and multiple toggles.