用GitHub 的人几乎都撞到过这样一幕git push正推得起劲屏幕上突然砸下来一行红色报错大意是fatal: unable to access https://github.com/xxx/xxx.git/: Failed to connect to github.com port 443: Connection refused。第一次遇到的人多少有点慌以为是自己的代码仓库没了或者是电脑坏了。其实都不用慌443 这个报错在 GitHub 的使用过程中实在太常见了它往往不是你仓库的问题而是你的网络到 GitHub 服务器之间某个环节出了问题。443 是 HTTPS 默认的服务端口GitHub 的网页、API、HTTPS 方式克隆和推送全都走这个端口。换句话说只要这个端口上的 TCP 连接建不起来或者建起来之后 TLS 握手失败你看到的就是各种各样的 443 报错。这篇文章我会把手头积累的排查经验拆开讲报错到底卡在哪一层、先用哪几条命令定位、常见的几个坑在哪里、最后再给你一套可以照着做的处理顺序。不管你是刚碰 GitHub 的新手还是已经被 443 折磨过几次的老手按着这篇文章走至少能让你在下一次遇到报错的时候不至于对着屏幕干瞪眼。1. 先别急着改配置443 报错到底卡在哪一层1.1 443 不是玄学它是 HTTPS 的默认大门很多同学一看到 443 就头大下意识觉得是网络被墙了或者服务器挂了。其实 443 这个数字本身只是一个端口号就像一台服务器开了一扇门HTTPS 请求都得从这扇门进去。你的电脑要和 GitHub 通信需要完成这样几步先通过 DNS 查到 GitHub 服务器的 IP 地址然后从你的电脑到这个 IP 的 443 端口建立一条 TCP 连接连接建立之后再做 TLS 加密握手最后才传输 HTTP 数据。这四步里任何一步出问题你看到的报错文案都会不一样。有的是Connection refused说明连接被直接拒绝了有的是Connection timed out说明数据包发出去了但一直没回应还有的是SSL connect error说明 TCP 连上了但加密握手没谈拢。理解了这一层你就知道为什么网上那么多解决办法有些对你有效、有些完全没用——因为你们卡住的层可能根本不一样。1.2 三种常见报错形态对应三种不同的故障层我整理了实际工作中最常碰到的三类 443 报错以及它们背后的含义报错特征问题大概率出在Failed to connect to github.com port 443: Connection refused本地出口到 GitHub 443 端口的链路不通或者本地网络设备把请求拦了Failed to connect to github.com port 443: Connection timed out网络寻址或路由质量差DNS 解析异常、网络延迟过高都有可能导致SSL connect error或OpenSSL SSL_read: Connection reset by peer, errno 104TCP 能连上但 TLS 握手阶段失败常见于证书链、系统时间、HTTP/2 协议等问题你可以把这三类理解成寄快递的三个环节第一类是快递柜的柜门坏了根本投不进去第二类是快递员找不到地址在楼下绕圈第三类是快递柜门能开但你填的收件人信息和柜子里的标签对不上。这三种情况对应的处理方式完全不同所以拿到报错先看一眼它属于哪一种比直接搜终极解决办法要高效得多。1.3 排查心法本地优先、简单优先、验证优先我踩过无数次坑之后总结出来的排查顺序很简单先换网络再查本地最后才动配置。很多人一上来就改 Git 的全局配置或者折腾 hosts 文件结果问题不但没解决反而把原本好用的环境改乱了。正确的打开方式是先用自己的手机热点试一次如果热点能通说明你当前所在网络的出口有问题如果热点也不通再看是不是本地 DNS、Git 配置、SSL 证书这些环节。每做一步修改就重新跑一次最简单的访问命令来验证比如curl -I https://github.com。一次只改一个变量改了立刻验证这是排查网络问题最不容易把自己绕晕的方法。2. 3 分钟自查清单先跑这几条命令再动手2.1 用 curl 验证最原始的 HTTPS 链路是否通畅不管报错文案多花哨第一步我都建议先做一次最干净的 HTTPS 请求测试。打开终端执行curl -I https://github.com你可能会看到两种结果。一种是HTTP/2 200或者HTTP/1.1 200 OK之类的响应说明你的网络到 GitHub 443 端口是通的问题大概率出在 Git 客户端的配置或者具体仓库的 URL 上。另一种是直接超时、拒绝连接或者证书报错那就说明问题在更基础的网络层。这一步看起来简单但意义很大。因为它绕开了 Git 的所有配置直接用系统自带的网络工具去访问 GitHub。如果 curl 都通不了那改 Git 配置是没用的如果 curl 是通的你再回头看 Git 的报错方向就完全不一样了。2.2 用 git 命令定位到具体仓库的访问链路curl 通过之后再用 Git 自己测一次远程仓库的连通性。比如你有一个仓库地址是https://github.com/某用户/某项目.git执行git ls-remote https://github.com/某用户/某项目.git这个命令的作用是列出远程仓库的分支引用整个过程会走一次真实的 HTTPS 访问但不修改你本地任何文件。如果它能列出refs/heads/main之类的内容说明 Git 走 HTTPS 访问仓库的能力是正常的后面 push 或 clone 报错的原因就要往具体仓库目录、本地 .git 状态、大文件传输这些方向去想。如果这个命令也报 443那就继续往下排查。2.3 端口探测与网络切换对比做完上面两步再做一个端口级的探测确认 443 端口连通性nc -vz github.com 443如果系统没有nc可以用telnet github.com 443连上之后屏幕上会提示连接成功直接输入quit退出。这一步能验证 TCP 层是否通和 curl 的区别在于它不发送 HTTPS 请求只看端口能不能连。拿到结果之后再做一次换网络的对比测试。用手机开热点让电脑连上热点后再跑一遍curl -I https://github.com。如果热点能通那就是你所在网络环境的出口问题如果热点也不通可以把嫌疑范围锁定在本地设备本身。这一步几乎不花时间但能帮你砍掉一半的排查方向。3. DNS 解析异常九成 443 报错的隐形元凶3.1 为什么 DNS 问题会被误认为网络断了我处理过的 443 报错里十次有七八次最后都指向 DNS 解析异常。DNS 的作用是把github.com这样的域名翻译成服务器实际的 IP 地址。如果解析出来的 IP 是不存在的、过期很久的或者解析本身就超时那你的请求根本找不到 GitHub 的门在哪表现就是连接超时。这里有个特别坑的地方网上很多东西会告诉你GitHub 某个 IP 永远能用然后让你直接写进 hosts 文件里。但 GitHub 的 IP 不是一成不变的不同地区、不同时间的解析结果可能都不一样。你照抄了一个别人几个月前的 IP当时可能有效现在可能已经失效了反而会让问题更加扑朔迷离。所以遇到 443第一件事不是看网上的教程而是先看你本地到底把 GitHub 解析到了哪个 IP。执行nslookup github.com或者ping github.com要注意ping走的是 ICMP 协议和 HTTPS 的 443 端口不是一回事。有些环境下ping能通但 443 端口不通也有反过来ping不通但 curl 正常的情况。所以ping只能作为参考别把它当成唯一标准。真正要看的是nslookup返回的 IP 地址列表以及解析耗时。3.2 三步紧急修复取 IP、写 hosts、清缓存如果确认 DNS 解析出来的结果有问题可以按下面三步做紧急处理第一步通过多个公开的解析渠道查询 GitHub 当前可用的 IP。直接用你本地默认的 DNS 查一次再用公共 DNS 的地址解析一次对比一下结果是不是一样。公共解析服务可以用223.5.5.5或者119.29.29.29这些在国内访问都比较快。如果不同渠道查出来的 IP 差异很大说明本地 DNS 缓存或者运营商 DNS 可能存在问题。第二步把你确认能用的 IP 写进系统 hosts 文件绕过 DNS 解析的过程。hosts 文件的路径在 Windows 是C:\Windows\System32\drivers\etc\hosts在 macOS 和 Linux 是/etc/hosts。写入的格式是 IP 地址在前、域名在后中间用空格隔开一行一个域名。建议把github.com和www.github.com都写上示例140.82.112.3 github.com 140.82.112.3 www.github.com注意上面 IP 只是格式示例千万不要照抄一定要用你自己查询确认过的结果。不同网络环境下能用的 IP 可能完全不同照抄旧 IP 是我见过最多人踩的坑。第三步刷新本地 DNS 缓存让 hosts 文件的修改立即生效。Windows 执行ipconfig /flushdnsmacOS 执行sudo dscacheutil -flushcacheLinux 上不同发行版命令不一样常见的是sudo systemd-resolve --flush-caches如果提示命令不存在可以尝试sudo resolvectl flush-caches。3.3 hosts 文件怎么维护才不会越修越乱hosts 文件是个好东西但它也是一把双刃剑。我见过很多人的 hosts 文件里堆了十几个网上找到的 GitHub IP五花八门有的早就不通了还夹杂着各种注释看都看不懂。这种文件不但解决不了问题反而会干扰后续排查。维护 hosts 文件就记住三个原则。第一写清楚注释每一行后面用#注明是什么时候、因为什么原因加进去的比如140.82.112.3 github.com # 2024-06-01 备用。第二保持精简只写真正需要的域名不要一口气加几十个。第三定时复查过一段时间就删掉 hosts 里的 GitHub 相关行重新走一遍正常 DNS 解析如果已经恢复正常就不要再保留这些人为指定了。3.4 更省心的长期方案切换公共 DNS如果频繁出现 DNS 解析异常我的建议是从根上换掉本地默认的 DNS 设置。很多人用的是运营商自动分配的上网 DNS解析速度和质量不一定好。可以在系统网络设置里手动指定一组公共 DNS 地址比如223.5.5.5和119.29.29.29。切换之后记得再跑一遍curl -I https://github.com验证效果。如果解析恢复正常说明问题确实出在默认 DNS 上。这种方式比维护 hosts 文件更省心因为 DNS 服务器会自动更新解析记录你不用手动追踪 IP 的变化。我自己的电脑长期就是用手动指定的公共 DNS遇到 GitHub 443 的概率明显下降。4. Git 自身配置与 TLS 层问题连上了却握不上手4.1 检查 Git 历史遗留的全局配置很多时候你的网络是通的curl 也正常但 Git 一跑就报 443 错。这时候就要怀疑 Git 自己的配置是不是有问题。执行git config --global --list把输出内容看一遍重点看有没有http.开头的配置项。如果你从来没有手动配过这些项这里应该是空的。一旦看到很多http.开头的自定义项就要想想是不是之前为了某个特定场景手动设置过比如调整过 SSL 校验方式或者设置过转发的网关参数。这些配置在当前网络环境下可能已经失效反而成了阻碍。处理的方法是先备份再逐项删除可疑项。备份可以直接把~/.gitconfig文件复制一份到别的地方然后针对可疑项执行git config --global --unset 配置项名称每删一项就跑一次git ls-remote验证直到恢复通畅。这里我特别想提醒一句不要为了图省事把整个.gitconfig删掉重来因为你里面可能还留着用户名、邮箱、别名等有用的设置删了之后一堆东西要重新配。4.2 SSL 证书验证失败三查时间、证书链、Git 版本如果报错信息里带SSL certificate problem或者SSL connect error那问题就从连不上变成了握不上手。SSL/TLS 握手的时候你的电脑会验证 GitHub 服务器的证书是不是合法、是不是过期、签发链是不是完整。这一关挂掉常见原因有三个。第一个是系统时间不对。证书的有效期是限定的如果你的电脑时间比真实时间偏了好几天证书验证就会直接失败。这种问题在电脑长期休眠、主板电池没电的机器上特别常见。打开系统设置看一眼时间校对一下再试。第二个是证书链不完整。有些企业内网或者特殊环境下系统里缺少必要的根证书导致 GitHub 的证书链验证不通过。这种情况可以检查一下系统是否更新了最新的根证书包macOS 用户看看钥匙串访问里有没有对应的证书Windows 用户检查一下系统更新。第三个是 Git 版本太旧旧版本的 Git 内置的证书库可能不识别新的证书签发方。执行git --version看看版本号如果版本比较老建议直接升级到新版本。这里有一条红线要划清楚网上很多人遇到 SSL 证书报错就直接建议git config --global http.sslVerify false关掉验证我强烈不建议这么干。关掉验证意味着你不再确认对方服务器的身份中间有任何设备伪造证书你都不知情这在安全性上是把自己完全暴露了。关验证只能作为临时测试手段测完一定要恢复。4.3 HTTP/2 协议惹的祸一条配置切换回 HTTP/1.1Git 在较新版本里默认使用 HTTP/2 协议和服务器通信。HTTP/2 本身效率更高但它在某些网络设备、防火墙或者旧版 Git 的组合下会出现一个很经典的问题连接能建立请求也发出去了但服务器返回数据的一瞬间连接被重置报错东西类似OpenSSL SSL_read: Connection reset by peer, errno 104。遇到这种报错可以先怀疑是 HTTP/2 协商出了问题。把 Git 的 HTTP 协议版本强制切回 HTTP/1.1git config --global http.version HTTP/1.1这是个很安全的配置改动它只是让 Git 用老版本的 HTTP 协议不涉及任何安全风险。改完之后重新跑一次git ls-remote大概率能看到报错消失。等确认没问题之后可以留着这个配置它对你的日常操作几乎没影响只是少了一点点性能优势。4.4 大仓库推送失败postBuffer 与超时参数的调优443 报错还有一种典型场景不是连不上而是传着传着就断了。尤其是推大仓库、传大文件的时候报错信息里经常带RPC failed; curl 18 transfer closed with outstanding read data remaining。这往往是因为 Git 默认的 HTTP 缓冲区不够大或者网络稍有延迟就超时。针对这类问题有两个参数很管用。一个是调大 HTTP 缓冲git config --global http.postBuffer 524288000这个值的单位是字节524288000 就是 500MB。原理是让 Git 在上传大对象时分块更从容避免一次发送太多数据被网络设备掐断。另一个是放宽低速限制git config --global http.lowSpeedLimit 0 git config --global http.lowSpeedTime 999999Git 默认在传输速度低于某个阈值并持续一段时间后会主动断开连接。上面这两条配置相当于告诉 Git别因为慢就掐断我在弱网环境下尤其有效。不过要注意这些只是权衡方案如果你要推的仓库有好几个 GB更好的做法是考虑用 SSH 通道或者把大文件交给专门的大文件存储方案而不是让 Git 硬扛。5. 走备线SSH 443 端口与仓库自救方案5.1 用官方支持的 SSH 443 通道作为备选接入如果 HTTPS 的 443 端口在当前网络环境下怎么都不通还有一条官方支持的备选接入方式用 SSH 协议走 443 端口。默认情况下 SSH 走 22 端口但 GitHub 官方提供了一个特殊的 SSH 服务地址ssh.github.com专门监听 443 端口。先测试一下这条通道通不通ssh -T -p 443 gitssh.github.com如果返回Hi 用户名! Youve successfully authenticated说明这条通道可用。接下来把它写进 SSH 配置文件让以后访问 GitHub 都走这条线路。编辑~/.ssh/config加入这样一段Host github.com HostName ssh.github.com Port 443 User git保存之后测试一下正常的 SSH 连接ssh -T gitgithub.com同样能收到成功的提示就说明配置生效了。之后你把远程仓库地址改成 SSH 格式比如gitgithub.com:某用户/某项目.git就能在这个网络环境下顺畅推拉。这里要提醒一句使用 SSH 需要你提前在 GitHub 账号里配置过公钥如果没配过得先去生成密钥对、把公钥添加到账号里这部分内容 GitHub 官方文档写得很清楚。5.2 浅克隆与大仓库断续拉取技巧还有一种经常被忽略的自救方案是针对仓库太大、历史太深导致 443 拉取失败的场景。当你 clone 一个超大仓库时Git 要下载全部历史对象一旦中间断网或超时整个克隆就失败了。这时候可以改用浅克隆先只拉最近一次提交git clone --depth 1 https://github.com/某用户/某项目.git浅克隆之后仓库体积会小很多网络压力也小很多。如果你后续需要完整历史可以再手动加深历史git fetch --unshallow如果仓库实在太大--unshallow也会很吃力那就按需加深比如把历史加深到最近 20 次提交git fetch --depth 20这个思路的核心是先让自己能干活再去补齐历史而不是一次拉到位。我遇到超大仓库的 443 超时几乎都是用这套方法救回来的。5.3 .git 目录异常自救锁文件与对象损坏有时候 443 报错只是表象真正的根因在本地.git目录已经处于一个不健康的状态。最常见的两种情况是存在锁文件和对象损坏。如果你执行 Git 命令时提示Unable to create .git/index.lock: File exists说明上一次 Git 操作异常中断留下了一个锁文件。处理方式是在确定没有其他 Git 进程运行的前提下手动删除这个文件rm .git/index.lock注意一定要确认没有正在跑的 Git 进程才删否则可能损坏仓库状态。另一种情况是提示对象损坏或者.git/objects里的文件不完整可以先运行完整性检查git fsck --full如果报告有损坏对象而且你本地有未推送的提交先想办法把提交备份出来。如果没有未推送的重要提交最省事的办法是从远端重新拉一份干净的副本把本地有问题的目录删掉重来。不要试图手动去改.git/objects里面的文件那是拿着手术刀给心脏做手术风险远大于收益。6. 常见问题速查表与我的踩坑记录6.1 一张表搞定常见 443 报错场景为了让你以后遇到问题能对号入座我把常见场景整理成一张速查表报错特征最可能原因第一步动作Failed to connect to github.com port 443: Connection refused本地到 443 端口链路不通换手机热点测试再查 hosts 与 Git 配置Failed to connect to github.com port 443: Connection timed outDNS 解析异常或网络质量差刷新 DNS 缓存切换公共 DNS对比多个解析结果SSL connect error或certificate verify failedTLS 握手阶段失败检查系统时间、证书链、Git 版本OpenSSL SSL_read: Connection reset by peer, errno 104HTTP/2 协商被网络设备重置设置http.version HTTP/1.1后重试RPC failed; curl 18 transfer closed大仓库传输超时或被中断调大http.postBuffer放宽低速限制unable to access ... 403仓库不存在或权限不足检查仓库 URL、账号权限、凭据是否正确这张表覆盖了我日常排障中九成以上的情况。真正需要花时间深挖的往往是那些做了三四项测试还找不到问题所在的个例那时候就需要结合系统日志和抓包工具再分析了。6.2 我踩过的三个坑DNS 缓存、配置残留、IP 过期第一个坑是刚改完 hosts 文件就以为万事大吉结果忘了刷新 DNS 缓存导致实测还是旧 IP。后来我养成了习惯每次改完 hosts 立即执行刷新命令然后重新跑 curl 验证再往下推进。第二个坑是 Git 全局配置里的残留项。有一阵子我的 Git 访问特别诡异同一个仓库有时候能连有时候不能连折腾了半天才发现是早期为了某次测试手动加过几个http.开头的参数一直没清理。那次之后我给自己立了条规矩每过几个月看一眼git config --global --list但凡看到不认识的参数问一句这个参数是怎么来的、现在还需要吗不然就删。第三个坑是照着网上的万能 IP写 hosts。有一回我复制了一组网上流传的 GitHub IP当时确实通了但过了一段时间又不行了排查之后发现那组 IP 早就变了。现在我宁可让正常 DNS 去解析也尽量少碰 hosts 文件除非真的走投无路而且每次用之前都必须自己多渠道验证。我的一点小建议是在使用别人的方案前先想清楚它解决的是 DNS 层、TLS 层还是 Git 配置层的问题对症下药才是最快的路径。6.3 给团队的一键自查方案如果是团队协作时有人频繁遇到 443 报错我的建议是把上面这些排查步骤整理成一段简单脚本放到团队的共享文档里。脚本的核心内容是跑几条命令、给出判断建议让新手也能照着做。echo 1. 测试 HTTPS 基础链路 curl -I https://github.com echo 2. 查看 GitHub 当前解析 IP nslookup github.com echo 3. 查看 Git 全局配置中的 http 相关项 git config --global --get-regexp ^http\. echo 4. 测试 SSH 443 备线 ssh -T -p 443 gitssh.github.com让遇到问题的人先跑一遍这段脚本把输出贴回来有经验的人一看就能判断问题在哪一层不用再隔着屏幕反复问你报错信息是什么。写到现在我想把整个排查思路浓缩成一句我自己的操作准则遇到 443 报错先做链路验证再查 DNS 解析最后动 Git 配置。这三步不会让你踩太多弯路。一次解决不了就换网络再验一次很多时候重启一下手机热点换一个 DNS就能解决根本不用上升到改什么高级配置的程度。这些方法看似基础但恰恰是它们帮我处理了绝大多数 GitHub 访问问题希望你也能用上。
阅读完成 · 觉得有帮助?