SSH代理用法:通过ssh代理(跳板)在终端连线ssh服务器

之前的VPN用着用着就被墙掉了,公司NOC无奈给开了一台ssh服务器,用作连线海外服务器的跳板。但问题是mac osx的终端不支持设置网络代理访问,于是通过强大的ssh命令,找到了ProxyCommand选项。通过在终端执行man ssh_config命令可以在里面看到ProxyCommand选项的介绍:

 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' direc-
         tive to avoid a lingering shell process.

         In the command string, any occurrence of `%h' will be substituted by the host name to connect, `%p' by the port, and `%r' by the remote user name.  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

ProxyCommand选项指定一个命令,这个命令从ProxyCommand关键字后的字符开始一直到所在行结束,使用shell的‘exec’来执行,这样的话ProxyCommand后的字符串可以试shell的任何网络连接命令了,可以通过shell调用代理软件命令。

SSH 客户端将通过标准输入输出和这个命令启动后的进程进行正常的 SSH 通信, 而 Proxy 连接着 SSH 服务器(一般是一个 Server Proxy, 再由该 Server Proxy 连接服务器). Proxy 和 Server Proxy 之间组成了一条隧道. 如果两者之间用 HTTP 协议进行通信, 则整个系统便称为”tunneling SSH over HTTP”, 当然也可以使用 UDP, TCP, IP 以及其它任意的可行的协议.

SSH ProxyCommand 相对于 SOCKS, HTTP 或者其它的 Proxy 技术, 更简单. 因为它工作在进程间的文件 IO 通信, 用任何支持 socket 的编程语言, 都能轻易地编写出一个可用的 Proxy. 复杂度只落在隧道本身. 想一想, 如果没有 ProxyCommand, 你需要改变或侵入操作系统的 TCP 子系统才能实现 SSH 隧道. ProxyCommand 提供了方便应用隧道的接口, 网络程序都应该提供这样的接口, 而不是完全依赖于 socket.

因为一个会话就会启动一个 ProxyCommand 进程, 所以, 只有在会话依赖于连接的协议上才能使用这种技术.

通过SSH代理(SSH over SSH)

使用nc命令(netcat)实现,假设本地SSH代理的监听端口是3000,则ProxyCommand为:

ProxyCommand nc -x 127.0.0.1:3000 %h %p

其中%h表示目标地址,%p是目标端口。这句可以用在命令行里,例如:

ssh -oProxyCommand="nc -x 127.0.0.1:3000 %h %p" -i ~/.ssh/github git@github.com

或者写入config文件(参见使用SSH CONFIG)

Host myserver HostName 域名/IP User 用户 IdentityFile 证书文件路径 ProxyCommand nc -x 127.0.0.1:3000 %h %p

nc(netcat)也可以用于HTTPS代理,这需要指定所使用的协议,即添加 -X connect 参数。比如ssh_config中的例子

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

netcat也有很多其他用途,有兴趣可以看看

或者直接使用ssh tunnel来跳到指定服务器:

Host myserver hostname 域名/IP user 用户 port 端口 IdentityFile /IdentityFile_Path ProxyCommand ssh usern@跳板服务器域名/IP -p 端口 -i /IdentityFile_Path nc %h %p 2> /dev/null

然后就可以在终端执行以下命令直接连到所要连的服务器了:

ssh myserver

Wilson

张弛有度、简约不简单