SSH端口转发

端口转发

在之前的总结中提到过端口映射即端口转发:如何从外网访问家里的电脑。即将数据从一台机器的某个端口转发到另一台机器的某个端口。

端口转发

A 的数据通过 B 转发 到 C,C 的响应再从 B 转发到 A

之前研究了一段时间小程序,微信官方只允许小程序访问在公众平台配置好的域名,这个域名往往指向一个服务器,该服务器一般是腾讯云等Vps。那么,我们在自己本地写小程序代码的时候如何调试呢?小程序是无法直接访问我们的本地机器的。

在寻找解决办法的时候,了解到了 SSH 端口转发的功能。

我们知道,SSH 会自动加密和解密所有 SSH 客户端与服务端之间的网络数据。但是,SSH 还同时提供了一个非常有用的功能,这就是端口转发。它能够将其他 TCP 端口的网络数据通过 SSH 链接来转发,并且自动提供了相应的加密及解密服务。这一过程有时也被叫做“隧道”(tunneling)。

SSH 端口转发能够提供两大功能:

  • 加密 SSH Client 端至 SSH Server 端之间的通讯数据。

  • 突破防火墙的限制完成一些之前无法建立的 TCP 连接。

在介绍端口转发的内容之前,先学习几个别的参数:

1
2
3
4
5
-g 在-L/-R/-D参数中,允许远程主机连接到建立的转发的端口,如果不加这个参数,只允许本地主机建立连接。
-N 不打开远程shell,不执行远程命令. 用于转发端口.
-T 不为这个连接分配TTY
-f SSH连接成功后,转入后台运行,通常和-N连用

本地转发

本地端口转发,适用于以下场景:

A 与 B 两台主机无法连通,但是主机 C 可以同时连通 A 和 B。

此时我们可以通过 C 来达到 A、B 通信的目的。

比如,你购买了一台VPS(B),现在想在公司的主机(A)上访问这台VPS。但是由于保密原因,公司的主机不可以访问外网,只有一台外网机(C)可以访问外网(没错,这就是我们公司)。

在主机 A 上执行:

1
2
# ssh -L <本地主机端口>:<目标主机>:<目标主机端口> <远程主机>
ssh -NTf -L 1219:B:22 C

先明确几个概念:

本地主机:执行 ssh 连接命令的主机

远程主机:ssh 登录到的主机

目标主机:最终想要在本地主机去访问的主机

其中 A 就是本地主机,1219即本地端口;目标主机为 B,目标主机端口为 22。这条命令的意思,就是指定 SSH 绑定本地端口1219,然后指定 C 将所有的数据,转发到目标主机 B 的22端口(B 主机ssh运行在22端口)

此时,我们只要访问 A 的1219端口,就相当于登录 B 了。

在 A 上执行:

1
ssh -p 1219 localhost

登录 B 后,从 A 到 B 的数据流应该是这样的:

  1. 我们在 A 上输入的数据发送到 A 的1219端口上,

  2. 而 A 的 SSH Client 会将 1219 端口收到的数据加密并转发到 C 的 SSH Server 上。

  3. SSH Server 会解密收到的数据并将之转发到 B 22端口上

  4. 最后再将从 B 返回的数据原路返回以完成整个流程。

远程转发

我们在做本地转发时,A 无法直接访问 B,需要借助 C 进行转发。所以,要求 A 可以访问 C。

如果 A 也不能直接访问C,但是反过来可以, C 可以连接 A。此时若 A 想访问 B,就需要使用远程端口转发。

比如,你在家里有一台电脑(A),想要访问公司测试机(B)上的数据库服务。但是公司的测试机是与外网隔绝的,只有一台外网机(C)可以访问外网,并且这台外网机只能主动访问外网,不能被外网访问。

利用之前学到的技能:如何从外网访问家里的电脑,我们可以让 C 访问 A。此时:

  • A 无法直接访问 B,C;

  • B、C 之间可以互相访问;

  • C 可以访问 A。

如果想从 A 访问 B,既然 C 可以连 A,那么就从 C 上建立与 A 的SSH连接,然后在A 上使用这条连接访问 B 就可以了。

在主机 C 上执行:

1
2
# ssh -R <远程主机端口>:<目标主机>:<目标主机端口> <远程主机>
ssh -NTf -R 1219:B:2003 A

这条命令的意思,就是让 A 监听它自己的1219端口,然后将所有数据经由 C,转发到 B 的2003端口。

此时,我们只要访问 A 的1219端口,就相当于连接 B 的数据库服务了。

在 A 上执行:

1
isql -p 1219 -h localhost

从 A 到 B 的数据流应该是这样的:

  1. 我们在 A 上输入的数据发送到 A 的1219端口上,

  2. 而 A 的 SSH Server 会将 1219 端口收到的数据加密并转发到 C 的 SSH Client 上。

  3. SSH Client 会解密收到的数据并将之转发到 B 2003端口上

  4. 最后再将从 B 返回的数据原路返回以完成整个流程。

动态转发

动态转发可以用来科学上网。

如果想要科学上网,一般我们需要购买一台可以访问“外网”的 VPS 主机,然后在上面搭建 shadowsocks 服务,参考VPS使用笔记

不用在 VPS 上搭建 shadowsocks 服务,通过 ssh 我们同样可以通过 VPS 进行 fg。

在你本地主机上执行下面的命令:

1
ssh -NTfg -D 2018 <SSH Server>

上面的命令实际上在你本机创建了一个 socks 代理服务,所有发往2018端口的请求都将被转发到 SSH Server 上面。

现在需要一个 socks 客户端来进行访问,Chrome 上有一个 SwitchyOmega 的插件可以满足我们的需求:

代理

我在 192.168.172 上执行了上述命令,通过配置 SwitchyOmega 实现了科学上网。