TUN vs. System Proxy: Where Traffic Is Captured
Your browser works, but a terminal, game, or desktop app cannot connect. A common cause is that the app does not use the system proxy. System proxy settings tell compatible apps to send requests to a specified HTTP or SOCKS endpoint. If an app makes connections directly, ignores proxy settings, or uses UDP traffic that the proxy does not cover, enabling the system proxy alone may not be enough.
TUN creates a layer 3 virtual network interface and uses routing rules to send matching IP packets to the core. mihomo then checks the destination address, domain information, and rules to decide whether to connect directly or use a proxy. Apps generally do not need to be configured with a proxy address, but the core must have permission to create the interface and change routes.
| Comparison | System Proxy | TUN Mode |
|---|---|---|
| Traffic capture point | Apps connect to a listening port using a proxy protocol | System routes send IP packets to a virtual interface |
| App compatibility | Apps must support proxy settings or be configured manually | Apps usually do not need to recognize proxy settings |
| Permissions | Usually does not require permission to create a network interface | Desktop systems typically require administrator or root access, or an authorized service |
| UDP | Depends on the app and proxy endpoint | Can capture traffic, but the proxy node and protocol must also support it |
| Coverage limits | Connections that do not use the proxy may bypass it | Affected by routes, exclusions, IPv6, and other VPNs |
Before You Enable TUN: Check Your Core, Nodes, and Recovery Plan
“Clash client” describes the app interface; it does not mean every client uses the same core. The YAML in this guide is for mihomo and should not be treated as a universal configuration for every original Clash or older Premium core. Check the actual core in the client’s About or Core Info screen. If you run it separately, check the version output:
mihomo -v
mihomo -t -f config.yaml
The second command checks whether the current core can parse the configuration. It does not confirm that nodes work or routes are correct. If the command cannot find the program, use the actual executable path. In Windows PowerShell, a program in the current directory is usually written as .\mihomo.exe.
- Keep a working copy of your current configuration and override files. Subscription updates may overwrite changes made directly to subscription files, so use the client’s merge or override feature whenever possible.
- First, confirm that your node works in system proxy mode. Test at least one website. If you need games, voice chat, or QUIC, also confirm that the node supports UDP.
- Pause other VPNs, network accelerators, and older proxy cores. For the first test, avoid letting two tools modify the default route at the same time.
- Know how to turn TUN off. If you manage a server remotely, make sure you have console access or another recovery path so a route change does not cut off your only SSH session.
mihomo TUN: Basic Configuration and Field Reference
Add this top-level snippet to an existing working configuration. It is not a complete subscription with nodes and proxy groups. If you already have a tun or dns section, merge the fields instead of adding a duplicate top-level key. For the first test, handle IPv4 only; check IPv6 separately once the connection works.
mode: rule
log-level: info
ipv6: false
tun:
enable: true
stack: mixed
auto-route: true
auto-detect-interface: true
dns-hijack:
- 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
The two DNS addresses here only demonstrate how to specify regular DNS upstreams; choose addresses reachable from your network. Regular DNS queries are not encrypted. If you already have a working DNS split-routing setup and domain resolution for your nodes, keep it rather than replacing it wholesale with this starter example.
| Field | Purpose and what to check |
|---|---|
enable | Requests that TUN start; success still depends on permissions, the interface, and the logs. |
auto-route | Automatically sets routes to send traffic into TUN; this does not remove every exclusion route. |
auto-detect-interface | Detects the active outbound network interface. Check the result if you use multiple network adapters or another VPN. |
dns-hijack | The example captures UDP DNS traffic to destination port 53 entering TUN; it does not capture all encrypted DNS. |
listen | Local DNS listening address. 1053 is an example port, not a port to enter as your system DNS server. |
fake-ip-range | Allocates addresses for domain mapping. Apps that receive these addresses still need to route traffic through the core. |
The 198.18.0.1/16 address range is reserved for benchmarking. It is not the real IP of a remote website or a regular public node address. If an app caches a Fake-IP and keeps using it after the core stops, access may fail temporarily. Close the affected apps and clear the DNS cache before testing again.
Choosing a Stack: system, gvisor, or mixed
system: Primarily uses the system network stack to handle connections. A good starting point is the value recommended by your client, but results depend on the operating system and network environment.gvisor: Uses a userspace network stack. Try it as an alternative when a specific app has compatibility issues, but do not assume it will be faster or more stable.mixed: Uses the system stack for TCP and the gVisor stack for UDP. This is a hybrid handling mode, not two proxy configurations running at once.
Stack support and limitations vary by platform and core version. After making a change, validate the configuration and check the startup logs. Do not change the stack, DNS upstreams, and node all at once; if connectivity returns, it will be difficult to tell which change made the difference.
Windows: Give the Core Permission to Create a Network Adapter
- Exit other proxy clients and confirm that the current node works with the regular system proxy.
- If the client offers a service mode, install and start the service through its interface. If it does not, and you trust the program’s source, try launching the client as an administrator for the initial test.
- Enable virtual network adapter capture in the client’s TUN settings, then check the logs for successful interface creation and route setup—or a clear error. Menu names vary across clients; the toggle’s color alone does not confirm that TUN is working.
- Press Win + R, run
ncpa.cpl, and check your network adapters. The interface name depends on the client or configuration and may not include “Clash.”
For testing, turn off the client’s system proxy and leave only TUN enabled. This prevents the browser from continuing to use the system proxy and masking a TUN problem. In Windows 11, check the manual proxy setting under Settings → Network & internet → Proxy. On work-managed devices, do not change organizational policies without authorization.
route print
ipconfig /all
curl.exe --noproxy "*" -I https://example.com
Use route print to inspect routes, but do not expect a traditional default route pointing to TUN. An implementation may capture traffic using more-specific subnets instead. Also check the client’s connection list to confirm that the request entered the core and matched the expected policy. An HTTP response only proves that the destination was reachable; it does not prove the request used a proxy node.
macOS and Linux: Check Permissions, Routes, and DNS
Enable TUN on macOS
- Use a client that supports mihomo TUN and follow its prompts to install or authorize the helper service. A regular user process usually cannot perform every required network configuration task directly.
- After enabling TUN, check the logs, then run
ifconfigandnetstat -rnin Terminal. Your system may already have severalutuninterfaces, so seeing one does not prove it belongs to the current client. - Go to System Settings → Network → your current network service → Details → Proxies and check for an old manual proxy. The exact labels may vary by system version.
- Turn off the system proxy, make a new connection from an app without an explicitly configured proxy, and cross-check it in the core’s connection list.
If websites work but devices on your local network do not, first check the rules and routes matching local network traffic. Then decide whether to adjust excluded subnets. Do not mistake a failure to reach the entire LAN for a DNS problem.
Enable TUN on Linux
Linux typically requires root or equivalent network administration privileges, and the system must provide a TUN device. First check whether /dev/net/tun exists. Containers and minimal systems may also restrict device access, so running as root does not always guarantee that an interface can be created.
ls -l /dev/net/tun
mihomo -t -f config.yaml
sudo mihomo -f config.yaml
# Check in another terminal
ip link
ip rule
ip route show table all
resolvectl status
Running the core in the foreground makes it easier to see where the first failure occurs. For long-term use, configure a managed service; do not grant permissions indiscriminately to every program in a directory just to troubleshoot. resolvectl applies to systems using systemd-resolved. On other distributions, check how DNS is actually managed.
Android and iOS: Use the System VPN Permission
Android clients typically capture traffic through the system VPN interface. Approve the VPN permission on first connect, then check the client’s app exclusions or per-app proxy settings. An excluded app will not enter the rules flow just because TUN is enabled. You can view the active connection under Android Settings → Network & internet → VPN; some manufacturers put it under Connection & sharing.
Android usually allows only one active VPN service per user or profile. Local firewalls, ad blockers, and other VPNs may compete for that connection. If Always-on VPN or Block connections without VPN is enabled, understand what happens when you close the client. Android Private DNS uses an encrypted channel, so do not assume it is covered by a port 53 hijack rule.
On iOS, use a client that supports the required configuration and approve its system VPN connection. Check its status under Settings → General → VPN & Device Management. An iOS client may not use mihomo or support the YAML fields above. Follow the app’s configuration format; desktop settings are not a universal import format.
DNS, IPv6, and UDP: Three Checks That Are Easy to Miss
Port 53 Hijacking Does Not Cover DoH or DoT
The example’s any:53 handles regular UDP DNS. DNS over TLS typically uses TCP port 853, while DNS over HTTPS usually uses HTTPS on port 443. This configuration alone does not automatically route either through the core’s DNS resolver. For troubleshooting, temporarily turn off Secure DNS in your browser for comparison, then decide on your final DNS setup.
Test domain resolution and whether connections enter the core separately. For example, nslookup example.com can show the lookup result, but it cannot prove that a browser uses the same resolution path. Whether a domain rule matches also depends on whether the core can identify the domain for that connection.
Disabling AAAA Responses Does Not Disable System IPv6
The IPv6 setting in this example simplifies initial troubleshooting; it does not guarantee system-wide protection against bypasses. Apps may still use cached IPv6 addresses, IP literals, or other resolvers. If you need IPv6, check the core’s IPv6 settings, TUN routes, DNS responses, and node support together. If you do not need it, check for IPv6 paths that are still not covered.
Successful UDP Capture Still Requires a Working UDP Outbound
If voice chat or a game fails, first check whether its UDP sessions appear in the connection list, then confirm that the selected node supports UDP. Browser QUIC also uses UDP; a website loading over TCP fallback does not mean UDP is working. Do not rely on a single web speed test instead of testing the game or voice app itself.
Common Issues: Troubleshoot Permissions, Routes, DNS, and Outbound in Order
| Symptom | Check first | Next step |
|---|---|---|
| Turns off immediately after enabling | Configuration parse error, service not running, or insufficient permissions | Validate the configuration and check the first interface creation error. |
| All network access stops after enabling | Wrong outbound interface, conflict with another VPN, or unreachable node | Turn off TUN to restore connectivity, then leave only one traffic-capture tool enabled. |
| IP addresses work, but domain names fail | DNS upstream unreachable, port conflict, or DNS traffic not being captured | Check the listener on port 1053 and the DNS logs; do not replace all your rules as a first step. |
| Websites work, but games fail | UDP outbound, rule policy, or app exclusions | Check the UDP sessions and the node each one actually selected. |
| Fails after switching Wi-Fi networks | Outbound interface and routes did not update with the network change | Restart the TUN session and check which physical network adapter it detects. |
| Still cannot connect after turning TUN off | Leftover system proxy settings, routes, or Fake-IP cache | Exit the client first, check proxy and routing settings, then clear the cache. |
Adjust MTU only when there is a specific reason to suspect it. A typical symptom is that small requests work but large responses or certain websites stall, though node or link issues can cause the same behavior. Record the original value and test mtu: 1400 for comparison. This is only a troubleshooting starting point, not an optimal value for every broadband, mobile, or VPN setup.
Once you confirm a DNS cache issue, run ipconfig /flushdns on Windows. On Linux systems using systemd-resolved, run sudo resolvectl flush-caches. Clearing the cache will not fix incorrect routes or a failed node. When troubleshooting is done, return temporary debug logging to info. Before sharing logs, remove subscription URLs, tokens, and other sensitive information.
How to Confirm It Works: Trace a Single Connection
- Turn off the system proxy and any explicit in-app proxy, then start a brand-new connection.
- Find the connection in the core and check its destination, TCP or UDP type, matched rule, and outbound policy.
- Test one destination that should connect directly and another that should use a proxy; do not test just one website.
- Check local network access, what happens when you switch networks, and whether connectivity recovers after TUN is turned off.
Passing all four checks confirms that traffic capture, rules, and outbound connectivity are basically working. Add IPv6, app exclusions, or more specific routing settings afterward, changing one thing at a time and keeping a record of how to roll back. For more on these fields, see TUN configuration in the Configuration Reference and DNS configuration.