System Proxy vs TUN Mode in Clash Verge Rev: Configuration Differences Explained

System Proxy modifies operating-system proxy settings to route traffic from proxy-aware applications only, while TUN Mode creates a virtual network interface that captures all IP traffic system-wide before it reaches the OS network stack.

Clash Verge Rev provides two fundamentally different approaches for steering network traffic through the Clash core. Understanding the difference between system proxy and TUN mode configuration in Clash Verge Rev is essential for optimizing your setup based on application compatibility and routing requirements. This analysis examines the implementation details in the clash-verge-rev/clash-verge-rev repository to clarify how each mode operates at the code level.

System Proxy Configuration

System Proxy operates by modifying the operating system's built-in proxy settings, affecting only applications that respect these configurations.

Configuration Location and UI Components

The system proxy settings reside in the Verge configuration file (verge.yml) under keys such as enable_system_proxy, proxy_auto_config, and system_proxy_bypass. The UI component responsible for manipulating these settings is SysproxyViewer, implemented in src/components/setting/mods/sysproxy-viewer.tsx.

When you toggle System Proxy via the UI, the component invokes patchVergeConfig({ enable_system_proxy: true/false }). This function, defined in src/services/cmds.ts, triggers OS-specific commands through the system-proxy helper:

  • Windows: netsh winhttp set proxy ...
  • Linux: gsettings
  • macOS: networksetup

Scope and Privileges

System Proxy requires no special administrative privileges on most platforms because standard users can modify OS proxy settings. However, it only affects proxy-aware applications such as web browsers and CLI tools that check the system proxy configuration. Native applications, games, and services that communicate directly via IP bypass these settings entirely.

TUN Mode Configuration

TUN Mode operates at the network interface level, creating a virtual NIC that intercepts packets before they reach the OS routing table.

Configuration Structure and UI

TUN Mode configuration lives in the Clash core configuration (config.yaml) under the tun: section. The TunViewer component in src/components/setting/mods/tun-viewer.tsx provides the interface for configuring parameters including stack, device, auto-route, and dns-hijack.

When saving TUN settings, the UI constructs a TUN object and transmits it via patchClash({ tun }), which sends the configuration to the running Clash core through its REST API (/configs endpoint).

Virtual Interface Implementation

Upon receiving the configuration, Clash creates a TUN/TAP virtual network interface—named utun1024 on macOS or Mihomo on Windows. This interface captures all IP traffic regardless of application proxy awareness. Because creating virtual network interfaces requires kernel-level access, TUN Mode demands Service Mode or Admin Mode privileges. The UI disables the toggle when these prerequisites are unavailable, as indicated by the isTunModeAvailable state in src/components/home/proxy-tun-card.tsx.

Key Differences Comparison

Aspect System Proxy TUN Mode
Configuration File verge.yml (Verge config) config.yaml (Clash core)
UI Component SysproxyViewer (sysproxy-viewer.tsx) TunViewer (tun-viewer.tsx)
Traffic Scope Proxy-aware applications only All applications and services
Implementation OS proxy table modification Virtual NIC packet interception
Privileges Standard user Administrator/Service Mode
Use Case Web browsing, development tools Gaming, system-wide filtering, DNS hijacking

Practical Implementation Examples

Enabling System Proxy

The following TypeScript excerpt from src/components/setting/mods/sysproxy-viewer.tsx demonstrates the UI invocation:

const enableSystemProxy = async (value: boolean) => {
  await patchVergeConfig({ enable_system_proxy: value });
  // UI refreshes automatically via SWR mutate
};

The backend abstraction in src/services/cmds.ts handles the platform-specific implementation:

export const patchVergeConfig = async (payload: Partial<IVergeConfig>) => {
  return invoke<T>(`patchVergeConfig`, payload);
};

Configuring TUN Mode

From src/components/setting/mods/tun-viewer.tsx, the TUN configuration object is constructed as follows:

const onSave = async () => {
  const tun: IConfigData["tun"] = {
    stack: values.stack,
    device: values.device || (OS === "macos" ? "utun1024" : "Mihomo"),
    "auto-route": values.autoRoute,
    "route-exclude-address": splitRouteExcludeAddress(values.routeExcludeAddress),
    ...(OS === "linux" && { "auto-redirect": values.autoRedirect }),
    "auto-detect-interface": values.autoDetectInterface,
    "dns-hijack": values.dnsHijack[0] === "" ? [] : values.dnsHijack,
    "strict-route": values.strictRoute,
    mtu: values.mtu ?? 1500,
  };
  await patchClash({ tun });
};

This generates a YAML configuration block in the Clash core:

tun:
  enable: true
  stack: gvisor
  device: utun1024
  auto-route: true
  dns-hijack:
    - any:53

Mode Selection Interface

The proxy-tun-card.tsx component renders the selection interface, showing mutual exclusivity between modes:

<TabButton
  isActive={activeTab === "system"}
  onClick={() => handleTabChange("system")}
  label={t("home.components.proxyTun.title.system")}
/>
<TabButton
  isActive={activeTab === "tun"}
  onClick={() => handleTabChange("tun")}
  label={t("home.components.proxyTun.title.tun")}
  hasIndicator={!isTunModeAvailable}
/>

Summary

  • System Proxy modifies OS-level proxy settings via patchVergeConfig, requiring no special privileges but only affecting proxy-aware applications.
  • TUN Mode creates a virtual network interface via patchClash, requiring Administrator or Service Mode to intercept all system traffic.
  • Configuration for System Proxy lives in verge.yml and is managed by SysproxyViewer, while TUN settings reside in the Clash config.yaml and are edited through TunViewer.
  • TUN Mode automatically disables System Proxy in the UI when activated, as the virtual interface supersedes OS proxy settings for system-wide routing.

Frequently Asked Questions

Can I use System Proxy and TUN Mode simultaneously?

No, Clash Verge Rev treats these modes as mutually exclusive. When TUN Mode is enabled, the System Proxy toggle is automatically hidden or disabled in the UI because the virtual network interface captures all traffic before it reaches the OS proxy chain, making system proxy settings redundant.

Why does TUN Mode require Service Mode or Administrator privileges?

TUN Mode creates a virtual network interface (TUN/TAP device) at the kernel level to intercept all IP packets. According to the implementation in src/components/setting/mods/tun-viewer.tsx, creating these network interfaces requires elevated privileges on Windows, macOS, and Linux. The UI checks isTunModeAvailable to disable the toggle when the service lacks necessary permissions.

Which applications require TUN Mode instead of System Proxy?

Applications that bypass system proxy settings—such as games, native desktop applications, and background services that communicate directly via raw sockets—require TUN Mode. The virtual interface in TUN Mode (utun1024 on macOS or Mihomo on Windows) captures traffic before the application layer, ensuring all packets route through the Clash core regardless of the application's proxy awareness.

How do I configure DNS hijacking in TUN Mode?

DNS hijacking is configured through the TunViewer interface in src/components/setting/mods/tun-viewer.tsx via the dns-hijack parameter. When enabled, Clash intercepts DNS queries on port 53 and routes them through the proxy chain, preventing DNS leaks. This setting is part of the TUN object sent to patchClash({ tun }) and appears in the generated configuration as dns-hijack: [any:53].

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →