First, separate traffic capture from outbound routing

System proxy and TUN solve the same first-step problem: how an app's connections reach the Clash core. Once there, the operating mode, routing rules, and policy groups determine whether traffic goes direct, through a proxy, or is blocked. Enabling TUN does not mean all traffic is sent through a proxy, and enabling the system proxy does not mean every process will use it.

This article uses Clash clients running the mihomo core as an example. TUN implementations vary across clients, cores, and operating systems, so do not assume a toggle with a particular name works the same way in every app. Before making changes, check the client's core information to confirm it is running mihomo, then refer to the configuration fields it supports.

System proxy: apps connect to a local port

How a browser hands connections to Clash

When you enable the system proxy, the client usually sets the operating system's HTTP and HTTPS proxy addresses to a local listening address. For example, mixed-port: 7890 in the configuration accepts both HTTP proxy and SOCKS requests on the same port. 7890 is only an example; check the active configuration for the port in use.

A browser that supports the system proxy reads the setting and connects to 127.0.0.1:7890. For an HTTPS site, it typically uses HTTP CONNECT to establish a tunnel, then carries TLS traffic through it. Standard proxy forwarding does not require installing a root certificate to decrypt website traffic.

Apps that support the system proxy
  → 127.0.0.1:7890
  → mihomo rule matching
  → DIRECT or selected proxy node

System settings don't cover every app

So if a browser works but a terminal doesn't, the node may still be fine. The two apps may not be using the same traffic-capture path at all. Likewise, Windows WinHTTP proxy settings and the proxy settings in the user interface are separate; the output of netsh winhttp show proxy alone cannot tell you whether a browser is using a proxy.

TUN: capture traffic with a virtual adapter and routes

TUN is a Layer 3 virtual network interface. When enabled, the client or a helper service creates a virtual adapter and adjusts routes according to its configuration. IP packets whose destination matches those routes are sent to the core for processing; apps do not need to understand HTTP proxy or SOCKS protocols first.

App sends an IP packet
  → Operating system selects a route
  → TUN virtual adapter
  → mihomo network stack and rule matching
  → DIRECT or selected proxy node

This path can bring apps that ignore the system proxy into the routing rules. It does not guarantee that every protocol can be forwarded through every proxy node. For example, game voice chat uses UDP, so the node protocol, server, and relevant settings must support UDP. Whether ICMP gets the expected response also tells you nothing conclusive about HTTPS proxy health.

What three common fields do

FieldPurposeWhat to check
auto-routeAutomatically configure routes through TUNCheck for conflicts with a company VPN or other virtual adapters
auto-detect-interfaceAutomatically detect the network interface used for outbound trafficCheck that the correct interface is selected after switching between Wi-Fi and Ethernet
stackChoose the network stack used by TUNChoose based on core support and system compatibility

Creating an adapter and changing routes usually requires administrator privileges, a system service, or platform authorization. A client's “service mode” typically lets a helper service perform these tasks; it is not a proxy server, and installing the service does not guarantee that a node will work. If the TUN toggle immediately switches off, check permissions, the service, and adapter creation logs before troubleshooting nodes.

DNS and fake IP: how domains are used for routing

With a system proxy, an app may pass the domain directly to the local proxy, or it may resolve the domain locally first. The behavior depends on the app and proxy protocol. TUN receives IP packets instead; if the core has no corresponding domain mapping, it cannot always recover the original domain from the destination IP alone.

In fake-IP mode, DNS returns a synthetic address for a domain and stores the domain-to-address mapping. For example, mihomo commonly uses the 198.18.0.0/16 range for these mappings; it does not represent the website's real outbound IP address. When the app connects to the synthetic address, the core can look up the domain and apply rules such as DOMAIN-SUFFIX.

Merge this snippet into your existing profile

The mihomo YAML snippet below illustrates how the fields work together. It contains no nodes or policy groups and cannot be used as a complete subscription. It uses IPv4 DNS as an example; do not overwrite an existing profile or add a second top-level dns or tun key. If your client uses overrides or merge rules, check the final active configuration.

mixed-port: 7890
mode: rule

tun:
  enable: true
  stack: system
  auto-route: true
  auto-detect-interface: true
  dns-hijack:
    - any:53

dns:
  enable: true
  listen: 127.0.0.1:1053
  enhanced-mode: fake-ip
  fake-ip-range: 198.18.0.1/16
  nameserver:
    - 223.5.5.5

dns-hijack with any:53 hijacks matching traditional DNS requests captured by TUN; by default, it matches UDP. To handle DNS over TCP, add tcp://any:53 as described in the core documentation. This does not force every DNS protocol to use local resolution: browser-based DoH usually runs over HTTPS and cannot be captured by port 53 rules alone.

Choosing a setup: start with app requirements

Use caseTry firstHow to verify
Browsers and desktop apps that use the system proxySystem proxyOpen a website and confirm its domain appears in the client's connection log
A single command-line toolThe tool's own proxy optionSet the local proxy port explicitly and compare the result with a request that uses no proxy
Apps that ignore the system proxyTUNTurn off the system proxy and check whether new app connections still reach the core
Games, voice chat, and other UDP appsTUN and a node that supports UDPCheck UDP connections, policy group selection, and whether the session works
Using a company VPN at the same timeKeep your existing network setup for nowCheck internal routes, DNS resolution, and excluded addresses, then enable settings one at a time

You can enable both methods at once, but it's best not to do so during initial troubleshooting. Apps that support the system proxy may keep connecting to the local proxy port, while other apps use TUN. Both paths can look healthy in the connection log, making it hard to tell which one is working. Verify one path at a time, then combine them if needed.

Don't assume that turning on TUN will always reduce latency. TUN changes how traffic is captured on your device; the node determines the remote exit location, route quality, and server status. For a fair comparison, keep the target site, node, rule mode, and test tool constant so you don't mistake a node change for an effect of the virtual adapter.

Switching methods: change one variable at a time

  1. Save your current configuration. Note the profile name, local port, operating mode, and policy group selection. Copy any custom overrides so you can restore them if a subscription update changes the configuration.
  2. Verify the local proxy first. Turn off TUN temporarily while keeping the core running, then use an explicit proxy command to access a test URL. If it fails, troubleshoot the port, node, or rules first.
  3. Test the system proxy. Turn it on, visit the same URL in a browser, and check the client's connection page for the domain, matched rule, and actual outbound route. Turn the system proxy off after testing.
  4. Enable TUN by itself. Grant permissions or start the service as required by the client. Check the logs for adapter creation or route configuration failures, then test an app without a proxy setting.
  5. Check traffic beyond your main use case. Test LAN devices, company intranet services, voice chat, and network access after waking from sleep. Confirm that traffic which should remain direct isn't being sent to a remote node.

Use commands to distinguish port issues from routing issues

The URLs below are examples for testing. On Windows, use curl.exe; on macOS and Linux, use curl. Replace the example port with the one in your active configuration. The second command removes the explicit proxy setting for that request, but with TUN enabled, the virtual adapter may still capture its packets.

# Test the local HTTP proxy
curl --proxy http://127.0.0.1:7890 --connect-timeout 10 -I https://example.com/

# Bypass curl's proxy settings and check the system route
curl --proxy "" --noproxy "*" --connect-timeout 10 -I https://example.com/

An HTTP response only confirms that the request got a response; by itself, it does not prove whether the request used a proxy. Also check the client's connection page to see whether the request appears, which rule matched, and whether the final route was DIRECT or a proxy node. A browser may reuse an existing connection, so close old connections or restart the test app before checking the result after a switch.

Troubleshoot common issues by checking the entry point, DNS, and routes

System proxy works, but TUN doesn't

Web pages work, but games or voice chat don't

First confirm that the app's connection enters TUN, then check that the node selected by the relevant policy group supports UDP. Web browsing mainly tests TCP or the browser's own connection path; it cannot prove that a game's UDP traffic works. Don't rely on a node latency test alone either: a successful test URL and a working application protocol are two different things.

Internet access stops after closing the client

First check whether the system proxy still points to a 127.0.0.1 port that is no longer listening. Then use the client to shut down TUN normally and confirm that routes and DNS settings are restored. If the client exited unexpectedly, restart it and shut it down normally. If the problem persists, save the logs and restore settings one at a time using your operating system's network controls; don't delete every adapter or route at once.