Separate traffic capture from rule-based routing

System proxy and TUN solve the same first-step problem: how an app's connection reaches the Clash core. Once it does, mode, rules, and proxy groups determine whether the connection goes direct, through a proxy, or gets rejected. So enabling TUN does not mean all connections use a proxy, and enabling the system proxy does not mean the entire device is captured.

The configuration examples in this article are based on mihomo, the kernel maintained by the Clash Meta project. GUI clients may generate or override some settings, and options in older Clash kernels, mobile VPN interfaces, and desktop clients are not necessarily equivalent. Before making changes, check the client’s kernel information or startup logs to confirm which kernel is running.

For example, with mode: rule, a connection entering through TUN may still match DIRECT. A connection sent through the system proxy to the local 7890 port may also be routed to a proxy node by the rules. Check the capture path and the selected route separately.

System proxy: apps connect to a local port

A GUI client’s system proxy option typically changes the operating system’s proxy settings, prompting apps that honor them to send requests to a local listening port. For example, with mixed-port: 7890, an app first connects to 127.0.0.1:7890, and the kernel establishes the onward connection. A mixed port accepts both HTTP proxy and SOCKS connections.

HTTPS through a proxy does not mean HTTPS is decrypted

When a browser uses an HTTP proxy to access an HTTPS site, it typically establishes a tunnel with CONNECT. Enabling the system proxy alone does not decrypt the site’s TLS traffic, nor do you need to install a site certificate for ordinary proxy use. HTTP as a proxy protocol and HTTPS as a website’s protocol are separate things.

Common cases the system proxy does not cover

  • Command-line tools: They may only read environment variables such as HTTP_PROXY and HTTPS_PROXY, or require a proxy to be specified with a separate option.
  • Games and custom network apps: They may open sockets directly without reading system proxy settings.
  • Windows services: Their account and networking APIs may differ from those of the signed-in user. A user's proxy settings do not automatically apply to every service.
  • UDP traffic: Enabling an HTTP proxy does not mean game UDP, voice traffic, or QUIC is being proxied.

A system proxy is a good place to start when testing a subscription, node, and basic rules. Changing the current user’s proxy settings generally does not require running as administrator, and it is easier to see which apps are affected. If only your browser needs a proxy, there is no need to enable TUN just to capture more traffic.

TUN: receive IP packets through a virtual interface

TUN creates a virtual network interface and uses routing to send eligible IP packets to the kernel. Apps connect to destination addresses as they normally would; they do not need to understand HTTP or SOCKS proxies. mihomo receives the packets, handles the connections, and selects an egress route according to the rules.

auto-route: true automatically configures relevant routes; auto-detect-interface: true detects the egress interface. Neither setting replaces the required permissions or guarantees compatibility with other VPNs. Connecting to a corporate VPN, switching Wi-Fi networks, or adding an Ethernet adapter can all change the egress interface and route priorities.

Comparison System proxy TUN
How traffic reaches the kernel The app connects to a local proxy port Routing sends IP packets to a virtual interface
Does the app need to cooperate? It must read proxy settings or have a proxy specified explicitly The app generally does not need to understand proxy protocols
UDP capture A standard HTTP system proxy does not cover UDP Can capture UDP within the routed scope; the egress must also support it
System permissions Usually changes settings for the current user Typically requires elevated privileges, a service, or platform authorization
Main areas to check Port, app settings, environment variables Virtual interface, routes, DNS, egress interface

TUN does not give a node that lacks UDP support the ability to carry UDP, nor does it mean every IP protocol can be forwarded through a remote proxy. In particular, do not rely on a single successful or failed ping to determine whether TCP website access is working; ICMP and application traffic may take different paths.

DNS: resolution paths affect rule matching

With a system proxy, DNS resolution depends on the app and proxy protocol. An HTTP proxy can receive a domain name as the destination; SOCKS5 can receive either a domain or an IP the app has already resolved. In a terminal, socks5:// and socks5h:// may use different resolution paths, so a change in the egress IP is not the only thing to check.

TUN typically receives IP packets. To keep domain-based rules working reliably, the kernel needs to use DNS mappings, existing metadata, or traffic sniffing as needed. Enabling the virtual interface without checking DNS can leave you with working websites but unexpected domain-rule matches.

What fake-ip and DNS hijacking each do

  • enhanced-mode: fake-ip: Returns a mapped address for applicable DNS queries, which the kernel then associates with the domain. The 198.18.0.1/16 range in this example is used for that mapping; it is not the actual address of a website or proxy egress.
  • dns-hijack: Sends matching DNS traffic to the kernel’s DNS handler. A common configuration covers UDP 53 and TCP 53.
  • nameserver: Specifies the upstream resolvers the kernel actually uses. Encryption, reachability, and routing policy need to be considered separately.

Check IPv6 separately as well. Configuring IPv4 routes does not prove that IPv6 is being captured under the same policy. If corporate intranet domains, printers, or LAN services rely on local DNS, preserve their resolution path. Not every DNS issue means the proxy node is unavailable.

mihomo configuration: start with minimal changes

The snippets below illustrate individual settings; they are not a complete subscription. Merge them into the corresponding sections of your existing configuration, keeping your current proxies, proxy-groups, and rules. Do not declare two dns or two tun sections at the same level. If your client supports overrides, use its persistent override feature so subscription updates do not discard your changes.

mixed-port: 7890
allow-lan: false
mode: rule
log-level: info

tun:
  enable: true
  stack: mixed
  auto-route: true
  auto-detect-interface: true
  dns-hijack:
    - "any:53"
    - "tcp://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
    - 119.29.29.29

127.0.0.1:1053 is a local DNS listening address explicitly opened here; it does not mean the operating system will automatically send queries to that port. TUN DNS hijacking is a separate path into the kernel’s DNS handler. The example uses conventional DNS upstreams to make the relationship between fields clear. Choose upstreams based on your network and privacy needs; these addresses are not universally optimal.

Which stack should you use: system, gvisor, or mixed?

  • system: Uses the system network stack to handle connections. Verify compatibility with your operating system and kernel implementation.
  • gvisor: Uses a user-space network stack and can serve as an alternative when troubleshooting specific compatibility issues.
  • mixed: Combines network stacks in mihomo: TCP uses the system path, while UDP uses the gVisor path.

Do not treat any stack option as a speed ranking that applies to every device. For a fair test, keep the node, destination, and rules the same; change only stack, restart the kernel, and make sure existing connections have closed before comparing connection success and app behavior. If your client or kernel does not support an option, restore the default rather than repeatedly applying settings from other versions.

Permissions and combining modes: test each separately first

On Windows, creating a virtual network adapter and configuring routes typically requires administrator privileges; some clients perform these operations through a service. macOS and Linux also require appropriate elevated or service permissions. On Linux, this includes access to the TUN device and network management capabilities. A TUN toggle showing as enabled only confirms that the operation was requested. Check startup logs for permission errors or failures to create the interface or add routes.

Choose an entry point based on what you need to cover

  1. Browsers and everyday desktop apps: Start with the system proxy alone and confirm that the node, rules, and local port work.
  2. Terminal tools: Test with an explicit proxy option first, then decide whether to set environment variables. Temporary variables are easier to undo than global changes.
  3. Apps that ignore proxy settings: Turn off the system proxy and test TUN by itself to avoid changing both entry points at once and making troubleshooting harder.
  4. When you need both entry points: You can enable them together after verifying each one. Apps explicitly configured to use the local proxy will use that route; TUN can capture other traffic that matches its routing conditions.

Enabling both does not necessarily mean traffic is proxied twice, nor does it automatically improve network quality. Normally, the kernel must keep its own outbound connections outside TUN capture to avoid a routing loop. Manual routes, other VPNs, or an incorrect egress interface can break this assumption. If problems appear when using both, revert to a single entry point first.

The system proxy may also have a “bypass local addresses” setting, while TUN handles private-network routes in a separate configuration layer. To access a NAS, LAN printer, or corporate intranet, check the system proxy bypass list, routing, and mihomo rules separately. Do not assume both modes use the same exceptions.

Testing and troubleshooting: find out which path a connection takes

Use the same destination for each comparison. First confirm that the local proxy port works, then check whether system-level capture is working. These commands are test methods, not claims about any pre-tested results. On Windows, use curl.exe explicitly to avoid same-named aliases in some PowerShell environments.

Step 1: Specify the proxy explicitly to isolate system capture

curl --proxy http://127.0.0.1:7890 --connect-timeout 10 --max-time 20 -I https://example.com/
curl --proxy socks5h://127.0.0.1:7890 --connect-timeout 10 --max-time 20 -I https://example.com/

The command will try the specified local port even if the system proxy is off. If the connection is refused, first check that the kernel is running and listening on 7890. If the request reaches the kernel but still fails, check the logs for DNS, rule matching, node handshake, and remote connection errors.

Step 2: Remove the explicit proxy and test the TUN path

curl --noproxy "*" --connect-timeout 10 --max-time 20 -I https://example.com/

--noproxy "*" tells curl not to use its application-level proxy settings for this request, but it does not bypass the operating system’s TUN routes. Turn off the system proxy, enable TUN, and run the command. Then check the destination, matched rule, and policy on the client’s connections page. A successful request alone does not prove that it used a proxy node; the rules may have selected DIRECT.

Step 3: Narrow down the cause based on what you observe

  • Explicit proxy works, but TUN fails: Check permissions, the virtual interface, and routes first. On Windows, use route print; on Linux, use ip route to inspect the routing table.
  • Browser works, but terminal tools fail: Check the terminal’s environment variables and the tool’s own proxy options; do not assume the node is at fault.
  • Domains fail, but a known IP works: Focus on DNS and use an appropriate test service. Replacing an HTTPS domain with an IP directly introduces certificate and SNI differences.
  • TCP works, but voice or games fail: Check UDP capture, the node’s UDP support, and server-side restrictions instead of simply switching rule modes.
  • Problems start after enabling another VPN: Temporarily turn one VPN off and compare the default route, DNS, and egress interface before configuring how the two can coexist.

Change one variable at a time and record five things: entry point, DNS, matched rule, actual policy, and error logs. To roll back, turn off TUN, restore the original configuration, and then check the system proxy address. Before closing the client, remove any proxy setting that still points to 127.0.0.1:7890 so apps do not keep connecting to a port that is no longer listening.

For a first-time setup, start with the Getting Started guide. To review rules and configuration structure, see the full documentation.