Developer tools often expose a network problem that ordinary browsing does not. A browser may open GitHub normally while git clone stalls, an SSH push times out, or Homebrew fails while downloading a bottle. The reason is that terminal programs do not always use the system proxy automatically. They may resolve DNS differently, ignore the desktop proxy setting, or connect through a protocol that requires its own configuration.

Clash can provide a reliable solution, but the setup has several layers: the Clash listener must accept the right protocol, terminal environment variables must point to that listener, Git must receive proxy settings, SSH needs a dedicated ProxyCommand, and routing rules should send only the developer services that need the proxy through it. This guide presents a practical Clash configuration for GitHub clones, SSH pushes, package managers, and split tunneling without forcing every local service through the proxy.

Understand the Developer Proxy Path

A desktop Clash client usually exposes one or more local ports. The most common arrangement is a mixed HTTP and SOCKS port, an HTTP-only port, and sometimes a TUN interface. The exact port numbers depend on your profile and client, so check the active listener in Clash Verge, Clash Verge Rev, Mihomo, or another compatible client before copying commands.

ListenerTypical useCommon environment variable
Mixed portAccepts both HTTP proxy requests and SOCKS5 connectionsHTTP_PROXY and HTTPS_PROXY
HTTP portGit, curl, Homebrew, and other HTTP-aware toolsHTTP_PROXY and HTTPS_PROXY
SOCKS5 portSSH wrappers, browser tools, and applications with SOCKS supportALL_PROXY or tool-specific settings
TUN interfaceSystem-wide traffic capture, including applications without proxy supportNo per-tool variable required in most cases

For the examples below, assume Clash listens on 127.0.0.1:7890 for HTTP or mixed traffic and 127.0.0.1:7891 for SOCKS5 traffic. Replace these values if your client uses different ports. Keeping the listener bound to 127.0.0.1 is the safest choice for a personal computer because it prevents other devices on the local network from using your proxy without permission.

The request path for a normal HTTPS clone looks like this:

  1. Your shell starts git.
  2. Git reads its proxy configuration or environment variables.
  3. Git sends an HTTP CONNECT request to the local Clash listener.
  4. Clash matches the destination, such as github.com or objects.githubusercontent.com, against its rules.
  5. The selected proxy group establishes the remote connection, and the encrypted Git traffic passes through it.

SSH is different. An SSH remote such as [email protected]:team/project.git is not an HTTP request, so HTTP_PROXY alone cannot make it work. SSH needs either a SOCKS-capable helper, a local forwarding command, or a Clash TUN interface that captures the connection at the network layer.

Start with a single listener: A mixed port makes initial testing easier because curl, Git, and many package managers can share the same endpoint. Add a separate SOCKS port when configuring SSH or applications that do not understand HTTP CONNECT.

Configure Clash Rules for GitHub and Package Downloads

Terminal proxy variables only decide whether a program talks to Clash. They do not decide which Clash node handles the request. That decision is made by the active profile and its rules. For developer traffic, domain-based rules are usually more dependable than IP-based rules because GitHub and package delivery services use changing address ranges and content delivery networks.

A practical rule set should cover the main GitHub domains rather than only github.com. Repository pages, Git smart HTTP operations, release archives, Git LFS objects, and Actions-related downloads may use different hosts. Homebrew also retrieves metadata and bottles from several domains, and those endpoints can change as projects update their mirrors.

Developer Routing Rules
rules:
  - DOMAIN-SUFFIX,github.com,Developer
  - DOMAIN-SUFFIX,githubusercontent.com,Developer
  - DOMAIN-SUFFIX,githubassets.com,Developer
  - DOMAIN-SUFFIX,github.io,Developer
  - DOMAIN-SUFFIX,gitlab.com,Developer
  - DOMAIN-SUFFIX,bitbucket.org,Developer
  - DOMAIN-SUFFIX,brew.sh,Developer
  - DOMAIN-SUFFIX,homebrew.org,Developer
  - DOMAIN-SUFFIX,pythonhosted.org,Developer
  - DOMAIN-SUFFIX, npmjs.org,Developer
  - DOMAIN-SUFFIX,npmjs.com,Developer
  - DOMAIN-SUFFIX,rubygems.org,Developer
  - DOMAIN-SUFFIX,proxy-provider.example,DIRECT
  - DOMAIN-SUFFIX,corp.example,DIRECT
  - MATCH,DIRECT

Remove the accidental space in DOMAIN-SUFFIX, npmjs.org,Developer when adapting the example; it is shown here as a reminder that rule syntax is sensitive to whitespace. In a real profile, use a proxy group name that exists in your configuration. If your group is called Proxy, replace Developer accordingly.

Rule order matters. Clash evaluates rules from top to bottom and uses the first match. Put private networks, company domains, and local services before broad developer rules when they must remain direct. For example, an internal Git server at git.corp.example should not accidentally be sent to an external proxy merely because a general rule appears earlier in the file.

Do not attempt to list every IP address used by GitHub. CDN addresses can change frequently, and hard-coded ranges become stale. If a particular download still fails, inspect the connection log in your Clash dashboard, identify the actual hostname, and add a targeted domain rule. This is more maintainable than repeatedly expanding an IP list.

Set Terminal Proxy Variables Correctly

Most command-line tools understand the conventional proxy variables, although case sensitivity differs between applications and operating systems. Setting both uppercase and lowercase names avoids surprises when a script, language runtime, or package manager reads only one form.

Temporary Shell Proxy
# HTTP and HTTPS tools use the local Clash mixed or HTTP port
export HTTP_PROXY=http://127.0.0.1:7890
export HTTPS_PROXY=http://127.0.0.1:7890
export http_proxy=http://127.0.0.1:7890
export https_proxy=http://127.0.0.1:7890

# Do not proxy local addresses or private services
export NO_PROXY=localhost,127.0.0.1,::1,.local,10.0.0.0/8,172.16.0.0/12,192.168.0.0/16
export no_proxy=$NO_PROXY

Run a simple test before changing Git or Homebrew:

Test the HTTP Listener
curl -I https://github.com
curl -I https://raw.githubusercontent.com
curl -I https://formulae.brew.sh

A successful HTTP status proves that curl can reach the service through the selected path, but it does not prove that Git is using the same settings. Use env | grep -i proxy to inspect the current shell, and use curl -v when you need to confirm that the connection is being made to 127.0.0.1:7890.

For a persistent setup, add the exports to ~/.zshrc on macOS and most modern Linux distributions using zsh, or to ~/.bashrc for Bash. Avoid placing credentials in a shared shell file. If your local Clash listener requires authentication, use a protected credential store or a tool-specific configuration rather than publishing the token in a dotfile.

Windows PowerShell uses a different syntax:

PowerShell Proxy Variables
$env:HTTP_PROXY = "http://127.0.0.1:7890"
$env:HTTPS_PROXY = "http://127.0.0.1:7890"
$env:http_proxy = $env:HTTP_PROXY
$env:https_proxy = $env:HTTPS_PROXY
$env:NO_PROXY = "localhost,127.0.0.1,::1,.local"

PowerShell variables set this way apply only to the current terminal session. To make them persistent, configure them through the Windows environment variable interface or your PowerShell profile. Session-only variables are often preferable when you occasionally switch between direct and proxied development networks.

Route Git HTTP and HTTPS Traffic over Clash

Git can use the shell variables, but an explicit Git configuration is often easier to audit and more predictable for scripts launched outside your interactive shell. Configure a global proxy when most remote repositories use HTTPS:

Configure Git HTTP Proxy
git config --global http.proxy http://127.0.0.1:7890
git config --global https.proxy http://127.0.0.1:7890

git config --global --get http.proxy
git config --global --get https.proxy

To proxy only GitHub rather than every Git host, use a URL-specific section. This is useful when an internal company Git server must remain direct:

Proxy GitHub Only
git config --global --unset http.proxy
git config --global --unset https.proxy

git config --global http.https://github.com/.proxy http://127.0.0.1:7890
git config --global http.https://github.com/.sslVerify true

GitHub repositories can be tested without cloning a large project:

Test Git Connectivity
git ls-remote https://github.com/owner/repository.git
GIT_CURL_VERBOSE=1 git ls-remote https://github.com/owner/repository.git

The verbose command displays connection details and is useful for confirming whether Git is contacting the local Clash port. Do not leave verbose output enabled in automated builds because it can reveal URLs, headers, or other information that should not appear in logs.

There are two common mistakes. The first is setting an HTTPS proxy with an https:// URL simply because the destination uses HTTPS. A local Clash listener commonly expects an HTTP proxy URL and then creates a CONNECT tunnel to the HTTPS destination, so http://127.0.0.1:7890 is usually correct. The second is configuring a SOCKS port as an HTTP proxy. If you want Git to use SOCKS5 directly, use a supported syntax such as socks5h://127.0.0.1:7891, where available. The h variant asks the proxy side to resolve the hostname and can avoid local DNS problems.

When a repository uses HTTPS, this is normally enough. SSH remotes require the separate configuration below.

Configure SSH Clones and Pushes through Clash

SSH uses TCP port 22 by default, while most HTTP proxies cannot forward it directly. Clash can still handle SSH when you provide a local SOCKS5 listener and an SSH-compatible connector. The exact helper depends on your operating system.

On macOS and Linux, ncat from the Nmap package is a convenient option. Install it using your operating system's package manager, then add a host-specific block to ~/.ssh/config:

SSH through a SOCKS5 Listener
Host github.com
    HostName github.com
    User git
    Port 22
    IdentityFile ~/.ssh/id_ed25519
    ProxyCommand ncat --proxy 127.0.0.1:7891 --proxy-type socks5 %h %p
    ServerAliveInterval 30
    ServerAliveCountMax 3

The placeholders %h and %p are replaced by SSH with the destination host and port. The connector opens a SOCKS5 request to Clash, and Clash then applies the route for github.com. Keep the host block narrow instead of putting a proxy command under Host *; otherwise local servers, bastion hosts, and internal Git services may unexpectedly use the external proxy.

Some systems provide a different connector. If your OpenSSH build includes a compatible nc, the following form may work:

Alternative SSH Connector
Host github.com
    HostName github.com
    User git
    ProxyCommand nc -x 127.0.0.1:7891 -X 5 %h %p

Connector flags are not universal. Run ncat --help or nc -h and confirm the SOCKS option before using a command in a build script. If the helper is missing, SSH will fail immediately with an error such as “exec request failed” or “No such file or directory,” even though Clash itself is working.

GitHub also supports SSH over port 443, which is useful on networks that block outbound port 22. Add a separate host alias so you can switch without changing every repository URL:

GitHub SSH over Port 443
Host github-443
    HostName ssh.github.com
    User git
    Port 443
    IdentityFile ~/.ssh/id_ed25519
    ProxyCommand ncat --proxy 127.0.0.1:7891 --proxy-type socks5 %h %p
    ServerAliveInterval 30
    ServerAliveCountMax 3

Use the alias in the remote URL:

Use the SSH Alias
git clone git@github-443:owner/repository.git
git remote set-url origin git@github-443:owner/repository.git
ssh -T git@github-443

The first SSH connection may ask you to verify the host key. Confirm the fingerprint through GitHub's official documentation before accepting it. A proxy changes the network path, but it does not remove the need for normal SSH host-key verification.

Do not confuse authentication with proxying: A successful connection to Clash does not prove that your GitHub key is accepted. Test the layers separately with ssh -vvv [email protected], then check ssh-add -l and the public key registered with your GitHub account.

Make Homebrew and Package Managers Reliable

Homebrew uses Git repositories for some operations and downloads prebuilt bottles or source archives from other endpoints. A proxy that fixes git clone may not fix bottle downloads if the relevant domain is missing from Clash rules or if Homebrew was launched from a shell without proxy variables.

With the temporary shell variables already set, test Homebrew metadata and a harmless diagnostic command:

Test Homebrew through Clash
brew update --dry-run
brew config
brew doctor

Review the Clash connection log while running the command. Look for hosts such as formulae.brew.sh, github.com, and the bottle download host shown in the request. If the bottle host is direct and fails, add its domain to the developer rule set instead of blindly proxying all traffic.

The same principle applies to other package managers. npm, pip, RubyGems, Cargo, Go modules, and container registries each have their own configuration and may not consistently inherit every shell variable. Prefer an explicit per-tool configuration when a project must behave identically on a developer laptop and in CI.

  • npm: use npm config set https-proxy http://127.0.0.1:7890 when shell inheritance is unreliable.
  • pip: use the --proxy option for a one-time install, or configure a project-specific package index where appropriate.
  • Cargo: configure proxy variables in the environment used by Cargo, and remember that Git dependencies may separately invoke Git or SSH.
  • Go: check GOPROXY and GONOSUMDB; a proxy listener does not replace a Go module mirror.
  • Docker: configure the Docker daemon and build environment separately. A proxy variable in your interactive shell does not automatically reach the daemon.

For CI runners, avoid pointing at 127.0.0.1 unless Clash is running inside the same runner. In a container or remote build machine, the loopback address refers to that environment, not your development computer. Use the runner's approved proxy endpoint, or configure Clash on the runner itself with suitable access controls.

Use Split Tunneling for a Faster Build Workflow

Sending every connection through a proxy is simple, but it can increase latency for local services, private registries, intranet hosts, and nearby mirrors. Split tunneling is usually better for development: route public Git hosting and unavailable package endpoints through Clash while keeping local and corporate traffic direct.

There are two ways to implement it. Rule-based split tunneling works at the Clash profile level and is appropriate when you can identify domains. TUN mode captures applications that do not honor proxy variables, but it should be enabled carefully because it affects more traffic and may change DNS behavior.

A balanced rule order commonly looks like this:

  1. Send localhost, private IP ranges, and local mDNS domains directly.
  2. Send company domains and internal Git hosts directly.
  3. Send GitHub, GitLab, package registries, and required artifact hosts to the developer proxy group.
  4. Apply the normal browser or general traffic policy.
  5. Use a final MATCH rule as a deliberate fallback rather than leaving traffic ambiguous.
Split-Tunnel Rule Order
rules:
  - DOMAIN-SUFFIX,local,DIRECT
  - IP-CIDR,127.0.0.0/8,DIRECT,no-resolve
  - IP-CIDR,10.0.0.0/8,DIRECT,no-resolve
  - IP-CIDR,172.16.0.0/12,DIRECT,no-resolve
  - IP-CIDR,192.168.0.0/16,DIRECT,no-resolve
  - DOMAIN-SUFFIX,corp.example,DIRECT
  - DOMAIN-SUFFIX,github.com,Developer
  - DOMAIN-SUFFIX,githubusercontent.com,Developer
  - DOMAIN-SUFFIX,brew.sh,Developer
  - MATCH,Proxy

The no-resolve option on private IP rules prevents Clash from performing an unnecessary DNS lookup before matching. Do not apply it indiscriminately to domain rules. If you use fake-IP DNS mode, ensure your local domains and services are included in the appropriate fake-IP filter or direct-resolution settings, especially when working with databases, virtual machines, and service discovery tools.

TUN mode is valuable when a tool ignores HTTP and SOCKS settings, but it can hide the original cause of a failure because traffic is captured transparently. Enable it only after ordinary proxy variables and explicit tool configuration are understood. Keep an eye on DNS mode, IPv6 behavior, and exclusions for VPN clients or virtualization software.

Debug Common Clash Developer Failures

When a clone or build fails, diagnose one layer at a time instead of changing the node, rules, DNS mode, and Git configuration simultaneously. The following sequence usually identifies the problem quickly:

  1. Confirm Clash is running and the selected proxy group has an available node.
  2. Check that the local listener accepts connections with curl -v.
  3. Check the destination hostname in the Clash connection log.
  4. Test the same destination with curl, Git, and SSH separately.
  5. Inspect whether the request matched DIRECT, Developer, or an unexpected rule.
  6. Only then investigate authentication, TLS, host keys, or package-manager-specific behavior.
SymptomLikely causeFirst check
curl works, Git failsGit-specific proxy setting or certificate issuegit config --show-origin --get-regexp proxy
HTTPS clone works, SSH clone failsNo SSH ProxyCommand or wrong SOCKS portssh -vvv [email protected]
GitHub opens, bottle download failsUnmatched CDN or package hostInspect the Clash connection log during download
Everything is slowAll traffic is proxied or node latency is highReview split-tunnel rules and proxy-group health
Internal services stop workingPrivate domain matched a broad proxy ruleMove internal and private rules above developer rules
SSH says connection refusedClash SOCKS listener is disabled or port is incorrectVerify the active port in the client settings

To remove a global Git proxy and return to environment-based control, run:

Reset Git Proxy Settings
git config --global --unset http.proxy
git config --global --unset https.proxy
git config --global --get-regexp 'http\..*proxy|https\..*proxy'

If a command works in your terminal but fails in an IDE, compare the IDE's environment with env | grep -i proxy. GUI applications may not read shell startup files, and an IDE launched before Clash starts may retain an old environment. Configure the IDE's integrated terminal or application proxy settings explicitly, or use TUN mode when the application cannot be configured separately.

Keep a small diagnostic script: Record the Clash listener ports, proxy variables, Git proxy state, and SSH test command in your project documentation. This turns a network failure into a repeatable check and makes onboarding new developers much easier.

A dependable developer setup does not require routing every byte through Clash. Use the HTTP or mixed listener for Git and package managers, the SOCKS listener for SSH, domain rules for public developer services, and direct exclusions for private infrastructure. Once each layer is tested independently, GitHub clones, SSH pushes, Homebrew updates, and repeatable builds become much less sensitive to the network you happen to be using.

Get Started

Take Full Control of Your Traffic with Clash

Available on Windows, macOS, Linux, Android, and iOS. Flexible rules, simple setup, ready to use.

Download Free View Setup Guide →