Why developers use Clash TUN for command-line traffic

If your browser connects through Clash but git clone, npm install, pip install, or a Docker image pull still hangs, the problem may be that those tools do not use the same proxy settings as your browser. Many command-line programs rely on environment variables, their own configuration files, or the network stack of a background service. A system proxy toggle alone does not guarantee that every process will follow it.

Clash TUN mode offers another approach: it creates a virtual network interface and lets Mihomo route eligible device traffic according to the active profile’s rules. That can cover applications that do not understand HTTP_PROXY or HTTPS_PROXY, making it useful for a developer workstation with a mix of shells, package managers, IDEs, and command-line tools.

TUN is not a magic switch that automatically fixes every development connection. Traffic may still bypass the tunnel because of route exclusions, firewall rules, DNS behavior, a separate network namespace, or an incorrectly selected Clash mode. Docker deserves special attention because containers and the Docker daemon may not share the host’s routing path. This guide gives you a repeatable way to enable TUN, test Git, npm, pip, and Docker independently, and narrow down common DNS and timeout failures.

The examples use a Clash-compatible client backed by Mihomo, such as Clash Verge Rev. Menu labels and permission prompts vary by operating system and client version. Use a profile you trust, follow your organization’s network policies, and treat configuration changes as a diagnostic process: change one variable, test, and keep a record of the result.

TUN mode versus per-application proxy settings

With a conventional application proxy, a program must know the proxy address and protocol. You might export HTTPS_PROXY for one shell, add a proxy option to Git, or edit a package manager’s configuration. This is explicit and can be convenient on a server, in a CI job, or when only one tool should use a proxy. It also creates several places to configure and maintain, and a tool that ignores those settings can still make a direct connection.

TUN works at a different layer. After the client creates its virtual interface and installs the required routes, eligible network connections can be passed to Mihomo for rule matching. A command-line application can therefore be routed without having a proxy feature of its own. The selected Clash mode and rules still matter: a connection classified as DIRECT will not use a proxy node just because TUN is active.

  • Use TUN when: several desktop applications or command-line tools need consistent rule-based routing, including tools that do not honor proxy environment variables.
  • Use environment variables when: you need a narrow, portable setup for a single shell, container, CI runner, or remote host, and the program supports standard proxy variables.
  • Use both deliberately when: a specific process needs explicit proxy configuration while the rest of the workstation uses TUN. Check for loops or conflicting routes rather than assuming the two mechanisms will cooperate automatically.

Before turning TUN on, note the current state of your system proxy, other VPN clients, and firewall software. Two tools trying to own the same routes or network extension can produce intermittent behavior that looks like a bad proxy node. Keep one network-routing mechanism active while you establish a baseline. TUN may require administrator approval or an operating-system network permission; grant only the permission requested by the client you installed and review the prompt rather than bypassing security controls.

Prepare the profile, mode, and DNS path

Start with a known-good profile and a reachable proxy group. In the Clash client, update or select the profile you intend to use, choose a suitable node or group, and confirm that ordinary traffic can pass through it. If the selected group is empty, unavailable, or pinned to a failed node, TUN will faithfully route connections into a broken path.

Next, choose a routing mode that matches your goal. Rule mode applies the profile’s rules; Global mode generally sends matching traffic through the selected proxy group; Direct mode bypasses proxying. Names and behavior can differ by client, so verify the active mode in the UI. For a first test, a temporary Global-mode comparison can help distinguish a routing-rule problem from a tunnel or node problem. Do not leave a broad mode enabled if it conflicts with your network policy or intended split routing.

DNS is part of the path, not a separate detail. A package tool can resolve a hostname through the operating system, a container resolver, or an application-specific DNS library. Mihomo profiles may use fake-IP behavior or other DNS settings that affect how names map to connections. Avoid changing several DNS options at once. First record the failing hostname, the resolver used by the process if known, and what appears in Clash’s Connections or Logs view.

  • Confirm the profile has a working proxy group and the intended mode is active.
  • Enable TUN using the client’s documented control, then approve the required system permission.
  • Check that the TUN status is active and that the client has not reported a route, permission, or DNS initialization error.
  • Keep the system proxy setting consistent with your test. A command using an explicit proxy variable may succeed for reasons unrelated to TUN.
  • Open the connection log before testing so you can observe whether the destination is proxied, direct, rejected, or not visible at all.

When reviewing rules, use actual destinations seen in the client rather than copying a large domain list from an unrelated guide. Git hosts, registries, mirrors, and container registries can use different domains for authentication, metadata, package files, and redirects. A request may begin at one hostname and download content from another. A rule for just the first domain may make a login page load while the actual clone or package download still stalls.

A hands-on test sequence for Git, npm, pip, and Docker

Test one tool at a time, using a harmless request and the same selected Clash mode. The point is not only to see whether a command succeeds; it is to connect that result to an observable connection in Mihomo. If the client shows the destination as DIRECT, investigate mode and rule matching. If it shows the intended proxy group but the request times out, investigate the node, DNS, TLS path, or remote service.

  1. Verify TUN before testing package tools. Confirm that the client reports TUN as running. In the Connections view, make a normal request from a terminal and look for its process or destination. Visibility varies by platform and permissions, so an absent process label does not alone prove that TUN failed.
  2. Test Git with a read-only operation. Run git ls-remote against a repository you are authorized to access, or perform a small clone. For example: git ls-remote https://github.com/git/git.git HEAD. If it fails, compare the hostname and route shown in Clash with the exact error from Git. Authentication errors are different from connection timeouts and should be handled through your normal credential manager.
  3. Test npm against the configured registry. Check the registry with npm config get registry, then try a metadata request such as npm view npm version. A corporate or regional mirror may be intentional; do not replace it automatically. If metadata works but package installation fails, observe whether the tarball download goes to a different host.
  4. Test pip without changing its global configuration. Use a small package query or a controlled installation in a virtual environment, following your project’s dependency policy. For example, python -m pip index versions packaging can help test index access on supported pip versions. An index configured by a workplace or project may differ from the public Python Package Index.
  5. Test Docker separately. Run a small image pull that you are permitted to access, then inspect the Docker daemon’s logs and the Clash connection list. A host-side curl succeeding does not establish that Docker’s daemon or a container follows the same route.

For each test, record the command, timestamp, error text, destination hostname, selected mode, and whether Clash showed a connection. This small incident log prevents guesswork. If an error happens only on one tool, compare that tool’s proxy configuration, certificate store, and resolver with a known-working client. If every tool fails at once, prioritize TUN status, system routes, the active profile, and the proxy node before editing individual package-manager settings.

Environment variables can be useful as a comparison test, but they should not silently invalidate your TUN test. In a shell that supports the syntax below, inspect whether proxy variables are already set:

env | grep -i proxy
git config --show-origin --get-regexp 'http\..*proxy'
npm config get proxy
npm config get https-proxy

Do not paste output containing credentials or proxy authentication tokens into a public ticket. If a variable points to a local Clash HTTP or mixed port, a successful command proves that the explicit proxy path works; it does not by itself prove that TUN works. For a clean comparison, temporarily unset only the relevant variables in that test shell, run the same request, then restore your normal environment. Avoid deleting organization-managed settings or changing a shared machine without permission.

Docker’s architecture often explains a stubborn exception. The Docker CLI sends requests to the Docker daemon, and the daemon may run as a privileged service with its own network context. A container also has a separate network namespace. Depending on the platform and Docker configuration, host TUN routing may cover some traffic but not every daemon or container path. If image pulls fail while host tools work, check whether the daemon itself has documented proxy settings, whether Docker Desktop uses its own networking layer, and whether the container’s DNS settings differ from the host. Apply the narrowest supported fix; do not assume that adding proxy variables inside a build stage configures the daemon that downloads the base image.

Troubleshoot DNS failures, timeouts, and unexpected DIRECT routes

Use the symptom and the connection log together. “Could not resolve host” suggests a name-resolution problem, but it can also come from a resolver that is unreachable on the current network. A TCP timeout after a hostname resolves points more toward route selection, a blocked path, an unavailable node, or a remote endpoint. TLS certificate errors may instead indicate a trust-store mismatch, inspection by a managed network, or a system clock problem. Changing DNS cannot repair invalid credentials or a certificate that the process does not trust.

  • Connections show DIRECT: confirm the active mode, inspect the matched rule, and check for a more specific rule earlier in the profile. If Global mode succeeds but Rule mode fails, the evidence points toward rule coverage or ordering.
  • No relevant connection appears: verify that TUN remains active and that the command is not running inside a VM, container, remote shell, or network namespace outside the host’s route. Check client permissions and operating-system route status using the appropriate platform tools.
  • DNS failures affect one tool: compare the tool’s configured registry or index and resolver path with another command. Check whether the destination is a private hostname that should remain on the corporate or local DNS path.
  • Only large downloads time out: look for redirects to a storage or CDN hostname, test a different healthy node, and distinguish an idle timeout from a DNS failure. Avoid repeatedly retrying large downloads against a clearly unhealthy route.
  • Git works but package installs fail: inspect the actual registry or artifact host reached after metadata lookup. Registry mirrors and package file hosts may be separate destinations governed by different rules.

For DNS diagnosis, begin with a hostname from the failing command and compare the operating system’s resolution result with the connection details Clash reports. A fake-IP address in a log is not necessarily evidence of a broken lookup; it may be expected behavior for the selected DNS mode. Conversely, a command that resolves a name on the host does not guarantee that a Docker container uses the same resolver. Keep the distinction between “name resolved,” “connection routed,” and “application accepted the TLS session” clear.

When you need to make a change, change one thing and repeat the same test. First verify that the node is healthy; then check mode and rule matching; next investigate DNS and the process’s network context. Restart a stuck process after changing routes if it holds a long-lived connection or cached DNS result. Do not rotate nodes, rewrite rules, change DNS mode, and alter firewall settings simultaneously: even if the symptom disappears, you will not know which change fixed it, and you may create a harder-to-debug failure later.

On managed networks, shared development hosts, or company laptops, check local policy before routing traffic through a proxy or editing system-wide DNS and routes. Some organizations require approved egress proxies or private registry access. A working TUN setup should respect those boundaries, keep credentials out of logs, and preserve direct access to internal services that must not leave the organization.

Frequently asked questions

Does TUN replace HTTPS_PROXY for every developer tool?

No. TUN can route eligible network traffic without application-level proxy support, but the result depends on operating-system routes, client permissions, rules, and the process’s network context. Explicit proxy variables remain useful for remote machines, CI jobs, containers, or narrowly scoped commands. Test each environment rather than assuming the workstation’s TUN configuration follows a process elsewhere.

Why does Docker fail when Git and npm work?

The Docker daemon, Docker Desktop, and containers may use network contexts that differ from the host shell. Image pulls are often performed by the daemon, while commands inside a running container use the container’s own networking and DNS configuration. Check daemon logs and the relevant Docker proxy documentation for your platform, then test the daemon path separately from a host command.

Should I switch DNS mode whenever a package install times out?

Not as a first step. A timeout can be caused by rule matching, a failed node, an unreachable endpoint, or a package host redirect—not just DNS. Identify the hostname and the point of failure from the command output and Clash logs, then make one controlled DNS change only if the evidence indicates a resolution problem.

Is Global mode the best permanent setup for development?

It is a useful diagnostic comparison, but it may route more traffic than you intend. If Global mode fixes a failure, use the result to identify a missing or misordered rule, then return to a policy that fits your needs. Keep internal services and destinations that must stay direct on the appropriate path.

Some per-tool proxy guides leave you maintaining separate Git, npm, pip, and Docker settings, while a generic VPN toggle may offer little visibility into which destination failed or why. Clash TUN gives you one rule-based routing point for eligible workstation traffic, and its connection logs help distinguish a DIRECT match from DNS, node, or application errors. If that observable workflow fits your development setup better, you can compare the available Clash clients and choose one for your platform.

Download Clash