众所周知,用ssh的方式访问github有时候会抽疯,需要一个解决办法,比如在中间加一层socks proxy。然后我的一个额外的要求是ssh能够使用Putty的Pageant来提供密钥验证服务,避免多次输入密码。

之所以不适用Putty自身的plink,是因为没搞懂在命令行下,怎么使用代理。 之前使用Putty的演化版Kitty的klink来连接Pageant,也就是将GIT_SSH_COMMAND设置成为path/to/klink.exe -auto-store-sshkey

首先需要wsl-ssh-pageant,可以把Pageant的验证服务提供给ssh。

  • 安装之后,运行:wsl-ssh-pageant.exe --systray --winssh ssh-pageant
  • 然后设置环境变量:set SSH_AUTH_SOCK=\\.\pipe\ssh-pageant。这样ssh就知道去哪里找验证服务了。
  • 通过ssh-add -l就可以看出来已经添加的验证服务。

从某个版本来时,Windows 10自带了ssh命令。但是存在了一个问题 ProxyCommand incorrectly requires an absolute path #1185

接下来尝试访问github:ssh -T git@github.com -vvv。GitHub会告诉你访问成功,随后就退出了。

下一步增加socks代理。假设本地有一个socks5代理,在127.0.0.1:3333处。可以使用connect命令来连接这个代理:

ssh -T -o ProxyCommand="path\to\connect.exe -S 127.0.0.1:7891 %h %p" git@github.com -vvv

Git for Windows在其Bash命令行中自带了connect,你也可以另行通过scoop install connect-proxy安装。

接下来,参考How to force Git to use socks proxy over its ssh connection?,可以用下面几种方式来告诉Git如何运行ssh

# [step 1] create a ssh-proxy
  ssh -D 9999 -qCN user@server.net

# [step 2] make git connect through the ssh-proxy
  # [current script only]
  export GIT_SSH_COMMAND='ssh -o ProxyCommand="connect -S 127.0.0.1:9999 %h %p"'
  # OR [git global setting] 
  git config --global core.sshCommand 'ssh -o ProxyCommand="connect -S 127.0.0.1:9999 %h %p"'
  # OR [one-time only use]
  git clone -c=core.sshCommand 'ssh -o ProxyCommand="connect -S 127.0.0.1:9999 %h %p"' git@github.com:user/repo.git
  # OR [current repository use only]
  git config core.sshCommand 'ssh -o ProxyCommand="connect -S 127.0.0.1:9999 %h %p"'

假设使用GIT_SSH_COMMAND, 在Windows下要将GIT_SSH_COMMAND设为C:/Windows/System32/OpenSSH/ssh.exe -o ProxyCommand="path/to/conne ct.exe -S 127.0.0.1:3333 %h %p"。主要是因为前面wsl-ssh-pageant是以–winssh方式启动的,所以必须要使用Windows内置的ssh。

其他

使用Git Bash内置的ssh和connect

Git for Windows内置了很多东西,比如ssh、connect以及ssh-agent。可以使用内置的ssh-agent来连接Pageant的验证服务,你需要一个sh脚本:

#!/bin/sh

# ssh-pageant
eval $(/usr/bin/ssh-pageant -r -a "/tmp/.ssh-pageant-$USERNAME")

exec /usr/bin/ssh -o ProxyCommand="connect.exe -S 127.0.0.1:7891 %h %p"  "$@"

把这个脚本命名为git-ssh.sh并增加可执行权限,然后设置环境变量GIT_SSH=path/to/git-ssh.sh即可。

注意:由于GIT_SSH优先级比GIT_SSH_COMMAND低,如果要使用GIT_SSH,则要取消GIT_SSH_COMMAND。另外GIT_SSH指定的路径不能使用双引号“括起来,空格可以用\转义。

Git小技巧

可以设置GIT_TRACE=true来让git打印出更多调试信息。参考10.8 Git Internals - Environment Variables

ncat相关

尝试使用namp中的ncat来作为ProxyCommand:ProxyCommand ncat --proxy-type socks5 --proxy 127.0.0.1:1090 %h %p,结果不成功。参考Tunneling ssh via a SOCKS5 Proxy on Windows

参考链接

(本篇完)

2020-10-06更新

把GIT_SSH指向脚本在git-lfs中会出问题,还是改成使用GIT_SSH_COMMAND吧。

(更新完)

2020-11-02更新

如果是使用Http代理的话,需要将connect的选项从-S改为-H:

connect.exe -H 127.0.0.1:7891 %h %p

(更新完)

2021-03-24更新

Netch可以给游戏加代理。可以从剪贴板赋值SS代理列表。可以给单进程做代理,只要输入目标进程名即可。

(更新完)