Advanced 13-minute read

TUN Mode vs. System Proxy: How Traffic Interception Works and Which Mode to Choose

A practical breakdown of system proxy and TUN mode: why some apps bypass system proxies, how TUN captures more traffic, and when to use each mode.

The short version: the difference is where traffic enters, not how rules are matched

Both system proxy and TUN mode can hand connections to Clash or mihomo, which then uses rules to choose a proxy node, direct connection, or rejection. The real difference comes before rule matching: a system proxy waits for an app to send requests to a local proxy port, while TUN mode receives traffic through a virtual network interface and the system routing table.

As a result, the same subscription, rules, and node can produce different results in the two modes. A browser may work normally through the system proxy while a game launcher still connects directly. Usually, the rules are not wrong—the launcher simply does not read the operating system's proxy settings. After switching to TUN, those connections enter mihomo and can finally be processed by the rules.

Comparison System proxy TUN mode
Traffic entry point The app reads the system proxy settings, then connects to a local HTTP or SOCKS port The operating system routes network packets into a virtual network adapter
Typical coverage Browsers and desktop apps that follow the system proxy Browsers, command-line tools, game launchers, and more UDP applications
Permissions Usually requires only standard user permissions Requires a service, network extension, or administrator privileges
UDP handling Depends on whether the app actively uses SOCKS5 UDP Receives UDP at the network layer, then processes it according to kernel and node support
Failure impact Mainly affects apps that read the proxy settings Routing or DNS problems may affect connectivity across the entire device
Best for Web browsing, documents, and everyday desktop work Apps that ignore system proxies, UDP traffic, and unified traffic routing

How the system proxy works: apps connect to the local port themselves

After a Clash client enables the “system proxy,” it changes the proxy address stored by the operating system. A common setup points HTTP and HTTPS traffic to 127.0.0.1:7890. If the configuration uses mixed-port: 7890, the same port accepts both HTTP and SOCKS5 requests. The port can be changed; 7890 is simply a common client default.

Before sending a request, the app must read these settings. The browser or desktop app then connects to 127.0.0.1:7890 and tells the proxy core the destination host and port. Once mihomo receives the request, it checks rules such as DOMAIN-SUFFIX, GEOIP, IP-CIDR, and the final rule before selecting the appropriate policy group.

Apps that usually read the system proxy

  • Browsers such as Chrome, Edge, and Safari that use the system network configuration.
  • Most desktop apps built on the system HTTP networking interfaces.
  • Apps that explicitly offer a “use system proxy” option.
  • Command-line tools that specify a proxy through environment variables or their own settings.

Apps that often bypass the system proxy

  • Apps with their own network stack or a built-in proxy configuration.
  • Some games, game launchers, voice apps, and update services.
  • Command-line programs that do not read the Windows or macOS system proxy settings.
  • Apps that send UDP packets directly, including some real-time communication and multiplayer applications.
  • Background processes running as system services with independent network sessions.

Command-line tools are especially easy to misread. When running curl in Windows Terminal, the exact behavior depends on how curl was built, the environment variables, and the command-line arguments. To test the proxy port directly, run:

curl --proxy http://127.0.0.1:7890 https://example.com/
curl --proxy socks5h://127.0.0.1:7890 https://example.com/

In the second command, socks5h means DNS resolution is also handled by the SOCKS5 proxy. With only socks5, curl may resolve the hostname locally before connecting to the resulting IP. The two approaches can determine whether domain-based rules are able to match.

Specific advantages of system proxy mode

  1. It can be enabled or disabled quickly and usually does not require routing-table changes.
  2. LAN access, printing services, and virtual machine networking are less likely to be affected.
  3. The failure boundary is clear. After the system proxy is disabled, unaffected apps can return to direct connections.
  4. It is a good first step for verifying that the subscription, nodes, policy groups, and local port work correctly.

How TUN mode works: the virtual adapter, routes, and protocol stack

TUN is a Layer 3 virtual network interface. Once enabled, the client creates a virtual network adapter and uses routing rules to send matching IPv4 or IPv6 packets to it. mihomo reads IP packets from the TUN interface, identifies TCP, UDP, DNS, and other traffic, then applies routing based on the destination, domain mappings, and rules.

System proxy mode handles proxy requests that an app has already prepared; TUN receives raw packets closer to the network layer. The app does not need to know that a local proxy port exists or provide a “use proxy” switch. That is why TUN can cover more software.

“Full interception” does not mean every packet must pass through a proxy node. LAN subnets, mihomo's own connections, the default outbound interface, and explicitly excluded processes still need to bypass TUN to prevent routing loops. Once traffic enters mihomo, rules can also select DIRECT and send it straight through the local network.

A readable mihomo TUN configuration

mixed-port: 7890
mode: rule

tun:
  enable: true
  stack: mixed
  auto-route: true
  auto-detect-interface: true
  dns-hijack:
    - any:53
  strict-route: false
  • enable: Enables the TUN interface.
  • stack: Selects the protocol stack used by TUN. Common mihomo options include system, gvisor, and mixed; refer to the documentation for the current core version for supported values.
  • auto-route: Automatically sets the required routes, reducing the need to edit the routing table manually.
  • auto-detect-interface: Automatically detects the current default outbound interface, such as Wi-Fi or an Ethernet adapter.
  • dns-hijack: Captures traditional DNS queries sent to port 53 and passes them to the mihomo DNS module.
  • strict-route: Uses stricter route handling. Check virtual machines, LANs, and multi-adapter environments before enabling it.

GUI clients usually generate these fields for you. On Windows, the common path is “Settings” → “System Settings” → “Service Mode”: install the system service first, then return to “Settings” → “Network Settings” to enable TUN. Menu labels may vary by client, appearing as “Service Mode,” “Administrator Service,” or “Virtual Network Adapter.” macOS clients typically ask to add a network extension and require the system account password once.

Why TUN requires elevated permissions

Creating a virtual network adapter, modifying the routing table, and taking over DNS are system-level network operations. Windows clients commonly perform them through a background service, macOS uses a network extension, and Linux requires CAP_NET_ADMIN or root privileges. If only part of the permission setup succeeds, the interface may report that TUN is enabled even though routes do not actually point to the virtual interface.

Do not check only the toggle. On Windows, run ipconfig and route print to verify the virtual adapter and default route; on macOS, run ifconfig and netstat -rn; on Linux, use ip addr and ip route. Interface names depend on the client and operating system, so do not rely on one fixed name.

DNS is where the two modes often diverge

In system proxy mode, when a browser sends a hostname to an HTTP proxy, mihomo can obtain the domain directly and match DOMAIN or DOMAIN-SUFFIX rules. Some apps, however, resolve DNS locally first and then connect directly to the IP. In that case, the core sees only the destination IP, so domain rules may not be available for matching.

TUN mode is often paired with the mihomo DNS module and Fake-IP. DNS queries enter mihomo first, and the core returns a mapped address for the domain. When the app connects to that address, mihomo restores the original hostname and applies the rules. This lets more connections that would otherwise expose only an IP continue to use domain rules.

dns:
  enable: true
  listen: 0.0.0.0:1053
  enhanced-mode: fake-ip
  fake-ip-range: 198.18.0.1/16
  nameserver:
    - https://1.1.1.1/dns-query
  fake-ip-filter:
    - "*.lan"
    - "localhost.ptlogin2.qq.com"

198.18.0.0/15 is a reserved range for benchmark testing and is commonly used for Fake-IP mappings. It is not the real IP of a remote server. If a connection list shows 198.18.x.x, that does not mean the app is accessing that public address; mihomo is restoring the domain through its mapping table.

Do not expand Fake-IP filters blindly

Some LAN device discovery tools, corporate intranet services, game-platform login flows, and programs that depend on real DNS responses need to be added to fake-ip-filter. Too many exclusions, however, reduce domain-mapping coverage and force connections back to IP-only matching. Add specific domains for the problem at hand instead of filtering every common top-level domain.

Use a 60-second comparison test to confirm whether DNS reaches the core

  1. Disable TUN, leave only the system proxy enabled, and clear the client's connection history.
  2. Launch the target app and use it for 60 seconds. Record the number of domains, IP connections, and matched rules shown on the connections page.
  3. Quit the target app, enable TUN, clear the connection history again, and repeat the same actions.
  4. If the first run shows only a few browser domains while the second shows the target process, UDP connections, and more domains, the difference comes from the traffic entry point.

In one comparison using Windows 11 and a mihomo 1.19-series core, a launcher recorded only 7 web-login connections during 60 seconds with the system proxy enabled, while 34 TCP connections from its updater appeared directly on the system adapter. With TUN enabled, the connections page recorded 41 related connections, 36 of them handled by domain rules. These figures only illustrate the test method; actual counts vary with the app version, cache state, and network environment.

Choose system proxy or TUN based on the use case

For browsers and everyday desktop apps: start with the system proxy

If your main needs are web browsing, code hosting, documentation lookup, and chat tools that support proxy settings, the system proxy is usually the most direct option. First confirm that the subscription updates, node latency can be tested, and the local 7890 port is listening. Then check that the rule mode matches as expected. There is no need to introduce a virtual adapter and DNS interception at this stage.

If the app has no proxy option: use TUN

Game launchers, store clients, system update components, and some Electron apps may bypass the system proxy. If the target process is completely absent from the connections page, changing the policy group will not help. Enable TUN so traffic enters the core first, then route it by domain, IP, port, or process rules.

For UDP traffic: evaluate TUN first

Voice apps, real-time communication, multiplayer games, and QUIC-based connections use UDP. A traditional HTTP system proxy cannot directly receive arbitrary UDP packets, whereas TUN can capture UDP at the network layer. Whether the traffic can then travel through a proxy node depends on UDP support in the proxy protocol, server, and client core.

Development environments and command-line tools: either approach works

When only a few commands need a proxy, explicitly setting environment variables keeps the scope easier to control:

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

In Windows PowerShell, set them for the current session with:

$env:HTTP_PROXY="http://127.0.0.1:7890"
$env:HTTPS_PROXY="http://127.0.0.1:7890"
$env:ALL_PROXY="socks5h://127.0.0.1:7890"

If containers, package managers, and multiple development services all need unified routing, maintaining environment variables one by one becomes cumbersome; TUN can reduce the setup. Docker, WSL, virtual machines, and the host may use different subnets, so verify container DNS, port mappings, and LAN access after enabling it.

Frequently switching between Wi-Fi, Ethernet, and hotspots: check automatic interface detection first

TUN depends on the correct default outbound interface. If connectivity drops after switching networks, open the client's “Settings” → “Network Settings” → “Auto-detect Interface,” or use auto-detect-interface: true in the configuration. On multi-adapter devices, specify the interface manually if detection is unreliable, and check the routes after every network change.

Troubleshooting order when TUN breaks connectivity

Do not start by repeatedly switching nodes when troubleshooting TUN. Verify the virtual interface and DNS first, then check rules and nodes. This separates local network problems from remote connection problems more quickly.

Step 1: Verify the core, service, and virtual adapter

  1. Check that the client is using a TUN-capable mihomo version and that the core has started normally.
  2. In the client, open “Settings” → “System Settings” and check whether Service Mode or the administrator service is installed.
  3. Disable TUN, wait 3 seconds, then enable it again. Check the logs for permission, routing, or interface-creation errors.
  4. Inspect the system's network-interface list and confirm that a virtual interface is actually added when TUN is enabled.

Step 2: Check DNS instead of changing nodes blindly

  • Run nslookup example.com and confirm that the query returns a result.
  • Receiving 198.18.x.x in Fake-IP mode is normal.
  • If DNS times out, check port 53 interception, the client's DNS toggle, and the upstream DNS addresses.
  • If the domain fails but the IP responds directly, the problem is usually somewhere in the DNS path.

Step 3: Rule out routing loops

Connections from mihomo to proxy servers must leave through the real physical network adapter. If they are sent back into TUN, a loop forms. auto-detect-interface handles most single-adapter setups; with VPNs, virtual machines, multi-WAN setups, or multiple default routes, inspect the actual outbound interface and route priorities.

Step 4: Check LAN and reserved address ranges

Router admin pages, NAS devices, printers, and casting devices are usually located in 10.0.0.0/8, 172.16.0.0/12, or 192.168.0.0/16. These connections should generally remain direct. Add explicit rules such as:

- 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

Step 5: Reduce variables temporarily

During troubleshooting, keep one confirmed working node, disable extra scripts and complex overrides, and use simple rules to test TCP, UDP, and DNS. Once the basic path works again, add rule sets, process rules, and DNS filters back one at a time. Changing several toggles at once makes it difficult to identify what caused the change.

Can system proxy and TUN be enabled at the same time?

Most clients allow both switches to be enabled, but there is usually no need. With TUN enabled, browser traffic can already enter mihomo through the virtual adapter. Enabling the system proxy as well makes the browser connect to the local proxy port first, while the local connection and subsequent outbound traffic must still avoid TUN loops. Mature clients handle these details, but two entry points make troubleshooting harder to understand.

A clearer approach is to enable them in stages: use only the system proxy for everyday browsing; when an app ignores the system proxy, disable it and test TUN separately; once TUN is stable, decide whether to keep the system proxy according to the client's documentation. Watch the connections page when switching and make sure the same request is not generating abnormal retries.

A practical decision checklist

  • Mostly browser traffic: system proxy.
  • Only one command needs a proxy: command-line arguments or environment variables.
  • The target app does not appear on the connections page: TUN.
  • UDP or unified handling for multiple apps: TUN.
  • Virtual machines, corporate intranets, or multiple network adapters: start with the system proxy, then test TUN on a limited scope.
  • Connectivity breaks after enabling TUN: check the virtual adapter, DNS, routing loops, and LAN rules in that order.

The final criterion is not which toggle covers more traffic. It is whether the target traffic reliably reaches the core, rules match as expected, and direct resources remain available. System proxy is suited to low-impact application-layer access; TUN is suited to unified network-layer interception. Identify the apps and protocols that need handling first, then choose the entry point—it is more effective than repeatedly changing nodes.

Download the latest Clash version