Published on

macOS 中让 SSH 通过 Clash 代理连接 GitHub

Authors
  • Name
    Twitter

在中国区网络环境下,git clone git@github.com:xxx/xxx.gitssh -T git@github.com 经常会出现连接慢、超时或者握手失败的问题。

如果你的 Mac 上已经在运行 Clash,那么最直接的思路不是“让 Git 单独配代理”,而是让 ssh 本身通过 Clash 提供的本地代理端口发起连接

这篇文章讲的就是这个方案。

1. 先理解问题出在哪里

当我们使用下面这种地址时:

git clone git@github.com:owner/repo.git

底层走的不是 HTTPS,而是 SSH 协议
所以即使你已经给 Git 配过:

git config --global http.proxy http://127.0.0.1:7890
git config --global https.proxy http://127.0.0.1:7890

它也只对 HTTPS 请求有效,对 ssh 本身没有帮助。

也就是说,这个问题的关键不在 Git,而在 SSH。

2. Clash 里我们要用哪个端口

Clash 通常会在本机暴露一个或多个代理端口,最常见的是:

  • 7890:HTTP 代理
  • 7891:SOCKS5 代理

不同客户端版本可能略有不同,但大多数情况下都能在 Clash 的配置页里看到。

对于 ssh 来说,最常见的做法是走 SOCKS5 代理,也就是类似:

127.0.0.1:7891

如果你的 Clash 客户端端口不是这个值,请以你本机实际端口为准。

3. 核心做法:在 ~/.ssh/config 中配置 ProxyCommand

SSH 本身不会直接读取系统代理设置。
想让它通过 Clash 走代理,最常见的方法是使用 ProxyCommand

先打开或者创建这个文件:

vim ~/.ssh/config

加入下面这段:

Host github.com
  HostName github.com
  User git
  Port 22
  ProxyCommand nc -x 127.0.0.1:7891 -X 5 %h %p

这段配置的含义是:

  • 当你连接 github.com
  • 用户名固定使用 git
  • 目标端口是 22
  • 通过本机 127.0.0.1:7891 这个 SOCKS5 代理去转发连接

其中最关键的一行是:

ProxyCommand nc -x 127.0.0.1:7891 -X 5 %h %p

这里:

  • ncnetcat
  • -x 127.0.0.1:7891 表示代理地址
  • -X 5 表示使用 SOCKS5
  • %h %p 表示把当前目标主机和端口传给它

4. 为什么推荐用 ~/.ssh/config

因为它的好处非常明显:

  • 不需要每次手动带参数
  • 只对 github.com 生效,不影响其他 SSH 主机
  • git clonegit pullgit push 都能直接复用

配置好之后,下面这些命令都会自动走 Clash 代理:

ssh -T git@github.com
git clone git@github.com:owner/repo.git
git pull
git push

5. 如果你的网络屏蔽了 22 端口

在一些网络环境下,github.com:22 会被直接干扰。
这时 GitHub 官方还提供了一个专门给 SSH over HTTPS 使用的入口:

ssh.github.com:443

这时可以把配置改成这样:

Host github.com
  HostName ssh.github.com
  User git
  Port 443
  ProxyCommand nc -x 127.0.0.1:7891 -X 5 %h %p

这也是我更推荐中国区用户优先尝试的版本,因为它通常比直连 22 端口更稳定。

6. 一个更稳妥的推荐配置

如果你主要就是为了连 GitHub,建议直接用下面这份:

Host github.com
  HostName ssh.github.com
  User git
  Port 443
  ServerAliveInterval 60
  TCPKeepAlive yes
  ProxyCommand nc -x 127.0.0.1:7891 -X 5 %h %p

这份配置的特点是:

  • 使用 443 端口,兼容性更好
  • 通过 Clash 的本地 SOCKS5 代理转发
  • 增加 keepalive,长连接更稳一些

7. 如何验证是否已经生效

先执行:

ssh -T git@github.com

如果你的 SSH key 和 GitHub 账号已经绑定,通常会看到类似结果:

Hi <your-name>! You've successfully authenticated, but GitHub does not provide shell access.

这说明:

  • 代理链路是通的
  • SSH 握手成功
  • GitHub 认证成功

如果你还想看更详细的调试信息,可以用:

ssh -vT git@github.com

或者:

ssh -vvvT git@github.com

这样能看到 ProxyCommand 是否被执行,以及卡在哪一步。

8. 常见问题

nc: invalid option -- X

这通常说明你当前的 nc 版本参数不兼容。
macOS 自带的 nc 一般支持 -x-X,但如果你装了别的版本,行为可能不同。

这时你可以先运行:

nc -h

确认是否支持:

  • -x
  • -X

如果不支持,可以改用 connect-proxyncat,但对大多数 macOS 用户来说,自带 nc 通常已经够用。

明明 Clash 开着,还是连不上

优先检查这几个点:

  • Clash 的 SOCKS 端口是不是 7891
  • Clash 当前节点是否可用
  • Clash 规则里是否允许 GitHub 走代理
  • 你是不是把 HostName 写成了 github.com 且端口仍然是 22

如果是中国区环境,建议优先尝试:

  • HostName ssh.github.com
  • Port 443

Permission denied (publickey)

这通常不是代理问题,而是 SSH key 认证问题。
需要检查:

  • 本机是否有可用的 SSH key
  • 公钥是否已经添加到 GitHub
  • ssh-agent 是否已经加载对应私钥

9. 可选方案:只在单次命令里临时指定

如果你不想修改 ~/.ssh/config,也可以临时这样执行:

ssh -o 'ProxyCommand=nc -x 127.0.0.1:7891 -X 5 %h %p' -T git@github.com

或者在 clone 时这样写:

GIT_SSH_COMMAND="ssh -o 'ProxyCommand=nc -x 127.0.0.1:7891 -X 5 %h %p'" git clone git@github.com:owner/repo.git

但这种方式更适合临时排查,不如 ~/.ssh/config 长期维护方便。

10. 小结

如果要把这件事压缩成一句话,就是:

ssh 通过 ProxyCommand 把连接转发到 Clash 的本地 SOCKS5 代理端口。

对 macOS 用户来说,最实用的方案通常就是下面这份:

Host github.com
  HostName ssh.github.com
  User git
  Port 443
  ProxyCommand nc -x 127.0.0.1:7891 -X 5 %h %p

配好之后:

  • ssh -T git@github.com
  • git clone
  • git pull
  • git push

都可以直接复用,不需要每次重复设置。