本文档整理 Git 在 HTTP/HTTPS 和 SSH 两种协议下的代理配置方式,以及
nc和ncat在 SSH 代理中的实际差异。写作背景:解决
git push通过 SOCKS5 代理访问 GitHub 时卡住的问题。
1. Git HTTP/HTTPS 代理
Git 本身支持为 HTTP/HTTPS 协议单独配置代理,适用于 git clone、git fetch、git push 等操作。
1.1 全局配置(所有仓库生效)
# 为 GitHub 单独设置 HTTP 代理
git config --global http.https://github.com.proxy http://proxy0.lan:7890
# 为所有 HTTPS 远程仓库设置代理(不推荐,会覆盖特定域名配置)
git config --global http.proxy http://proxy0.lan:7890
1.2 仅当前仓库生效
git config http.https://github.com.proxy http://proxy0.lan:7890
1.3 查看已配置的代理
git config --global --get-regexp proxy
git config --local --get-regexp proxy
1.4 取消代理
git config --global --unset http.https://github.com.proxy
2. Git SSH 代理(~/.ssh/config)
当 Git 远程地址使用 SSH 协议时(例如 git@github.com:user/repo.git),Git 本身不直接处理代理,而是依赖底层 SSH 客户端 的代理能力。
配置方式是在 ~/.ssh/config 中为特定 Host 设置 ProxyCommand。
2.1 基础配置模板
Host github.com
User git
HostName ssh.github.com
ProxyCommand ncat --proxy-type socks5 --proxy proxy0.lan:7890 %h %p
参数说明:
| 参数 | 含义 |
|---|---|
%h | SSH 配置中的 HostName(此处为 ssh.github.com) |
%p | 端口(此处为 22) |
2.2 为什么推荐使用 ncat 而不是 nc
在实际排查中发现,使用 OpenBSD nc 作为 SOCKS5 代理时存在一个隐蔽问题:
当远程服务器(GitHub)完成数据传输并关闭连接后,
nc不会自动退出,导致 SSH 会话一直挂起,git push进程卡住。
两种工具对比
| 特性 | nc (OpenBSD netcat) | ncat (nmap) |
|---|---|---|
| SOCKS5 代理 | -x proxy:port | --proxy-type socks5 --proxy proxy:port |
| 连接关闭后自动退出 | ❌ 不会自动退出(除非 stdin 收到 EOF) | ✅ 会正确退出 |
git push 体验 | 容易卡住 | 正常 |
| 安装 | 系统自带 | 通常需要单独安装(apt install nmap / brew install nmap) |
如果必须使用 nc 该怎么配置
如果环境里没有 ncat,只能使用系统自带的 nc(OpenBSD netcat),需要注意以下问题:
nc 的核心问题:OpenBSD nc 在 SOCKS5 代理模式下,只有在 stdin 收到 EOF 后才会退出。而 git push 与 SSH 之间的管道交互比较复杂,nc 的 stdin 往往无法及时收到 EOF,导致连接完成后进程挂起。
nc 可用参数说明:
| 参数 | 作用 | 对 git push 是否有效 |
|---|---|---|
-q 0 | stdin EOF 后立即退出 | ⚠️ 部分有效,手动测试 SSH 命令时有效,但 git push 场景下仍可能卡住 |
-N | stdin EOF 后关闭网络 socket | ❌ 无法解决 nc 本身不退出问题 |
-w <秒> | 连接空闲 N 秒后强制关闭 | ⚠️ 有风险,若大数据传输期间空闲超时会中断 push |
nc 配置 SOCKS5 代理:
# ⚠️ 能用,但 git push 完成后有几率卡住,不推荐生产环境使用
Host github.com
ProxyCommand nc -q 0 -x proxy0.lan:7890 %h %p
nc 配置 HTTP CONNECT 代理:
如果代理提供的是 HTTP CONNECT 隧道(而非 SOCKS5),需要显式指定 -X connect:
# ⚠️ 同样存在连接完成后卡住的风险
Host github.com
ProxyCommand nc -q 0 -X connect -x proxy0.lan:7890 %h %p
注意:OpenBSD
nc不支持 HTTP 代理认证。如果代理需要用户名密码,只能使用ncat(支持--proxy-auth)或socat。
如果 -q 0 在你环境中仍然卡住,唯一的稳妥方案就是换用 ncat 或 socat:
# ✅ 使用 ncat(最推荐)
Host github.com
ProxyCommand ncat --proxy-type socks5 --proxy proxy0.lan:7890 %h %p
# ✅ 使用 socat(备选)
Host github.com
ProxyCommand socat - PROXY:proxy0.lan:%h:%p,proxyport=7890,proxyproto=socks5
3. 常见问题排查
3.1 git push 卡住 / 无响应
排查步骤:
确认是 SSH 还是 HTTP 协议
git remote -vgit@github.com:...→ SSH 协议,问题在~/.ssh/confighttps://github.com/...→ HTTP 协议,问题在git config代理
测试 SSH 连通性
ssh -T git@github.com如果也卡住,说明 SSH 代理配置有问题。
测试代理命令本身
# 测试 ncat SOCKS5 代理通道
ncat --proxy-type socks5 --proxy proxy0.lan:7890 ssh.github.com 22
# 测试 ncat HTTP CONNECT 代理通道
ncat --proxy-type http --proxy proxy0.lan:7890 ssh.github.com 22
# 测试 nc HTTP CONNECT 代理通道
nc -X connect -x proxy0.lan:7890 ssh.github.com 22如果成功,会收到 GitHub 的 SSH banner:
SSH-2.0-...检查 SSH 配置是否被注释掉
cat ~/.ssh/config | grep -A 4 "Host github.com"使用 GIT_TRACE 查看 git 内部执行过程
GIT_TRACE=1 git push
GIT_TRACE_PACKET=1 git push
3.2 代理服务器不通
# 测试代理端口是否开放
nc -z proxy0.lan 7890
# 或
timeout 3 bash -c 'nc -x proxy0.lan:7890 ssh.github.com 22 < /dev/null'
4. 完整配置示例
假设代理服务器为 proxy0.lan:7890(HTTP & SOCKS5 混合端口):
~/.ssh/config
Host github.com
User git
HostName ssh.github.com
ProxyCommand ncat --proxy-type socks5 --proxy proxy0.lan:7890 %h %p
Git 全局配置
git config --global http.https://github.com.proxy http://proxy0.lan:7890
git config --global http.https://huggingface.co.proxy http://proxy0.lan:7890
5. 总结
| 场景 | 配置位置 | 推荐工具 / 命令 |
|---|---|---|
| Git HTTP/HTTPS 代理 | git config | 直接填 HTTP 代理地址 |
| Git SSH + SOCKS5 代理 | ~/.ssh/config + ProxyCommand | ncat --proxy-type socks5(首选) |
| Git SSH + HTTP CONNECT 代理 | ~/.ssh/config + ProxyCommand | ncat --proxy-type http(支持认证) |
| Git SSH 代理(无 ncat) | ~/.ssh/config + ProxyCommand | nc -X connect -x ...(有卡住风险) |
核心建议:如果通过 SOCKS5 代理访问 GitHub SSH,**请使用 ncat 替代 nc**,可以避免 git push 完成后进程卡死的隐患。
如果受限于环境只能使用 nc,可以尝试加上 -q 0,但要了解它在 git push 场景下仍有几率卡住,需要做好随时切到 ncat 或 socat 的准备。