What Is Clash TUN Mode? How Virtual Network Adapters Route All Traffic
Learn how TUN mode uses virtual network adapters and routing tables to capture traffic from apps that ignore system proxies, with setup and troubleshooting tips for stack, auto-route, and dns-hijack.
TUN mode: Capturing application traffic at the IP layer
TUN is a virtual network interface. The operating system sends IP packets that match its routing rules to this interface, where the proxy core reads them and uses the destination address, domain, and rules to decide whether to connect directly or use a proxy node. The key difference from a system proxy is where traffic is captured—not how fast the proxy node is.
A system proxy typically tells apps that an HTTP or SOCKS proxy is available at an address such as 127.0.0.1:7890. Browsers may follow this setting, but command-line tools, games, and apps with their own networking stacks may not. TUN relies on system routing to capture traffic from some apps that don't use the system proxy settings.
How a connection travels
- The app looks up a domain and gets either its real IP address or a Fake-IP assigned by the core.
- The app opens a TCP or UDP connection. The operating system checks the routing table and selects a virtual interface.
- The TUN stack processes the packet, and the core restores connection details and matches the applicable rules.
- The core connects directly or through a proxy using the physical network adapter, then returns the response to the app.
“All traffic” here means system-level traffic routing, not a guarantee that every network path is covered. Apps explicitly bound to a physical interface, virtual machine and container networks, excluded subnets, and IPv6 routes that aren't captured may use other paths. LAN broadcasts and Layer 2 discovery protocols also shouldn't be treated as ordinary traffic that TUN can proxy.
Before you start: Check the core, permissions, and config source
The configuration below is for mihomo cores that support these fields. The original Clash core, legacy Premium cores, and mihomo don't have identical TUN capabilities or fields; a client's name alone doesn't identify its core. Check the core name and exact version in the client’s core information, About page, or startup logs, then consult the documentation for that version.
- Windows: Creating a virtual interface and changing routes usually requires administrator privileges. Some clients perform these tasks through an installed service, so the desktop app can run without elevated permissions.
- macOS: TUN usually requires the client's privileged helper or the appropriate authorization. Permission to access the local network does not grant permission to change routes.
- Linux: You need an available
/dev/net/tundevice and the necessary network permissions. Containers also require their device mappings and permissions to be configured separately. - Android: Clients typically create the interface through the system VpnService. Desktop steps for administrator or service mode don't apply; running another VPN at the same time often causes conflicts.
Export a working config first, and check whether subscription updates will overwrite your changes. If the client supports config overrides, merges, or extensions, use that mechanism to save the TUN settings. Editing a temporary file generated from a subscription may stop working after the next update or restart. See the configuration reference for related fields.
Minimal config: Verify traffic capture before adding proxy rules
This complete, minimal config is intended for desktop troubleshooting. It sends every connection directly so you can verify the virtual interface, routes, and DNS; it does not include a working proxy node. In this example, 7890 is the mixed proxy port and 1053 is the local DNS listening port. They serve different purposes.
mixed-port: 7890
allow-lan: false
mode: rule
log-level: info
ipv6: false
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
ipv6: false
enhanced-mode: fake-ip
fake-ip-range: 198.18.0.1/16
nameserver:
- 223.5.5.5
- 1.1.1.1
rules:
- MATCH,DIRECT
The example uses standard DNS upstreams to make troubleshooting easier; it doesn't encrypt DNS traffic. Adjust them to suit your network's reachability and privacy requirements. ipv6: false narrows the scope of initial troubleshooting; it doesn't disable IPv6 in the operating system or guarantee other apps won't use the system's IPv6 path.
stack: A protocol stack option, not a speed setting
| Value | How it works | When to choose it |
|---|---|---|
system | Processes connections using the system network stack. | Useful for compatibility testing; exact behavior depends on the platform. |
gvisor | Uses a user-space network stack. | Try it alongside other options when troubleshooting connection compatibility. |
mixed | Uses system for TCP and gVisor for UDP. | A good starting point for mihomo versions that support this option. |
Don't assume one stack is faster on every device. Results vary with the operating system, core version, and traffic type. Change only stack when testing, then restart the core and open new connections; existing long-lived connections aren't a reliable way to compare settings.
auto-route and auto-detect-interface
auto-route: true tells the core to configure routes that direct traffic to TUN; it doesn't enable proxy rules. auto-detect-interface: true automatically selects an outbound interface so proxy connections use the real network path instead of looping back into TUN.
With multiple network adapters, another VPN, a corporate network, or a virtual switch, auto-detection may not choose the intended outbound interface. Check the routes and interfaces first, then consider setting an outbound interface with a field such as interface-name, if supported by your core version. Don't copy an interface name from another computer; it may change when you switch between Wi-Fi and Ethernet.
DNS capture: How dns-hijack relates to Fake-IP
dns-hijack sends matching DNS traffic entering TUN to the core's DNS module. In this example, any:53 matches UDP port 53, and tcp://any:53 matches TCP port 53. This doesn't capture every type of name resolution or redirect all traffic to local port 1053.
- Traditional DNS: Usually uses UDP port 53; TCP port 53 may be used for large responses or in certain situations.
- DoT: Usually uses TCP port 853, so matching port 53 won't capture it.
- DoH: Usually runs over HTTPS on port 443. A browser's Secure DNS setting may bypass traditional DNS capture, although the connection itself may still enter TUN.
In Fake-IP mode, the core can return a mapped address to the app, such as 198.18.0.2, and use the mapping to recover the domain when the app connects. This helps domain-based rules match, but the returned address isn't the website's real IP. The example's 198.18.0.1/16 is a mapping pool, not a regular public destination to test for reachability.
Some LAN services and apps validate DNS responses themselves. If needed, configure fake-ip-filter for specific domains so they resolve to real addresses. Don't exclude every domain, or you'll change how DNS works across the board. After switching between Fake-IP and real-IP resolution, restart the test app and clear its DNS cache so it doesn't keep using an old mapping.
Setup: Verify each dependency in order
- Check the baseline network first: Turn off TUN and confirm the network works. If you already have a proxy config, use the system proxy to verify that the node and proxy group work before testing TUN. This helps avoid mistaking a node issue for a virtual adapter problem.
- Sort out permissions: Enable the client service or grant system authorization using the method provided by the client. On Linux, first confirm that
/dev/net/tunexists; don't rely on the toggle's appearance alone. - Save and reload the config: Validate the config before starting the core. Check the startup logs for errors creating the virtual interface, insufficient permissions, or invalid fields.
- Temporarily turn off the system proxy: This rules out the browser using an old proxy setting. TUN and the system proxy can coexist, but test them separately at first.
- Open a new connection: Quit and reopen the test app. Check the client’s connection list for the destination domain, destination IP, network type, and matched rule.
- Restore your rules: After verifying the minimal direct-connection config, re-enable your existing proxy groups and rules. Check the outbound path for both direct and proxied connections.
If the client automatically re-enables the system proxy on startup, check its setting again. An app's saved SOCKS settings and the terminal environment variables HTTP_PROXY and ALL_PROXY can also change the route. Turning off the system proxy alone doesn't prove a connection went through TUN.
Check routes and DNS results
These commands only show status; they don't fix problems. Compare interfaces and routes before and after enabling TUN. Routing may use multiple specific routes or policy rules rather than replacing a single default route.
# Windows: run in PowerShell
Get-NetAdapter
Get-NetRoute -AddressFamily IPv4
Resolve-DnsName example.com
# macOS: run in Terminal
ifconfig
netstat -rn -f inet
route -n get 1.1.1.1
# Linux: show main and policy routing tables
ip link show
ip rule show
ip route show table all
ip route get 1.1.1.1
A Fake-IP result from a DNS test only confirms that one lookup used the expected DNS path; it doesn't prove the app's connection was proxied correctly. For a complete check, inspect both the connection record and the outbound path: confirm the new connection reached the core, matched the expected rule, used the intended proxy or direct policy, and successfully reached the destination service.
Troubleshooting: Check the interface, routes, DNS, and outbound path
The toggle is on, but there's no virtual interface
First check whether the service is running, authorization is complete, the startup log shows errors, and the active config contains tun.enable: true. The client UI toggle may be overridden by the config, or the core may have failed to start. Changing DNS is unlikely to help at this point.
All apps lose network access after enabling TUN
Turn off TUN to restore connectivity, then check for other VPNs, the outbound interface selection, and DNS upstream reachability. Repeated connections to the same destination in the logs may indicate a routing loop. Don't change the stack, DNS, MTU, and rules all at once; keep a reproducible config and change one thing at a time.
If domains fail but connections to known IP addresses work, focus on DNS. If DNS returns results but connections time out, check routes, rules, and proxy nodes. Opening an HTTPS site by IP may fail because of certificates or virtual hosting, so that alone isn't proof of a network outage.
Browser works, but games or voice chat don't
First check whether the failed connection reached the core. If it did and uses UDP, check whether the proxy protocol, selected node, and server support UDP forwarding. TUN can capture UDP, but that doesn't mean every proxy outbound supports it. Browsers may fall back to TCP, so working websites don't prove that games will work.
Can't reach LAN devices, printers, or corporate resources
Check whether the destination is a private IP address and whether its subnet overlaps with another VPN or route. IP-CIDR,192.168.0.0/16,DIRECT,no-resolve is an example of a direct-connection rule at the policy layer, but direct connections may still be captured by TUN. To exclude a subnet at the routing layer, check which route exclusion fields your core supports. That's different from adding a DIRECT rule.
Network access doesn't return after turning TUN off
First exit the client normally so the core can clean up the virtual interface and routes. Then check whether the system proxy still points to 127.0.0.1:7890 after its listener has stopped. If needed, reconnect to the network or restart the system. Don't bulk-delete routes unless you understand their purpose, especially on corporate networks.
When to use TUN instead of a system proxy
For browser-only use, a system proxy is usually easier to monitor and troubleshoot. Consider TUN when apps ignore the system proxy, you need to handle more TCP and UDP connections centrally, or you want to apply rules at the system level. TUN expands traffic capture, but also adds responsibility for permissions, routes, and DNS.
- Keep
mode: ruleso local and proxied traffic can be handled separately by your rules. - Use connection logs to confirm traffic capture and matched policies to confirm routing; don't treat an enabled toggle as proof.
- Recheck interfaces, DNS, and routes after upgrading the core, switching networks, or adding a VPN.
- Adjust MTU only when you have evidence of a fragmentation or path MTU issue; a fixed value isn't a universal optimization.
Use this order to check a TUN config: interface exists, routes are active, DNS resolves, rules match, and the outbound path is reachable. Checking each layer in sequence makes problems easier to isolate than repeatedly toggling multiple settings.