ssh端口转发(ssh隧道)详解

摘要

ssh端口转发(或称ssh隧道)在本机和远程主机之间建立一个加密的通信隧道。这一隧道可以被其他非加密(例如IMAP,VNC,IRC等)或者加密传输的协议用来作为代理转播链接。

本文将探讨ssh端口转发的三种类型,分别说明每一种的配置及使用方法并给出相应的ssh命令。

背景知识需求

本文假设读者已经熟悉基本的ssh原理以及ssh操作,了解一定的网络基础知识例如网络协议、网络通信以及端口号等,并拥有一定的bash使用经验。

ssh端口转发的类型

ssh端口转发可以用来将互联网通信连入或传出一片原本对通信有所限制的网络,从而绕过网络限制或者无法正常工作的路由器,或者伪装连接的源/目的IP地址。ssh端口转发也可以配合一些简单的配置(如SOCKS Proxy)从而作为代理服务使用。

ssh端口转发可以被分为三种类型:

  1. 本地端口转发。本地端口转发指的是将从ssh客户发出的通信转发到ssh服务器,最终再访问某一目的地。本地端口转发可以用来绕过防火墙对某几个网站的访问限制。
  2. 远程端口转发。远程端口转发与本地端口转发的过程相反,指的是将从ssh服务器发出的通信经由ssh客户转发,最终再访问某一目的地。本地端口转发可以用来使我们从远程主机连接对访问有限制的公司内网(不推荐)。
  3. 动态端口转发。动态端口转发比较灵活,指的是从某几个服务或程序发出的通信将先由ssh客户转发至ssh服务器,再由ssh服务器转发至最终目的地。动态端口转发使得我们可以迅速地建立一个链接并结合SOCKS Proxy从而作为代理服务或者v*n服务。

如果想要使用端口转发,必须首先确保服务器上的端口转发功能为允许状态。同时还应当明确我们要使用的源端口号和目的端口号。对于本地端口转发和远程端口转发,如上所述,我们还需要一个最终访问的目的地址。对于动态端口转发来说,我们还需要配置SOCKS Proxy。注意具体如何配置端口转发取决于我们使用的ssh客户端版本。所以必要情况下我们可能需要进一步阅读相应的文档来了解更多技术实现上的细节。

在进行端口转发的同时,我们应当注意小于1024和大于49151的端口是为系统服务预留的,因此进行端口转发时应当尽量避免使用这些端口。另外,某些服务可能只能使用某些特定的端口,因而对于这些服务而言在进行端口转发的时候我们需要特别注意使用相应的端口。

本地端口转发

配置本地端口转发时,我们需要指定最终的目的地址(包括服务器地址和端口号),ssh服务器地址,以及需要被转发的端口号。举例来说,如果我们想要通过一个ssh服务器my-ssh-server.com来进行对本地端口5432的转发(假设我们在该服务器上的用户名为user),从而最终实现访问destination-server.com上的80端口,那么我们应当使用如下命令进行端口转发。

ssh -L 5432:destination-server.com:80 [email protected]

其中-L参数指定了转发类型为本地端口转发。在我们运行这个命令之后直到结束该ssh连接之前,任何对localhost:5432的访问都将通过my-ssh-server.com转发至destination-server.com:80

我们也可以在同一行ssh命令里指定多个端口转发,如下面的例子所示。这一命令将会开启两个本地端口转发。一个将对localhost:5432的访问经由my-ssh-server.com转发至destination-server-1.com:80,另一个将对localhost:12345的访问经由my-ssh-server.com转发至destination-server-2.com:80

ssh -L 5432: destination-server-1.com:80 -L 12345:destination-server-2.com:80 [email protected]

远程端口转发

远程端口转发可以使我们经由本机转发来自于远程端口的网络流量。配置远程端口转发时,我们首先需要知道远程ssh服务器的地址,远程服务器上将被转发的端口号,以及最终的目的地址以及端口号。例如我们想要将my-ssh-server.com上的5432端口经由本地ssh客户转发至destination-server.com的80端口,需要使用的命令如下。

ssh -R 5432:destination-server.com:80 [email protected]

其中的-R参数指定了远程端口转发。在这个ssh会话持续期间,所有在my-ssh-server.com上对localhost:5432的访问都将经由本地ssh客户被最终转发至destination-server.com:80

动态端口转发

使用动态端口转发可以方便地在我们使用的电脑上建立一个SOCKS Proxy。SOCKS协议是一个被各种程序和服务广泛用连接代理服务器并进行网络访问的协议。不同的程序在使用SOCKS Proxy的程序需要进行相应各不相同的配置。在停止使用SOCKS Proxy之后,也应当将相应的配置修改回去。

在配置一个SOCKS Proxy之前,我们首先需要建立与远程ssh服务器建立连接。

ssh -C -D -N 5432 [email protected]

其中-C参数指定这一ssh连接将压缩所传输的数据。这一选项有助于在利用ssh隧道传输文本格式的数据时提升速度,但也会降低传输二进制信息时的速度。-D参数指定采用动态端口转发。-N参数关闭了执行远程命令的功能(因为我们此处仅仅采用ssh来进行端口转发)。

接下来我们需要修改相应的配置。以Mac OSX系统为例,配置流程如下:

  1. 首先打开__system preference__,并打开其中的__Network__设置。
  2. 打开当前正在使用的网关__advanced__设置中的__proxy__,如下图所示。
    ssh端口转发(ssh隧道)详解
  3. 勾选其中的__SOCKS Proxy__,并在server栏分别填入localhost5432作为server地址和server端口(因为我们在上文的ssh命令中指定5432作为动态端口转发所使用的端口号),如下图所示。
    ssh端口转发(ssh隧道)详解
  4. 保存设置并点击应用。

完成上述设置后,我们的Mac上的所有网络连接都将通过该SOCKS Proxy进行转发。当我们关闭ssh连接之后,SOCKS Proxy也就不能继续使用了。这时候我们就需要取消勾选设置中的__SOCKS Proxy__,否则会出现电脑无法上网的现象。