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.
| Listener | Typical use | Common environment variable |
|---|---|---|
| Mixed port | Accepts both HTTP proxy requests and SOCKS5 connections | HTTP_PROXY and HTTPS_PROXY |
| HTTP port | Git, curl, Homebrew, and other HTTP-aware tools | HTTP_PROXY and HTTPS_PROXY |
| SOCKS5 port | SSH wrappers, browser tools, and applications with SOCKS support | ALL_PROXY or tool-specific settings |
| TUN interface | System-wide traffic capture, including applications without proxy support | No 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:
- Your shell starts
git. - Git reads its proxy configuration or environment variables.
- Git sends an HTTP CONNECT request to the local Clash listener.
- Clash matches the destination, such as
github.comorobjects.githubusercontent.com, against its rules. - 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.
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.
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.
# 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:
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:
$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:
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:
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:
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:
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:
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:
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:
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.
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:
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:7890when shell inheritance is unreliable. - pip: use the
--proxyoption 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
GOPROXYandGONOSUMDB; 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:
- Send localhost, private IP ranges, and local mDNS domains directly.
- Send company domains and internal Git hosts directly.
- Send GitHub, GitLab, package registries, and required artifact hosts to the developer proxy group.
- Apply the normal browser or general traffic policy.
- Use a final
MATCHrule as a deliberate fallback rather than leaving traffic ambiguous.
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:
- Confirm Clash is running and the selected proxy group has an available node.
- Check that the local listener accepts connections with
curl -v. - Check the destination hostname in the Clash connection log.
- Test the same destination with curl, Git, and SSH separately.
- Inspect whether the request matched
DIRECT,Developer, or an unexpected rule. - Only then investigate authentication, TLS, host keys, or package-manager-specific behavior.
| Symptom | Likely cause | First check |
|---|---|---|
| curl works, Git fails | Git-specific proxy setting or certificate issue | git config --show-origin --get-regexp proxy |
| HTTPS clone works, SSH clone fails | No SSH ProxyCommand or wrong SOCKS port | ssh -vvv [email protected] |
| GitHub opens, bottle download fails | Unmatched CDN or package host | Inspect the Clash connection log during download |
| Everything is slow | All traffic is proxied or node latency is high | Review split-tunnel rules and proxy-group health |
| Internal services stop working | Private domain matched a broad proxy rule | Move internal and private rules above developer rules |
| SSH says connection refused | Clash SOCKS listener is disabled or port is incorrect | Verify the active port in the client settings |
To remove a global Git proxy and return to environment-based control, run:
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.
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.
Take Full Control of Your Traffic with Clash
Available on Windows, macOS, Linux, Android, and iOS. Flexible rules, simple setup, ready to use.