最近在向 GitHub 推送代码时,网络又开始抽风。无论是 git push 还是 git pull,都大概率会卡在某个地方,然后给我一个冰冷的 Connection refused 或者 Connection reset。就算切换到 SSH 协议,有时也难逃一劫。
每次遇到这个问题都要重新搜索一遍解决方案,效率太低。为了防止以后自己忘记,也为了形成一个可以快速查阅的备忘录,我决定把几种主流的解决方案整理成一篇文章,彻底搞定这个问题。
1. 背景与常见错误
问题的核心在于本地网络环境与 GitHub 服务器之间的网络连接不稳定或存在策略性阻断。这通常会导致以下几种典型的错误信息:
通过 SSH 协议访问时:
ssh: connect to host github.com port 22: Connection refused
fatal: Could not read from remote repository.
Please make sure you have the correct access rights
and the repository exists.
或者在测试 SSH 连通性时出现:
$ ssh -T git@github.com
Connection reset by 20.205.243.160 port 443
我们的目标就是通过配置代理,让 Git 的网络请求绕过不稳定的链路,从而实现稳定访问。
2. 准备工作:确认代理端口
在开始配置之前,必须先确认本地代理软件监听的协议和端口。如果这里搞错了,后续的所有配置都将无效。
- Clash: 通常 HTTP 代理端口为
7890,SOCKS5 代理端口为7891。 - V2RayN/V2RayU: 通常 HTTP 代理端口为
10808,SOCKS5 代理端口为10809。 - Shadowsocks: 通常 SOCKS5 代理端口为
1080。
提示:具体端口请以代理软件设置界面显示的为准。
3. 方案一:通过 SSH 配置代理
这个方案是我最推荐的,因为它只对 github.com 的 SSH 连接生效,不会影响其他任何工具或网站的访问,而且配置一次后就无需再关心。它适用于远程仓库地址格式为 git@github.com:user/repo.git 的情况。
步骤 1: 编辑 SSH 配置文件
打开终端,使用你熟悉的编辑器(如 vim 或 nano 或 vscode)编辑 SSH 用户配置文件。如果文件不存在,这个命令会自动创建它。
# 可以用nano
nano ~/.ssh/config
步骤 2: 添加代理配置
在打开的文件中,添加以下内容。请注意区分操作系统,因为它们使用的代理命令工具不同。
对于 macOS / Linux 用户:
Host github.com
Hostname ssh.github.com
Port 443
User git
# 使用 nc (netcat) 作为代理命令,-x 参数表示 SOCKS5 代理
# 如果你的代理是 HTTP 类型,可以尝试将 -x 改为 -X connect
ProxyCommand nc -v -x 127.0.0.1:7891 %h %p
对于 Windows (Git Bash) 用户:
Host github.com
Hostname ssh.github.com
Port 443
User git
# Git for Windows 自带了 connect.exe 工具
# -S 参数表示 SOCKS5 代理,-H 参数表示 HTTP 代理
ProxyCommand connect -S 127.0.0.1:7891 %h %p
注意:请务必将上述命令中的
127.0.0.1:7891替换为你自己在第二步中确认的真实代理地址和端口。如果你的代理是 HTTP 类型,记得将nc的-x参数或connect的-S参数相应地修改。
配置参数解释:
Hostname ssh.github.com: 使用 GitHub 官方提供的备用 SSH 域名,可以有效规避某些针对github.com的 DNS 污染。Port 443: 将 SSH 连接的默认22端口切换到443(HTTPS) 端口,这可以绕过部分防火墙对22端口的封锁。ProxyCommand: 这是核心指令,它告诉 SSH 在连接github.com时,不要直接发起 TCP 连接,而是执行一个指定的命令来建立通道。%h和%p是占位符,分别代表目标主机名(Hostname)和端口(Port)。
步骤 3: 测试连接
保存配置文件后,执行以下命令测试 SSH 连通性:
ssh -T git@github.com
如果看到以下欢迎信息,就说明配置成功了!
Hi your-username! You've successfully authenticated, but GitHub does not provide shell access.
4. 方案二:通过 HTTPS 配置全局代理
如果你的仓库地址是 https://github.com/user/repo.git 格式,则需要配置 Git 的 http.proxy 和 https.proxy。这种方式会影响所有使用 Git 的 HTTPS 请求,而不仅限于 GitHub。
提示:如果你的仓库当前是 SSH 格式,可以先用
git remote set-url origin https://github.com/user/repo.git切换到 HTTPS 格式。
步骤 1: 设置 Git 全局代理
执行以下命令,将 Git 的所有 HTTPS 流量都指向你的本地代理。
# 分别为 HTTP 和 HTTPS 协议设置代理
# 注意这里的代理地址格式是 http://<host>:<port> 或 socks5://<host>:<port>
git config --global http.proxy http://127.0.0.1:7890
git config --global https.proxy http://127.0.0.1:7890
步骤 2: 取消代理(需要时)
如果后续不需要代理了,可以通过 --unset 参数来移除配置。
git config --global --unset http.proxy
git config --global --unset https.proxy
5. 方案三:仅为 GitHub 配置 HTTPS 代理
这是方案二的优化版。如果你不希望代理影响到其他 Git 仓库(例如 Gitee 或 GitLab),只想针对 GitHub 进行配置,可以使用下面的命令。
设置针对性代理
git config --global http.https://github.com.proxy http://127.0.0.1:7890
取消针对性代理
git config --global --unset http.https://github.com.proxy
这个配置为一个特定的 URL 域设置了专有的代理。
6. 避坑指南与常见问题
在折腾的过程中,我还是踩了一些坑,这里一并记录下来,方便日后快速排查。
-
Windows 下提示
command not found: connect- 原因分析: 多数情况下,Git for Windows 自带
connect.exe。如果出现此提示,可能是PATH环境变量未正确配置,或者 Git 安装不完整。 - 解决方案: 可以在 SSH 配置中直接使用
connect.exe的绝对路径来规避PATH问题。# 将 ProxyCommand 指向 connect.exe 的绝对路径 ProxyCommand /mingw64/bin/connect -H 127.0.0.1:10808 %h %p
- 原因分析: 多数情况下,Git for Windows 自带
-
首次连接提示主机真实性无法确认
- 现象: 在执行
ssh -T git@github.com时,终端可能会显示以下信息:The authenticity of host '[ssh.github.com]:443 ([140.82.113.37]:443)' can't be established. Are you sure you want to continue connecting (yes/no/[fingerprint])? - 解决方案: 这并非错误,而是 SSH 的标准安全机制。它表示这是你第一次连接该主机,需要你确认其公钥指纹。
提示:直接输入
yes并回车即可。SSH 会将该主机的公钥信息保存到~/.ssh/known_hosts文件中,下次连接时便不会再提示。
- 现象: 在执行
-
连接测试时出现
Connection refused- 原因分析: 这是最常见的错误,表明你的 Git/SSH 请求根本没有成功到达代理服务器。
- 排查清单:
- 检查代理软件是否已启动并处于正常工作状态。
- 再次核对
~/.ssh/config或git config中填写的端口号是否与代理软件实际监听的端口完全一致。一个数字的错误就会导致失败。
-
SSH 连接时出现
Broken pipe错误- 原因分析: 这个错误通常是代理协议类型不匹配导致的。例如,你的代理是 HTTP 类型,但在
ProxyCommand中却错误地使用了-S(SOCKS5) 参数。 - 解决方案: 确保
connect命令的参数与你的代理协议一致。- 如果代理是 HTTP 类型,应使用
-H参数。 - 如果代理是 SOCKS5 类型,应使用
-S参数。
# 示例:将错误的 SOCKS5 参数(-S)修正为正确的 HTTP 参数(-H) ProxyCommand connect -H 127.0.0.1:10808 %h %p - 如果代理是 HTTP 类型,应使用
- 原因分析: 这个错误通常是代理协议类型不匹配导致的。例如,你的代理是 HTTP 类型,但在