回国 SSH 代理设置 / SSH Proxy Settings

本次回🀄️发现虽然挂机场代理后外部访问问题不大,但GCP机器的ssh connection卡成翔,此贴记录一下macOS上ssh代理设置相关问题。

Command Interpretation

为ssh命令设置代理的通用模版是

1
2
ssh -o ProxyCommand="nc -X 5 -x 127.0.0.1:1080 %h %p" \
root@server

其中-o flag代表option, 用以唤起ProxyCommand这个选项,具体man page里描述为:

1
2
3
4
-o option
Can be used to give options in the format used in the configuration file. This is useful for specifying
options for which there is no separate command-line flag. For full details of the options listed below,
and their possible values, see ssh_config(5).

这里面,man ssh_configProxyCommand的描述为:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
ProxyCommand
Specifies the command to use to connect to the server. The command string extends to the end of the
line, and is executed using the user's shell ‘exec’ directive to avoid a lingering shell process.

Arguments to ProxyCommand accept the tokens described in the TOKENS section. The command can be
basically anything, and should read from its standard input and write to its standard output. It should
eventually connect an sshd(8) server running on some machine, or execute sshd -i somewhere. Host key
management will be done using the Hostname of the host being connected (defaulting to the name typed by
the user). Setting the command to none disables this option entirely. Note that CheckHostIP is not
available for connects with a proxy command.

This directive is useful in conjunction with nc(1) and its proxy support. For example, the following
directive would connect via an HTTP proxy at 192.0.2.0:

ProxyCommand /usr/bin/nc -X connect -x 192.0.2.0:8080 %h %p

nc命令即TCP/UDP监听, -X flag 默认值5指定socks5协议, -x 指定了代理的地址:端口。

1
2
3
4
5
6
7
8
9
10
11
NAME
nc – arbitrary TCP and UDP connections and listens
SYNOPSIS
nc [-46AcDCdhklnrtUuvz] [-b boundif] [-i interval] [-p source_port] [-s source_ip_address] [-w timeout]
[-X proxy_protocol] [-x proxy_address[:port]] [--apple-delegate-pid pid] [--apple-delegate-uuid uuid]
[--apple-ext-bk-idle] [--apple-nowakefromsleep n] [--apple-ecn mode] [hostname] [port[s]]

-X proxy_version
Requests that nc should use the specified protocol when talking to the proxy server. Supported protocols
are “4” (SOCKS v.4), “5” (SOCKS v.5) and “connect” (HTTPS proxy). If the protocol is not specified,
SOCKS version 5 is used.

我的梯子一般使用 clash 系的代理工具,clash Xstash
stash app store版用的是系统级VPN接口,理论上不需要另外为ssh设置代理。局域网内设备运行的stash需要在 Settings > Network Settings 中turn on Allow LAN Devices 选项,以开启LAN访问。
clash 系工具的混合代理监听端口 (mixed proxy port) 一般是7890,将ProxyCommand的端口修改一下即可。

~/.ssh/config

本人是~/.ssh/config党,如果你还不会配置ssh config,推荐你稍微学习一下。

如果你要为特定的Host设置代理,只需给你的Host加入ProxyCommand相关行即可

1
2
3
4
5
Host de-zoomcamp-proxy
ProxyCommand nc -X 5 -x 127.0.0.1:7890 %h %p
HostName yourhostip
User yourname
IdentityFile ~/.ssh/gcp

因为我在墙外也需要连接同样的Host,一般就另外设置一个xxx-proxy Host专供墙内代理使用。
但比较令人无语的是,使用代理后ssh到GCP谷歌云依然有输入延迟。

SSH over HTTP Proxy

如果你没有sock5,仅有HTTP,也可以通过corkscrew给你的HTTP代理建立socks5隧道.

1
$brew install corkscrew

找到corkscrew的路径

1
2
$which corkscrew
/opt/homebrew/bin/corkscrew

再向~/.ssh/config写入

1
ProxyCommand /opt/homebrew/bin/corkscrew 127.0.0.1 7890 %h %p