为 Git 配置网络代理

2024-05-11 ⏳2.6分钟(1.0千字) 🕸️

虽然 Git 用得很多,却很少碰到需要为 Git 配置网络代理的场景。最近在跟的项目网络环境比较特别,需要为 Git 配置代理才能访问远端仓库。整理成文,权当备忘。

我司有的系统在公有云,有的系统在自建 IDC 机房。两种环境的安全基线不一致,所以不让在网络层互通。我手上的一个项目就在公有云,而公司的 Git 服务在自建机房,所以没法克隆代码。不过公司在公有云上有一个特殊网段,它可以同时访问其他公有云网段以及 IDC 网络。经过安全评估后,我在该网段内部了一个 socks5 代理服务,来中转 Git 请求。

代理协议分 Socks 代理和 HTTP 代理1。一般来说,下载文件使用 HTTP 协议就够用了。对于 Git 来说,它内部使用 libcurl 下载代码,支持 HTTP 代理。只需要设置 http_proxy/https_proxy 环境变量,Git 就会自动通过代理服务器克隆仓库。用它来加速下载 GitHub 资源非常方便。如果是私有仓库,使用 HTTP 协议需要指定用户名和密码,既不方便,也不安全。使用 SSH 协议可以免密下载,但是 Git 是调用本地 SSH 客户端完成通信,它不支持使用 HTTP 代理,所以我就想到用 Socks 代理。

Socks 代理有 v4 和 v5 两个版本,现在基本都是 v5 版本。网上有很多开源实现。因为 Go 语言交叉编译比较方便,而且编译出的二进制文件没有外部依赖。我就找到了 jqqjj/socks5 项目,安装和使用都很简单:

go install github.com/jqqjj/socks5@master

socks5 -p 1080

我本地是 Mac 环境,服务器是 Linux 系统。交叉编译也很方便,指定 GOOS 环境变量既可:

GOOS=linux go build .

如果你本机的 CPU 架构跟服务器的不同,还需要指定 GOARCH 环境变量,本文不再展开。

最后就是要配置 Git 通过 socks5 协议连接服务器。

与其说是配置 Git,倒不如说是配置 SSH,因为 Git 实际是利用本机的 ssh 客户端来连接服务器。但是 ssh 本身并不支持 socks5 协议,这可怎么办呢?查了一下发现 ssh 支持通过 ProxyCommand 指定代理程序,这比代理协议更加灵活。

我们在 ssh 配置文件 .ssh/config 添加如下内容:

Host git.example.com
  User git
  ProxyCommand nc -x 10.207.0.105:1080 %h %p

这里的配置是告诉 ssh,在访问 git.example.com 域名之前,要先执行 ProxyCommand 指定的程序,这里就是 nc,也就是 netcat 命令。-x 参数指定代理服务器的地址和端口;后面的 %h%p 表示 ssh 要访问的服务器域名和端口。ssh 会运行 nc 命令,然后通过 STDIO 来转发网络数据,这样就实现了让 nc 来代理 ssh 请求的效果。

到这里,我们就能利用 socks5 协议来让 Git 克隆代码了😄

有些系统上的 nc 可能不支持 -x 参数,这是因为安装的不是 openbsd 版的 nc。在 debian 系统上需要安装 netcat-openbsd 包才行。其他环境请读者自行研究。

网上有内容说还需要指定 -X 5 参数,这是为了让 nc 使用 socks5 协议。不指定默认也是 socks5 协议。但如果指定 -X connect,nc 就会使用 HTTP 代理协议发起连接。也就是说,我前面讲的 Git 使用 SSH 克隆代码时不支持 HTTP 代理协议是不对的,两种协议都支持。

以上就是本文的主要内容,欢迎留言讨论。


  1. HTTP 代理协议可以参考 ../https-tunnel.html↩︎