Build a predictable proxy workflow for development tools
GitHub timeouts, failed Git clones, package installation errors, and unreliable Copilot sessions often look like separate problems. In practice, they can share the same cause: the browser is using Clash successfully, while the terminal tool or background development service is taking a different network path. A browser normally reads the operating system proxy, but Git, OpenSSH, language package managers, containers, and editor extensions may use their own networking rules.
The useful approach is not to force every tool through the same setting immediately. First identify the application, the protocol it uses, and the Clash entry point that should receive the traffic. Clash commonly exposes an HTTP proxy, a SOCKS5 proxy, or a mixed port that accepts both. The exact port depends on the active configuration and client. Common examples include 7890 for HTTP and 7891 for SOCKS5, but these values are not universal and must be confirmed in the Clash or mihomo client.
For a development workstation, separate the workflow into four layers:
- Clash status: the core is running, the configuration is loaded, and a usable policy group is selected.
- Traffic entry: the operating system proxy, an application-specific proxy variable, or an SSH proxy command sends traffic into Clash.
- Routing policy: rules decide whether GitHub, package registries, documentation sites, and other targets use a proxy or DIRECT.
- Application behavior: Git, SSH, npm, pip, Docker, and editor services may need separate configuration even when the browser works.
Before changing settings, record the current Clash mode, the mixed or separate proxy ports, the selected policy group, and whether TUN mode is enabled. Keeping this baseline makes it easier to undo a change and determine which setting solved the problem.
Prepare Clash: ports, rules, DNS, and mode selection
Open the client settings and verify the ports exposed by the active core. A mixed port is convenient because many command-line programs can use either HTTP or SOCKS5 through one local address. If the client exposes separate ports, use the HTTP port for Git HTTPS and package managers that understand HTTP proxy variables, and use the SOCKS5 port for tools that support SOCKS directly.
Rule mode is normally the best starting point for development traffic. It allows ordinary websites and local services to remain DIRECT while selected domains use a proxy policy group. Global mode can help isolate a routing problem, but it may send package downloads, internal repositories, local network traffic, and credentials through a remote node unnecessarily. Direct mode is useful as a control test, not as a permanent solution when the destination is unreachable without a proxy.
Check whether your rules cover the actual hostnames used by the service. A Git operation may contact more than the visible repository domain. Authentication, release downloads, raw files, API calls, asset delivery, package metadata, and a remote extension service can use different hostnames. If a browser page opens but git clone still times out, inspect the Clash connection list while running the command. If no connection appears, Git has not entered Clash. If a connection appears with a DIRECT action, the rule or mode is the next place to investigate.
DNS handling is also important. In system-proxy mode, an application may resolve a hostname locally before sending the connection to Clash. In TUN mode, mihomo can handle more traffic at the virtual interface layer, often together with enhanced DNS features such as fake-IP or redirection-based DNS. These features improve coverage but increase the number of variables. Do not enable TUN, change DNS, and replace the configuration at the same time unless the current setup is unusable.
| Method | Best use | Main limitation |
|---|---|---|
| System proxy | Browsers and applications that follow operating system settings | Command-line and embedded networking stacks may ignore it |
| HTTP proxy variables | Git HTTPS, curl, npm, pip, and many build tools | Only works when the application reads the variables |
| SOCKS5 configuration | Tools with explicit SOCKS support | Not every package manager or Git transport accepts SOCKS directly |
| SSH ProxyCommand | Git over SSH and ordinary SSH sessions | Requires a local relay command and careful host configuration |
| TUN mode | Applications that ignore proxy settings or use several protocols | Needs additional permissions, routes, DNS, and firewall checks |
Connect Git over HTTPS without affecting every application
Git over HTTPS is usually the simplest development path because Git can use an HTTP proxy for HTTPS repository URLs. This does not mean that the proxy URL should begin with https://. In many configurations, the local Clash listener is an ordinary HTTP proxy that receives encrypted HTTPS traffic through the CONNECT method. The local proxy address is therefore commonly written as http://127.0.0.1:7890, subject to the port shown by your client.
Start with a temporary environment variable so that the test does not permanently alter Git. On macOS or Linux, a shell command can look like this:
export HTTPS_PROXY=http://127.0.0.1:7890
export HTTP_PROXY=http://127.0.0.1:7890
git ls-remote https://github.com/example/project.git
On Windows PowerShell, use the equivalent session-level variables:
$env:HTTPS_PROXY = "http://127.0.0.1:7890"
$env:HTTP_PROXY = "http://127.0.0.1:7890"
git ls-remote https://github.com/example/project.git
The repository name in this example is only a placeholder. The important part is to use a repository that you are authorized to access and to test a lightweight command such as git ls-remote before downloading a large history. Watch the Clash connection log at the same time. A successful response combined with a visible proxied connection confirms that Git reached the local listener and that the request received a usable policy.
If the temporary test works, save the setting at the Git level instead of exporting it globally for every program:
git config --global http.proxy http://127.0.0.1:7890
git config --global https.proxy http://127.0.0.1:7890
Git also supports more targeted configuration. A host-specific rule is safer when only one service requires the proxy:
git config --global http.https://github.com.proxy http://127.0.0.1:7890
Review existing values before adding another one. Multiple proxy entries, an obsolete port, or credentials embedded in a copied URL can create confusing failures:
git config --global --get-regexp 'http\..*proxy'
git config --show-origin --get-regexp 'http\..*proxy'
To remove a setting that is no longer needed, use git config --global --unset http.proxy or git config --global --unset https.proxy. Also inspect shell startup files and CI environment variables. A stale HTTPS_PROXY can override what you believe is the current Git configuration.
Route Git and SSH traffic through Clash with ProxyCommand
Git over SSH is different from Git over HTTPS. OpenSSH does not automatically treat an HTTP proxy as a normal network gateway, and setting HTTPS_PROXY alone usually does not configure an SSH connection. When a repository uses an SSH address such as [email protected]:owner/project.git, the SSH client must open a TCP connection to the SSH host, commonly on port 22 or an alternative SSH endpoint offered by the service.
A practical solution is to use a local relay program that understands SOCKS5 or HTTP CONNECT. Depending on the operating system, available tools may include nc with proxy support, connect, or another approved relay utility. The relay must be installed separately and its syntax differs between implementations, so copy the syntax from that utility's local documentation rather than assuming that every nc build accepts the same options.
For a SOCKS5-capable relay, the SSH configuration concept is:
Host github.com
HostName github.com
User git
ProxyCommand connect -S 127.0.0.1:7891 %h %p
IdentitiesOnly yes
Here, 127.0.0.1:7891 represents the SOCKS5 listener and %h and %p are replaced by the target host and port. The exact command may instead require a syntax such as nc -x 127.0.0.1:7891 -X 5 %h %p. Test the relay directly according to its implementation, then run SSH with verbose logging:
ssh -Tv [email protected]
git ls-remote [email protected]:owner/project.git
Verbose output helps distinguish several failure types. “Permission denied” usually means that the network path succeeded but the SSH key or account authorization failed. “Connection timed out” points more strongly to the relay, Clash rule, node, firewall, or destination port. A message indicating that the proxy command cannot be found means the local relay is missing or not available in the current PATH.
Use a narrow Host block rather than applying a proxy command to every SSH destination. Internal servers, GitLab installations, staging machines, and local development hosts may require DIRECT access or a different jump host. Keep separate aliases when necessary:
Host public-git
HostName github.com
User git
ProxyCommand connect -S 127.0.0.1:7891 %h %p
Host internal-git
HostName git.internal.example
User git
ProxyCommand none
When changing from HTTPS to SSH, remember that authentication and transport are separate. A working proxy path does not create an SSH key, approve a host key, or grant repository access. Verify the host key prompt carefully, use the intended identity, and do not disable host-key checking merely to bypass a connection error.
Hands-on test: verify one complete developer request
Perform the following sequence after preparing Clash. The goal is to change one layer at a time and identify the first failed boundary.
- Confirm the local listener. Check the Clash settings for the actual HTTP and SOCKS ports. Make sure another VPN, proxy application, or development service is not already occupying the port.
- Check a simple HTTP request. Use a command-line HTTP client that supports the selected proxy and request a small, authorized endpoint. If the command cannot connect to
127.0.0.1, the issue is local and unrelated to the remote repository. - Test Git HTTPS. Run
git ls-remotewith a temporary proxy variable. Review both the terminal output and the Clash connection list. - Test SSH separately. If your project uses SSH, configure the relay and run
ssh -Tv. Do not infer SSH health from a successful HTTPS test. - Try a small clone or fetch. Use a repository you can access. A small operation reduces the effect of bandwidth limits and makes timeout diagnosis easier.
- Test the package manager. Run a metadata or dry-run command for npm, pip, Cargo, Go, or another tool used by the project. Package registries may not share the same host or rule as GitHub.
- Record the result. Note the mode, policy group, node, proxy port, command, and error message before switching to another variable.
For example, if curl succeeds through the HTTP port but git ls-remote fails, inspect Git's own proxy configuration and credential helper. If Git HTTPS succeeds but SSH fails, inspect the SSH relay and port path. If both succeed but package installation fails, check registry configuration, certificate verification, and the package manager's proxy variables rather than replacing the Clash profile.
Configure package managers, editors, and Copilot carefully
Package managers often read standard environment variables, but they may also have their own configuration files. npm can use HTTP_PROXY and HTTPS_PROXY, or explicit npm settings. pip commonly reads proxy variables and can receive a proxy through its command-line options. Other ecosystems, including Cargo, Go, Maven, and language-specific build tools, differ in how they handle proxies and certificate authorities.
Begin with a temporary variable for a single command. This avoids forcing internal package registries through a public proxy:
HTTPS_PROXY=http://127.0.0.1:7890 npm view typescript version
HTTPS_PROXY=http://127.0.0.1:7890 python -m pip index versions requests
If a package manager has a dedicated proxy setting, check whether it stores the value in a user configuration file. Remove obsolete values when testing a new arrangement. A package download that fails with a timeout is a routing problem candidate; a certificate or signature error is not automatically solved by changing nodes. Corporate inspection certificates, private registries, and package integrity checks may require organization-specific trust configuration.
Editor extensions and Copilot-like coding assistants can use a different process from the integrated terminal. Some extensions inherit the editor's proxy settings, some read operating system settings, and others depend on the runtime used by the extension host. If code completion is unreliable while Git works, inspect the editor's network or proxy preference, restart the extension host after changing it, and watch whether the relevant connections appear in Clash. Do not assume that a successful browser login proves that the background service can complete its own API, streaming, or WebSocket requests.
When using TUN mode, these applications may be captured even when they ignore HTTP proxy variables. However, TUN does not bypass authentication, certificate validation, service quotas, or application-specific restrictions. It also does not guarantee that every connection will use the same route. Rules can still send some domains DIRECT, and an application may resolve several service endpoints during one session.
For teams, document the intended split: public source hosts through the selected proxy policy, internal Git servers DIRECT or through the corporate gateway, and package registries according to company security requirements. A reproducible policy is safer than asking every developer to enable Global mode whenever a command fails.
Security and troubleshooting: keep the developer path maintainable
A local proxy changes the route of application traffic, so treat the configuration as part of the workstation's security boundary. Use trusted nodes and avoid sending private repository traffic, deployment credentials, or package tokens through an unapproved service. A proxy can observe connection metadata, and an incorrectly configured debugging tool may expose credentials in logs or command history.
Do not disable TLS verification as a general fix. Options such as Git's http.sslVerify false, package-manager certificate bypasses, or SSH host-key checks remove protections without repairing the underlying route. If a certificate fails, determine whether the target certificate, local clock, trust store, corporate inspection certificate, or proxy interception is responsible.
The following order keeps diagnosis efficient:
- Check that Clash is running and the intended configuration is active.
- Confirm the local port with a small local connection test.
- Check whether the failing tool supports the selected proxy method.
- Inspect the Clash connection log for the exact hostname and action.
- Compare Rule mode with a controlled Global-mode test, then restore Rule mode.
- Compare a second node without changing the command or application settings.
- Clear only the stale setting that caused the problem and retest.
Common symptoms provide useful clues. “Proxy refused” often indicates a stopped core, wrong port, or port conflict. “Could not resolve host” points toward DNS, local resolver behavior, or an incomplete hostname. A timeout with no Clash log entry suggests that the tool bypassed Clash or failed before opening a network connection. A timeout with a logged DIRECT connection suggests a rule mismatch. A fast connection followed by repeated transfer stalls may indicate node load, destination throttling, or a large-file route problem rather than Git configuration.
For automated builds and CI, avoid copying a desktop user's proxy configuration blindly. CI runners may use different operating systems, credentials, DNS, and network policies. Prefer documented environment variables or runner-level proxy settings, keep secrets in the CI secret store, and ensure that the runner is authorized to access the selected proxy. If only a private network needs access, a dedicated runner or approved gateway may be more appropriate than a personal Clash node.
FAQ: GitHub, Git, and SSH proxy questions
Why does GitHub open in the browser while Git clone times out?
The browser may be using the system proxy while Git is using a direct connection. Check Git's http.proxy and https.proxy values, then run a small git ls-remote test with a temporary HTTP proxy variable. Also confirm that the Clash connection list shows the request and that the selected rule is not DIRECT.
Can HTTPS_PROXY configure Git over SSH automatically?
Usually not. SSH needs a TCP connection and does not generally interpret an HTTP proxy environment variable by itself. Configure an SSH ProxyCommand with a SOCKS5- or HTTP-CONNECT-capable relay, then test it with ssh -Tv.
Should developers use Global mode for package downloads?
Global mode can be useful as a short diagnostic comparison, but it is rarely the best permanent choice. Rule mode provides more control and reduces the chance of sending internal repositories, local services, or private package traffic through an unintended node.
Will TUN mode fix every editor or Copilot connection?
No. TUN can capture applications that ignore system proxy settings, but the result still depends on routes, DNS, rules, node availability, authentication, certificates, and the service's own endpoint behavior. Use the connection log to confirm what the editor actually sends through Clash.
Choose the right Clash client
Check the available desktop clients, confirm the correct platform build, and then use the client settings to verify ports, rules, and TUN permissions before configuring Git or SSH.