git 连接被拒速查:ssh connect to host 的六个根因与处置
更新时间:2026-10-24。FAQ 速查页,面向
git clone/git pull/git push时被ssh: connect to host git.example.com port 22: Connection refused或Failed to connect to ... port 443一句话挡住的同学。git 连接被拒的含义一句话:TCP 三次握手都没完成——包到了对端但被拒收(对端明确回 RST),或根本没到(超时是被丢包,措辞不同)。refused 说明网络层通、但目标端口上没有服务在听,或被中间设备主动拦下。收敛在六根轴上:远端 sshd/服务没起或崩溃、端口拼错或服务监听非标端口、本机/公司代理拒绝转发、防火墙与安全组拦端口、地址或协议拼错、以及 HTTPS 443 被封后的协议切换。本篇主线工具是ssh -vT与nc -vz——把 git 层剥掉直接验网络层,是这类报错的第一处置手段。
本文要回答的问题
Connection refused和Connection timed out的区别是什么?- 浏览器能打开网站,为什么 git 还是连不上?
- 怎么确认是本机问题、网络问题还是服务器问题?
- 公司代理下 git 要怎么配才能通?
- 22 端口被封,还能不能用 SSH 协议拉代码?
一、报错原文与典型现象
git 连接被拒家族的真实措辞如下(路径以 /proj/demo 占位,远端以 git.example.com 占位):
$ git clone git@git.example.com:group/demo.git /proj/demo
Cloning into '/proj/demo'...
ssh: connect to host git.example.com port 22: Connection refused
fatal: Could not read from remote repository.$ git clone https://git.example.com/group/demo.git /proj/demo
Cloning into '/proj/demo'...
fatal: unable to access 'https://git.example.com/group/demo.git/': Failed to connect to git.example.com port 443 after 75 ms: Connection refused$ ssh -T git@git.example.com
ssh: connect to host git.example.com port 22: Connection refused$ git -C /proj/demo pull
ssh: connect to host git.example.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.读报错抓三个信号:Connection refused 是对端明确拒收——路由通、端口没服务,或被防火墙回 RST 伪装成拒绝;Connection timed out 是包被静默丢弃——防火墙 DROP 策略的典型表现;after 75 ms 这种极短时间内的 refused 多半是本地代理或本机配置问题(这么快不可能是跨网往返)。先分清 refused 还是 timeout,排查方向完全不同。顺带一句: refused 与认证无关——还没到验身份的环节就死了,认证类报错见 git 认证失败速查。
二、病因处置速查表
| 报错现象 / 场景 | 可能原因 | 快速验证 | 处置 |
|---|---|---|---|
| 所有人都连不上自建 Git 服务 | sshd 或 Gitea/GitLab 服务没起 | 服务器上 systemctl status sshd | 拉起服务并设开机自启 |
| 只有这台机器 refused | 本机出站被拦或代理配置错 | nc -vz git.example.com 22 | 修代理或放行出站规则 |
| 提示 port 22 refused 但服务在别的端口 | 服务监听非标端口 | ssh -vT -p 2222 git@git.example.com | ~/.ssh/config 配 Port 字段 |
| 公司网 refused、家里正常 | 公司防火墙拦 22 出站 | 换手机热点重试即验证 | 改用 HTTPS 或 443 上的 SSH |
| 浏览器能开网页、git refused | 页面走了代理、git 没走 | git config --get http.proxy 无输出 | 配 http.proxy 或 ~/.ssh/config 的 ProxyCommand |
| ping 通但端口 refused | 端口级拦截或服务只监听特定网卡 | nc -vz 精确验端口 | 查服务 bind 地址与安全组 |
| 域名解析到错误地址 | hosts 残留或 DNS 污染 | getent hosts git.example.com | 清 hosts 残留、换 DNS |
| 443 也被 refused | 中间设备全网拦 Git 服务 | 同网络其他服务验证 | 走备用镜像或合法合规的网络方案 |
三、排查决策图
下面这张图是标准排查路线,颜色按角色区分:红是报错入口与命中的根因,蓝是排查动作,绿是通过分支,橙是修复动作,紫是防复发沉淀。
读这张图抓主线顺序:第一步永远是把 git 层剥掉——ssh -vT git@git.example.com 与 nc -vz git.example.com 22 直接验传输层,git 报错的措辞在传输层报错面前没有额外信息。第二步定界:换手机热点能通 = 公司网络拦;同机其他服务能通、只有这个端口不通 = 端口级问题;谁都不通 = 服务端挂了。九成 case 在这两步收敛,剩下的一成才轮到服务端配置细节。
四、逐条排查展开
第一条:远端服务没起——自建 Git 服务的最常见根因。 自己维护的 Gitea/GitLab/裸 sshd,机器重启后服务没自启、或进程崩溃,端口上没人听,客户端拿到的就是 refused。服务器上验证:
systemctl status sshd # 或 gitea / gitlab
ss -tlnp | grep ':22' # 确认端口确实在听处置:拉起服务、systemctl enable 设开机自启。验证端口在听但客户端仍 refused 时,接着查服务 bind 的网卡——只监听内网网卡时外网永远 refused。服务能起但握手后立刻断(kex_exchange_identification 报错)是另一个家族,见 git clone 卡死超时速查。
第二条:端口拼错或非标端口。 很多自建服务把 SSH 挪到 2222 等端口躲扫描,git 默认敲 22 自然被拒。验证:
ssh -vT -p 2222 git@git.example.com
nc -vz git.example.com 2222处置:在 ~/.ssh/config 里固化,以后所有 git 命令自动走对端口:
Host git.example.com
Port 2222
User git注意 remote URL 里写死的端口(ssh://git@git.example.com:2222/...)与 config 并存时以 URL 为准,两处别打架。
第三条:本机出站或代理拦截。 公司网络常见:出口防火墙拦 22 出站,或本机配了代理但代理本身拒绝转发。定界方法极简单——切手机热点重试,能通就是公司网络拦。代理环境下 SSH 协议要在 ~/.ssh/config 配 ProxyCommand,HTTPS 协议配 git 自己的 proxy:
git config --global http.proxy http://<代理地址>:<端口>
# SSH 走代理则在 ~/.ssh/config 加:
# ProxyCommand nc -X connect -x <代理地址>:<端口> %h %p配错代理(地址错、代理没起)时 refused 来得极快(毫秒级),这是识别「死在本地代理」的信号。
第四条:防火墙与安全组拦端口。 云主机安全组没放行 22/443 入站、或服务器本地 iptables 有 DROP 规则。refused 与 timeout 在这里分叉:REJECT 规则回 RST 表现为 refused,DROP 规则静默丢包表现为 timeout(timeout 家族的完整排查见 git clone 卡死超时速查)。处置:云平台控制台查安全组入站规则,服务器上 iptables -L -n 或 nft list ruleset 查本地防火墙,逐条对照端口与来源网段。
第五条:地址拼错或协议搞混。 域名拼错一个字母、把 git.example.com 写成内网短名、或拿着 SSH 路径用 HTTPS 协议敲。验证链路:
getent hosts git.example.com # 解析到哪个地址
git -C /proj/demo remote -v # 当前 remote 到底指哪getent 解出一个陌生地址时查 ~/.ssh/config 的 HostName 改写与 /etc/hosts 残留——hosts 里一条过期映射能把流量引到一台早下线的老机器上,表现为稳定的 refused。改对后 git remote set-url origin 固化。
第六条:443 也被拦时的协议与通道切换。 有些网络环境对 Git 服务特征做全网拦截,22 和 443 都 refused。两条合规出路:其一,很多代码平台支持「SSH over 443」(如 ssh.github.com 的 443 端口),~/.ssh/config 里给对应 Host 配 Port 443 与专用 Hostname 即可;其二,用平台提供的备用镜像域名。换通道后第一件事是重验 ssh -T,确认通的是真服务而不是拦截页面的伪装——伪装表现为握手成功但认证阶段报错,那就转去 git 认证失败速查 继续排。
五、规范做法与预防
- 端口与代理固化进 ssh config:非标端口、ProxyCommand 写进
~/.ssh/config,不依赖记忆与临时命令行参数,换工具(git/ssh/rsync)全生效。 - 自建服务开机自启加存活监控:
systemctl enable之外,给 22/443 加端口存活探测,服务挂了先于用户发现。 - 安全组最小放行:入站只放必要端口与必要来源网段,规则变更留评审记录——「安全组谁改挂了」是团队环境的高发事故。
- 远程操作前验通再验权:
ssh -vT通(传输层)→ 认证过(权限层)→ 再跑 git,三段分开验,报错定位不串层。 - 文档化网络要求:团队 Wiki 写明「访问代码服务需要哪些端口/代理」,新人撞墙先查文档再提工单。
这一篇在知识体系里的位置
本篇是 Git 排错速查簇的网络连通篇,定位「TCP 层连不上远端」:连上但握手挂住看 git clone 卡死超时速查;连上但认证不过看 git 认证失败速查 与 git 权限拒绝速查;推送阶段被拒看 git push rejected 速查;本批同簇的还有 remote 与分支重名冲突速查 和 submodule 没拉下来速查;远端操作的基础用法见 remote、pull、push 与 config、init、clone。
一句话总结
git 连接被拒的本质是「TCP 握手没完成,问题在传输层而不在 git」:先 ssh -vT 与 nc -vz 剥掉 git 层直验端口,再按「本机/网络/服务端」三层定界——服务端没起就拉服务,端口拼错就在 ~/.ssh/config 固化 Port,公司网拦 22 就切手机热点验证后改走代理或 SSH over 443,防火墙问题对照安全组与 iptables。端口代理写进 ssh config、服务加存活监控、验通再验权分三段,这类报错基本绝迹。