Getting Started 9-minute read

Clash Mode Comparison

Git clones stall, npm installs time out, or Docker pulls fail? Set up Clash TUN mode to route terminal traffic without configuring every CLI tool separately.…

Why command-line tools may miss your proxy

A browser working through Clash does not prove that Git, npm, pip, or Docker is using the same route. A desktop client can configure the operating system’s HTTP proxy, but many command-line programs do not automatically follow that setting. Some use their own proxy options; others connect directly unless their traffic is captured by TUN or another network-level mechanism.

It helps to separate three layers. The client’s system proxy setting asks proxy-aware applications to use a local HTTP or SOCKS listener. The TUN interface captures eligible IP traffic from applications that may not understand proxy settings. The core’s rules and policies decide what happens after a connection reaches Clash or mihomo. TUN is a traffic-capture method, not a proxy server or a routing mode; the active rules and selected policy still matter.

This distinction is especially important for development tools. Git may use its own http.proxy setting; npm and pip can have application-level proxy configuration; Docker image pulls are usually performed by a daemon or a virtualized backend rather than by the terminal process that ran docker pull. Each component may therefore take a different path.

Which layer commonly handles each development connection
ConnectionLikely traffic ownerFirst place to check
Git clone or fetch over HTTPSGit processGit proxy settings, system proxy, and TUN capture
npm install or package downloadNode.js processnpm proxy config, environment variables, and registry reachability
pip installPython processpip options, environment variables, and DNS or TLS errors
Docker image pullDocker daemon or Desktop backendDocker engine proxy settings and host-to-VM routing

Prepare Clash TUN mode safely

Before changing developer-tool settings, record the client and core versions, current operating mode, and the result of a known failing command. In Clash Verge Rev, look in Settings for the TUN or service controls; labels can differ between releases. Confirm that the client is using a compatible mihomo core if the configuration depends on mihomo-specific options. On macOS, approve the requested network extension or VPN configuration through the system prompt. On Windows, grant administrator permission if the client needs it to create or manage the virtual adapter.

Enable TUN in the client, then confirm its status indicator reports that it is active. Keep the core in Rule mode for ordinary use unless you are deliberately testing another mode. A typical mihomo configuration may include the following settings, but client-managed configurations do not always expose or accept direct edits to every field:

tun:
  enable: true
  stack: mixed
  auto-route: true
  strict-route: true

Do not paste this block over a client-generated configuration without checking its schema and version. Some clients manage TUN settings in their UI and regenerate the configuration on every launch. If your client provides a TUN toggle, use that control first. The example also does not define DNS behavior, exclusions, or a complete set of routing rules; those depend on the network and applications you need to support.

Check routing before testing tools

Choose a proxy policy that can reach the destination and confirm that your rules send the relevant traffic to it. A rule that sends a domain to DIRECT will not use a proxy node simply because TUN is enabled. Review the client’s connection list or logs while reproducing one request: a visible connection can show which rule and policy handled it. Redact hostnames, subscription data, and credentials before sharing logs.

If you already set a proxy environment variable, remember that it may direct the application to a local listener independently of TUN. That can be useful, but it also makes a test less conclusive: a request may succeed through the HTTP proxy even when TUN capture is broken. For a clean baseline, note the current environment, test with one method at a time, and restore any values you temporarily remove.

Verify terminal connectivity one layer at a time

Start with a simple HTTPS request to a destination relevant to your work, then test each tool. On macOS, use Terminal. On Windows, PowerShell is suitable; the examples below use commands available in common modern installations. A failure message is evidence, not a diagnosis: DNS resolution errors, connection timeouts, TLS verification failures, and HTTP authorization errors point to different layers.

# Check that the destination resolves and HTTPS responds
curl -I https://github.com

# Check the package registry endpoint
curl -I https://registry.npmjs.org

# Inspect proxy-related environment variables
# macOS / Linux shell
env | grep -i proxy

# Windows PowerShell
Get-ChildItem Env:*proxy*

If TUN is meant to capture the request, first make sure the command is not explicitly bypassing it with an unintended NO_PROXY entry or a direct-only application setting. Also check whether the domain resolves to an address that your rules route differently. A successful curl test confirms only that this particular process reached that particular URL; it does not establish that Docker’s daemon or another tool uses the same path.

Test Git without exposing credentials

Try a read-only request before changing global configuration:

git ls-remote https://github.com/example/project.git

Replace the example path with a repository you are authorized to access. If this succeeds with TUN active and no explicit Git proxy, Git traffic is reaching the remote through the current system route. If it fails, inspect Git’s configured proxy values and the error. A timeout suggests a routing or reachability problem; an authentication prompt or HTTP 401/403 response usually means the server was reached and the issue is authorization rather than TUN.

git config --show-origin --get-regexp 'http\..*proxy|https\..*proxy'

To remove a proxy only when you have confirmed it is stale, remove the specific setting at the scope where it was created. For example, git config --global --unset http.proxy changes the current user’s global setting; it does not erase a system-level or repository-local value. Avoid putting usernames, passwords, or access tokens in a proxy URL that could be saved in Git configuration or shell history.

Test npm and pip separately

For npm, check both the registry in use and any saved proxy configuration:

npm config get registry
npm config get proxy
npm config get https-proxy
npm ping

The standard public registry URL is https://registry.npmjs.org/, but a company or project may intentionally use a private registry. Do not replace that URL blindly. If requests fail, compare npm ping with a direct curl -I request to the registry. A certificate error is not a reason to disable TLS verification; check the system clock, trust store, enterprise TLS inspection, and the precise certificate error instead.

For pip, use a harmless version check and inspect the output rather than installing an arbitrary package just to test connectivity:

python -m pip --version
python -m pip index versions pip

The second command contacts the configured package index and may not be available in older pip versions. If your environment uses a private index or mirror, preserve it. Environment variables such as HTTP_PROXY, HTTPS_PROXY, and NO_PROXY can affect Python tooling, but support and precedence vary between programs. A clean TUN test should avoid adding a new per-tool proxy value until you know whether it is needed.

Configure proxy-aware tools only when needed

TUN is useful when an application ignores the operating system’s proxy setting, but it is not the only option. An explicit application proxy can be more predictable for a specific tool, especially on networks where virtual routing is restricted. First identify the local HTTP or SOCKS port in the Clash client. Common defaults such as 7890 are not guaranteed: the port can be changed, and HTTP and SOCKS listeners may use different ports.

For a temporary test in a macOS shell, set the proxy variables for the current terminal session, using the actual listener and port shown in your client:

export HTTP_PROXY="http://127.0.0.1:PORT"
export HTTPS_PROXY="http://127.0.0.1:PORT"
export NO_PROXY="localhost,127.0.0.1,::1"

In PowerShell, the corresponding temporary values can be set for the current session:

$env:HTTP_PROXY = "http://127.0.0.1:PORT"
$env:HTTPS_PROXY = "http://127.0.0.1:PORT"
$env:NO_PROXY = "localhost,127.0.0.1,::1"

Replace PORT with the actual HTTP proxy port. These examples assume an HTTP proxy listener; a SOCKS listener requires a compatible URL scheme and support in the application. Some tools recognize lowercase variable names as well as uppercase ones, while others apply their own configuration precedence. Test a single command, then remove temporary values by closing the terminal or clearing the variables. Do not save proxy settings globally until you have confirmed they are required.

For a persistent Git setting, use a local listener only if it is stable and appropriate for your machine. Check the exact configuration scope before adding one, and remember that a repository-local setting follows that repository. If you switch networks, clients, or proxy ports, stale values can make Git fail even when TUN works. npm and pip likewise have their own configuration stores; use their documented unset commands to undo a setting rather than editing unrelated configuration files.

Docker image pulls need a separate check

docker pull is not always a connection made by the terminal process. On Linux, the Docker Engine daemon generally performs the registry request. On macOS and Windows, Docker Desktop commonly runs the engine in a managed virtual machine or backend. The CLI sends a request to that engine, which then fetches the image. As a result, a successful Git or npm test on the host does not guarantee that Docker can reach Docker Hub or a private registry.

First run a small pull that you are permitted to use, and capture the complete error without publishing credentials:

docker pull hello-world

If the error says the daemon cannot connect, times out, or cannot resolve a registry host, check the Docker engine’s network path. In Docker Desktop, inspect its proxy or network settings for your installed version and restart the engine if a change requires it. On Linux, review the daemon’s proxy configuration and service environment; changing the shell’s HTTP_PROXY alone may affect the CLI but not the daemon. Do not copy a daemon configuration snippet from another system without checking the installed Docker version and service manager.

When the host’s local proxy is bound only to 127.0.0.1, a Docker Desktop virtual machine may not be able to reach that loopback address as though it were the host. The VM’s loopback is its own interface. Use Docker Desktop’s supported proxy configuration or an address reachable from the engine, and avoid exposing a proxy listener to an untrusted network merely to make the VM connect.

Also separate registry access from image-building traffic. Pulling a base image happens before a container starts; requests made by a running container use the container’s network and DNS setup. A successful pull therefore does not prove that npm install inside a build container will work. For builds, check the relevant build-time proxy arguments or package-manager settings and avoid baking credentials into the final image or image history.

Docker symptoms and the layer to investigate
SymptomLikely layerUseful check
Host curl works, but image pull times outEngine or Desktop VM routeDocker Desktop proxy settings or Linux daemon proxy
Image pulls, but package install in a build failsBuild container DNS or proxy configurationInspect build-time network settings and package registry access
Registry responds with unauthorizedAuthentication or image permissionsCheck registry login and repository access, not TUN first
Only one private registry failsRegistry-specific DNS, certificate, or allowlistCheck that registry’s hostname, trust chain, and organization policy

Troubleshoot by symptom on macOS and Windows

Make one change at a time and repeat the same command. If you change the operating mode, TUN state, proxy environment, and DNS settings together, you will not know which change fixed or caused the result. Check the Clash connection log at the moment the command runs, then compare the result with TUN disabled only if that is safe for your network and policy.

  • TUN will not start: On macOS, check whether the requested VPN or network extension was approved in system settings and whether another VPN client is competing for the same route. On Windows, check administrator permission, the client’s service status, and whether another virtual adapter or VPN has changed routes. Restart the client only after saving useful logs.
  • Browser works, but terminal requests time out: Confirm TUN is active and that the core sees the connection. If no connection appears, the process may be bypassing capture, using another network namespace, or connecting through a path not handled by the client. Check environment variables and tool-specific proxy settings before editing rules.
  • DNS lookup fails: Record the exact hostname and test whether the failure affects only one registry or all domains. Check the client’s DNS mode, system resolver, and whether the relevant DNS request is routed as expected. Do not replace DNS settings with a random public resolver without considering local policy, split DNS, or private registry names.
  • Connection succeeds but TLS verification fails: Note the certificate error and destination hostname. Check device time, certificate chain, enterprise inspection, and the registry’s certificate. Do not set a global “skip certificate verification” option as a workaround.
  • Git works but Docker does not: Treat this as an engine-path problem first. Check the daemon or Docker Desktop proxy configuration and the host address visible to its VM. Do not assume that changing Git’s proxy setting will configure the Docker engine.
  • Only private network services break: Review local-network and private-domain rules, route exclusions, and NO_PROXY. TUN may capture traffic that previously used a direct route. Confirm that internal names and subnets still go to the intended direct or corporate path.

When escalating an issue, include the operating system version, client and core versions, whether TUN reports active, the command and timestamp, and the exact sanitized error. Omit subscription URLs, node credentials, access tokens, private repository names, and sensitive IP addresses. A compact, reproducible test is more useful than a screenshot of a full configuration containing secrets.

FAQ

Does TUN replace the system proxy?

No. System proxy settings are used by applications that know how to follow them; TUN captures eligible network traffic at a lower level. They can be used separately or together, depending on the client and application. For troubleshooting, test one route at a time so you can tell whether a tool used an explicit proxy or was captured by TUN.

Should I set proxy variables for every development tool?

Not necessarily. If TUN reliably captures the tool and the core routes it correctly, additional proxy settings may be redundant and can create conflicts. Use per-tool settings when TUN is unavailable, the application is excluded from capture, or a specific network requires explicit proxy configuration. Keep any such settings reversible and avoid embedding credentials.

Why can Docker fail when Git works?

Git commonly runs as a host process, while Docker image downloads are handled by the engine or a Docker Desktop backend. Those components can have different proxy settings, DNS, and network routes. Check the engine’s supported proxy configuration and verify the route from the component that actually performs the pull.

Can I disable TLS verification to get installs working?

Do not use that as a general fix. Disabling verification can expose downloads to interception and conceal a broken trust chain. Identify whether the failure is caused by system time, a missing trusted certificate, enterprise inspection, or a destination certificate problem, and correct the relevant trust configuration instead.

Download ClashChoose a client for your platform