开发者
Mac 上 SSH 和 Git 超时
SSH 和 Git 需要与服务器之间有可用的 TCP 连接。网络屏蔽端口 22、IPv6 路径不通或代理,都可能让它们连不上。
症状
git push或git clone等待一段时间后显示“Operation timed out”。ssh在某个网络上显示“Connection timed out”,在另一个网络上却正常。- SSH 会话空闲几分钟后就卡住不动。
- HTTPS 形式的 Git 远程仓库正常,SSH 形式的却不行。
可能的原因
- 端口 22 被屏蔽。一些公司、酒店和公共网络会屏蔽 SSH。GitHub 表示,防火墙有时会拒绝 SSH 连接。
- IPv6 路径不通。Mac 会先尝试 IPv6。如果 IPv6 不可用,连接就会一直等待。
- 空闲连接被关闭。路由器或防火墙可能会断开一段时间内没有传输数据的连接。
- 需要代理。在公司网络上,HTTPS 方式的 Git 可能需要
http.proxy或代理环境变量。
如何检查
以详细输出模式连接。最后几行会显示连接停在哪一步。
ssh -vT git@github.com单独测试 TCP 端口,超时时间设为 5 秒。
nc -vz -G 5 github.com 22只用 IPv4 试试。如果这样能连上,问题就在 IPv6 路径。
ssh -4 -T git@github.com测试 GitHub 在端口 443 上的 SSH 服务。
ssh -T -p 443 git@ssh.github.com显示 Git 的代理设置和你的代理环境变量。
git config --get http.proxy env | grep -i proxy
如何修复
如果端口 22 被屏蔽,就为 GitHub 改用端口 443 上的 SSH。将以下配置块添加到
~/.ssh/config。Host github.com Hostname ssh.github.com Port 443 User git如果 IPv6 不通,就让该主机使用 IPv4。在
~/.ssh/config中该主机的配置块里添加AddressFamily inet。要让空闲会话保持连接,每 60 秒发送一次消息。在主机配置块中添加
ServerAliveInterval 60。为避免长时间等待,在主机配置块中添加
ConnectTimeout 10。对于位于代理之后的 HTTPS 远程仓库,设置 Git 的代理。
git config --global http.proxy http://proxy.example.com:8080作为测试,改用仓库的 HTTPS URL,而不是 SSH URL。
使用 Kilobat
Kilobat 的连接检查会分别测试 IPv4 和 IPv6,因此 IPv6 路径不通时能得到明确的结论。
kilobat why github.com查看某个进程打开的连接。
kilobat destinations --pid 12345
常见问题
为什么 ssh -4 能连上,普通 ssh 却不行?
Mac 先尝试了 IPv6,而 IPv6 路径不通。加上 -4 后,ssh 只使用 IPv4。
ServerAliveInterval 有什么作用?
连接在设定的秒数内没有数据时,ssh 会通过该连接发送一条消息。默认值为 0,即不发送。
参考资料
- GitHub 文档:在 HTTPS 端口使用 SSH
- ssh(1) 和 ssh_config(5),macOS 27.2 自带的 man 手册页
- nc(1),macOS 27.2 自带的 man 手册页
- git-config(1),http.proxy,macOS 27.2 自带的 man 手册页(Git 2.56)
参考资料核查于 2026年10月29日。man 手册页为 macOS 自带版本;在“终端”中用 man <name> 打开。