在 VPS 上执行 git clone、git fetch 或部署脚本时,GitHub 连接一直超时,卡在 Cloning into...,但浏览器又能打开仓库?先确认 Git 实际使用的是 HTTPS 还是 SSH、直连还是代理。网页可访问,不代表 SSH 的 22 端口通,也不能证明当前部署用户有仓库权限。
本文面向 GitHub.com 上的仓库,按“确认真实连接方式 → 小请求测试 → 端口或代理排查 → 认证判断 → 验证部署”处理。GitHub Enterprise Server 和使用数据驻留域名的企业服务,应按对应实例文档操作,不能直接套用本文的公共 443 SSH 入口。
| 看到的错误或现象 | 优先检查 |
|---|---|
Could not resolve host: github.com | VPS DNS 与代理主机解析 |
connect to host github.com port 22: Connection timed out | SSH 出站 22 端口与网络路径 |
连接 127.0.0.1:7890、旧代理地址失败 | Git 配置或环境中的代理是否真实可用 |
SSL certificate problem | 系统时间、可信 CA、TLS 代理与 Git TLS 配置 |
Permission denied (publickey) | SSH 已到达认证阶段,检查密钥与 GitHub 账号 |
Repository not found、401/403 | 仓库地址、账号权限、凭据和组织策略 |
RPC failed、HTTP/2 stream、early EOF | 传输中断,结合协议、代理、日志和仓库大小排查 |
GitHub 官方将防火墙、代理与网络规则列为常见连接故障来源,见连接问题排查文档。不要只凭“clone 失败”就换镜像地址或重新生成密钥。
在出现报错的同一个用户、终端或部署服务环境里检查:
git --version
git remote -v
git config --show-origin --get-regexp '^url\..*\.insteadof$'
git config --show-origin --get-urlmatch http.proxy https://github.com/
git config --show-origin --get-urlmatch http.sslVerify https://github.com/
env | grep -iE '^(http_proxy|https_proxy|all_proxy|no_proxy)='
如果尚未克隆出仓库,跳过 git remote -v,直接检查你准备使用的 clone URL。查询没有输出可能只是未设置该项,不必为此新建配置。
https://github.com/OWNER/REPO.git 使用 HTTPS;[email protected]:OWNER/REPO.git 通常使用 SSH。url.*.insteadOf 可以重写地址,所以命令里看起来是 HTTPS,实际却可能被改成 SSH。--show-origin 有助于找到配置来自哪个文件。
再看代理是否属于当前 VPS。你电脑上的 127.0.0.1:7890 指向电脑,VPS 上相同地址指向 VPS 自己;只有该机器上确实运行了对应代理,它才可用。HTTP 代理设置也不会自动替 OpenSSH 完成连接。
代理 URL、远端 URL 或环境配置可能包含凭据,检查输出时应保留在本机,分享前删去用户名、令牌和密码。不要把原始配置日志直接贴到公开工单。
先测试解析和 HTTPS,再对一个公开仓库做只读引用查询:
getent ahosts github.com
curl -I --connect-timeout 5 --max-time 15 https://github.com/
GIT_TERMINAL_PROMPT=0 git ls-remote https://github.com/vercel/next.js.git HEAD
git ls-remote 不下载整个仓库,适合确认 Git 传输是否至少能获取引用。这里的公开仓库仅用于连通性对照,不需要私人令牌。若有 URL 重写,仍要结合第一步确认实际使用的协议。
网页请求能完成而 Git 查询失败时,继续检查 Git 专用配置、代理与 TLS;公开仓库成功但目标私有仓库失败时,优先看地址和权限。小请求成功也不能保证大型 pack、Git LFS 或子模块传输都正常。
接着测试 SSH 22 端口:
ssh -vT -o ConnectTimeout=10 [email protected]
首次连接时,将显示的主机指纹与 GitHub 官方 SSH 指纹核对,一致后再接受。不要使用 StrictHostKeyChecking=no 隐藏身份问题。
注意:GitHub SSH 测试认证成功后会提示不提供 Shell,命令的退出码仍可能是 1。判断时看认证消息中的账号与实际仓库访问结果,不能把“退出码不是 0”一律当作端口不通。该行为见 GitHub SSH 测试文档。
如果 HTTPS 可用而 GitHub SSH 22 超时,先检查 VPS 的出站规则、云安全组、服务商网络与现有代理。GitHub.com 提供另一个官方 SSH 入口:
ssh -T -p 443 -o ConnectTimeout=10 [email protected]
主机是 ssh.github.com。 这是运行在 443 端口上的 SSH 协议,不是 HTTPS 请求;只允许真正 HTTPS 的代理或网络设备仍可能拒绝它。首次连接也需要核对官方指纹。
确认它能完成认证后,可以直接使用显式 URL,先不修改其他 SSH 连接配置:
git clone ssh://[email protected]:443/OWNER/REPO.git
把 OWNER/REPO 替换为目标仓库。GitHub 的官方 SSH 443 说明也明确指出,Enterprise Server 与 Enterprise Cloud 数据驻留场景不支持直接照搬这个公共入口。
备份现有 ~/.ssh/config,检查已有 GitHub 相关 Host 块,再合并下面的设置:
Host github.com
HostName ssh.github.com
Port 443
User git
保留已有 IdentityFile、账号别名和其他必要设置,不要覆盖整个文件或重复堆叠互相冲突的 Host 块。需要使用不同 GitHub 账号时,还应保留各自的密钥选择规则。
查看最终生效值,再测试:
ssh -G [email protected] | grep -Ei '^(hostname|port|user|identityfile|proxycommand|proxyjump) '
ssh -T [email protected]
如果不再需要该变更,恢复备份或撤销这次修改的字段。不要为了 GitHub 的出站连接,顺便改动 VPS 自身的 SSH 服务配置。
如果日志显示连接的是旧代理、错误端口或根本不存在的本机代理,先确认这台 VPS 是否本来就需要代理。允许直连的环境,可以做一次不持久化的对照测试:
env -u http_proxy -u https_proxy -u all_proxy \
-u HTTP_PROXY -u HTTPS_PROXY -u ALL_PROXY \
git -c http.proxy= -c http.https://github.com/.proxy= \
ls-remote https://github.com/vercel/next.js.git HEAD
它为这次命令移除常见代理环境变量,并清空普通及 GitHub URL 级别的 HTTP 代理设置。仍要确认没有其他更具体的 URL、remote 配置或地址重写影响目标;这不是忽略全部 Git 配置的开关。
如果单次直连成功,按 --show-origin 找到的真实来源修复失效代理:可能是 Shell 文件、部署服务环境、仓库配置或全局 Git 文件。只修改已经确认有问题的项,记录原值,保留恢复路径。不要删除整个 ~/.gitconfig,也不要清除其他项目还在使用的代理。
如果这台 VPS 必须通过受控代理访问外网,修复代理监听、地址、认证和可信证书;单次直连失败不代表代理配置就是正确的。Git 对代理来源和 URL 级别配置的定义见 git-config 文档。
检查系统时间、发行版的可信 CA 包,以及网络是否经过授权的 TLS 检查代理。若代理使用专用 CA,应从可信管理渠道取得证书,并正确配置系统或 Git 的信任来源。
保留 HTTPS 证书验证。http.sslVerify=false 或 GIT_SSL_NO_VERIFY 会绕过身份验证,不能当作修复。随意往 hosts 文件写一个搜索到的 GitHub IP,也可能导致过期地址、错误网络路径或认证风险。
可以仅对当前命令用 HTTP/1.1 做对照:
git -c http.version=HTTP/1.1 \
ls-remote https://github.com/vercel/next.js.git HEAD
如果对照改善,再核对 Git、libcurl、代理版本和真实目标传输。这个选项不解决 DNS、SSH 认证或仓库权限,也不能保证修复所有 early EOF。不要一遇到 RPC failed 就同时改协议、缓冲大小和 TLS 验证,导致无法判断是哪项生效。
盲目把 http.postBuffer 调到很大,不是 GitHub clone 的通用修复。先依据日志定位连接或传输问题,配置参数用途见 git-config 文档。
可以用以下命令做路径对照:
curl -4 -I --connect-timeout 5 --max-time 15 https://github.com/
ssh -4 -T -o ConnectTimeout=10 [email protected]
如果结果明显不同,继续检查 VPS 的 IPv6 地址、路由与 DNS 结果。不要把一个失败快照当作关闭所有 IPv6 的依据;SSH 与 HTTPS 的测试路径也要分别确认。
Permission denied (publickey) 表示已经走到 SSH 认证,重点检查当前部署用户实际使用的公钥、GitHub 账号或 deploy key,以及 ssh -vT 显示的密钥选择。VPS root 用户、普通部署用户和 CI 服务用户可能各有自己的 SSH 配置。
HTTPS 克隆私有仓库时,GitHub 不使用账号密码作为 Git 操作的认证凭据,应按官方流程使用适当令牌或受支持的凭据工具。Repository not found 既可能是地址写错,也可能是当前账号没有权限;组织 SSO、令牌授权范围和过期状态也可能影响访问。见 GitHub 克隆错误排查。
不要把令牌写进 clone URL、脚本、命令历史或日志。对只需要拉取一个私有仓库的部署场景,可评估权限受限的部署凭据;将实际认证与仓库授权问题修好,再验证目标仓库,不需要为此反复更换网络端口。
先确认卡住的是 Git pack、Git LFS、子模块,还是之后的依赖安装。Git LFS 和子模块可能连接另外的地址,主仓库引用查询成功并不能覆盖它们。
如果部署只需要近期提交,可以按需求使用浅克隆;希望按需获取文件对象时,可评估 partial clone:
git clone --depth 1 https://github.com/OWNER/REPO.git
git clone --filter=blob:none https://github.com/OWNER/REPO.git
这是两种不同选择,不是需要连续执行的两步。浅克隆缺少完整历史,可能影响版本计算、合并或 CI;partial clone 后续 checkout 和其他操作仍可能下载所需对象。用法见 git-clone 文档。它们能减少适合场景下的传输量,但不能修复端口阻断或认证错误。
如果只在特定时段变慢,记录时间、线路与错误,并检查 GitHub 服务状态。不同时间或网络路径的对照有助于区分服务异常、拥堵和本机配置,不必把所有问题都归结为“GitHub 限速”。
先对目标仓库执行只读的 git ls-remote,再在新的目录验证 clone 或受控 fetch,确认预期的提交可获取。不要把测试仓库成功当作私有业务仓库已经恢复,也不要在有未提交修改的生产工作目录里随意 git pull。
CI 或 Coding Agent 仍失败时,在它实际使用的用户、服务或容器环境核对同样的 DNS、代理、密钥和配置。你手动 SSH 登录时的环境,不一定与服务进程继承的环境相同。保留失败信息与修改项;如需详细 trace,先限制日志访问权限,分享前检查并脱敏。
- 域名无法解析:VPS DNS 与 systemd-resolved 排查。
- SSH 主机密钥突然变化:核对指纹与 known_hosts 安全修复。
- Runner 环境与手动登录不同:GitHub Actions 自托管 Runner 部署与隔离。
恢复 GitHub 连接的关键是:确定真实协议和配置,再针对网络、代理或认证修复。确认官方连接路径可用后,再把变更应用到部署环境,才能避免“终端好了,发布仍失败”。
