第二部分 本地转发与远程转发

本地转发实例分析

我们先来看第一个例子,在实验室里有一台 LDAP 服务器(Ldap Server Host),但是限制了只有本机上部署的应用才能直接连接此 LDAP服务器。如果我们由于调试或者测试的需要想临时从远程机器(LdapClientHost)直接连接到这个 LDAP 服务器 , 有什么方法能够实现呢?

答案无疑是本地端口转发了,它的命令格式是:

  1. ssh -L <local port>:<remote host>:<remote port> <SSH hostname> 

在Ldap Client Host上执行如下命令即可建立一个SSH协议的本地端口转发,例如:

  1. $SSH-L 7001:localhost:389 Ldap Server Host 

图 2. 本地端口转发

图 2. 本地端口转发

这里需要注意的是本例中我们选择了 7001 端口作为本地的监听端口,在选择端口号时要注意非管理员帐号是无权绑定 1-1023 端口的,所以一般是选用一个 1024-65535 之间的并且尚未使用的端口号即可。

然后我们可以将远程机器(LdapClientHost)上的应用直接配置到本机的 7001 端口上(而不是 LDAP 服务器的 389 端口上)。之后的数据流将会是下面这个样子:

我们在Ldap Client Host上的应用将数据发送到本机的 7001 端口上,而本机的SSH Client 会将 7001 端口收到的数据加密并转发到 LdapServertHost 的SSH Server 上。SSH Server 会解密收到的数据并将之转发到监听的 LDAP 389 端口上,最后再将从 LDAP 返回的数据原路返回以完成整个流程。我们可以看到,这整个流程应用并没有直接连接 LDAP 服务器,而是连接到了本地的一个监听端口,但是SSH端口转发完成了剩下的所有事情,加密,转发,解密,通讯。

这里有几个地方需要注意:

SSH协议端口转发是通过SSH连接建立起来的,我们必须保持这个SSH连接以使端口转发保持生效。一旦关闭了此连接,相应的端口转发也会随之关闭。我们只能在建立SSH连接的同时创建端口转发,而不能给一个已经存在的SSH连接增加端口转发。

你可能会疑惑上面命令中的 <remote host> 为什么用 localhost,它指向的是哪台机器呢?在本例中,它指向 LdapServertHost 。我们为什么用 localhost 而不是 IP 地址或者主机名呢?其实这个取决于我们之前是如何限制 LDAP 只有本机才能访问。如果只允许 lookback 接口访问的话,那么自然就只有 localhost 或者 IP 为 127.0.0.1 才能访问了,而不能用真实 IP 或者主机名。

命令中的 <remote host> 和 <SSH hostname> 必须是同一台机器么?其实是不一定的,它们可以是两台不同的机器。我们在后面的例子里会详细阐述这点。好了,我们已经在Ldap Client Host建立了端口转发,那么这个端口转发可以被其他机器使用么?比如能否新增加一台 LdapClientHost2 来直接连接Ldap Client Host的 7001 端口?答案是不行的,在主流SSH实现中,本地端口转发绑定的是 lookback 接口,这意味着只有 localhost 或者 127.0.0.1 才能使用本机的端口转发 , 其他机器发起的连接只会得到“ connection refused. "。好在SSH同时提供了 GatewayPorts 关键字,我们可以通过指定它与其他机器共享这个本地端口转发。

  1. ssh -g -L <local port>:<remote host>:<remote port> <SSH hostname> 

远程转发实例分析

我们来看第二个例子,这次假设由于网络或防火墙的原因我们不能用SSH协议直接从Ldap Client Host连接到 LDAP 服务器(LdapServertHost),但是反向连接却是被允许的。那此时我们的选择自然就是远程端口转发了。

它的命令格式是:

  1. ssh -R <local port>:<remote host>:<remote port> <SSH hostname> 

例如在 LDAP 服务器(LdapServertHost)端执行如下命令:

  1. $SSH-R 7001:localhost:389Ldap Client Host 

图 3. 远程端口转发

图 3. 远程端口转发

和本地端口转发相比,这次的图里,SSH Server 和SSH Client 的位置对调了一下,但是数据流依然是一样的。我们在Ldap Client Host上的应用将数据发送到本机的 7001 端口上,而本机的SSH Server 会将 7001 端口收到的数据加密并转发到 LdapServertHost 的SSH Client 上。SSH Client 会解密收到的数据并将之转发到监听的 LDAP 389 端口上,最后再将从 LDAP 返回的数据原路返回以完成整个流程。

看到这里,你是不是会有点糊涂了么?为什么叫本地转发,而有时又叫远程转发?这两者有什么区别?

本地转发与远程转发的对比与分析

不错,SSH Server,SSH Client,Ldap Servert Host,Ldap Client Host,本地转发,远程转发,这么多的名词的确容易让人糊涂。让我们来分析一下其中的结构吧。首先,SSH 端口转发自然需要SSH连接,而SSH协议连接是有方向的,从SSH Client 到SSH Server 。而我们的应用也是有方向的,比如需要连接 LDAP Server 时,LDAP Server 自然就是 Server 端,我们应用连接的方向也是从应用的 Client 端连接到应用的 Server 端。如果这两个连接的方向一致,那我们就说它是本地转发。而如果两个方向不一致,我们就说它是远程转发。我们可以回忆上面的两个例子来做个对照。

本地转发时:

LdapClientHost 同时是应用的客户端,也是SSH Client,这两个连接都从它指向 LdapServertHost(既是 LDAP 服务端,也是SSH Server)。

远程转发时:

LdapClientHost 是应用的客户端,但却是SSH Server ;而 LdapServertHost 是 LDAP 的服务端,但却是SSH Client 。这样两个连接的方向刚好相反。

另一个方便记忆的方法是,Server 端的端口都是预定义的固定端口(SSH Server 的端口 22,LDAP 的端口 389),而 Client 端的端口都是动态可供我们选择的端口(如上述例子中选用的 7001 端口)。如果 Server 端的两个端口都在同一台机器,Client 端的两个端口都在另一台机器上,那么这就是本地连接;如果这四个端口交叉分布在两个机器上,每台机器各有一个 Server 端端口,一个 Client 端端口,那就是远程连接。

弄清楚了两者的区别之后,再来看看两者的相同之处。如果你所在的环境下,既允许Ldap Client Host发起SSH连接到 Ldap Server Host,也允许 Ldap Server Host 发起SSH协议连接到 Ldap Client Host 。那么这时我们选择本地转发或远程转发都是可以的,能完成一样的功能。

接着让我们来看个进阶版的端口转发。我们之前涉及到的各种连接/转发都只涉及到了两台机器,还记得我们在本地转发中提到的一个问题么?本地转发命令中的 <remote host> 和 <SSH hostname> 可以是不同的机器么?

  1. ssh -L <local port>:<remote host>:<remote port> <SSH hostname> 

答案是可以的!让我们来看一个涉及到四台机器 (A,B,C,D) 的例子。

图 4. 多主机转发应用

图 4. 多主机转发应用

在SSH Client(C) 执行下列命令来建立SSH协议连接以及端口转发:

  1. $SSH-g -L 7001:<B>:389 <D> 

然后在我们的应用客户端(A)上配置连接机器(C )的 7001 端口即可。注意我们在命令中指定了“ -g "参数以保证机器(A)能够使用机器(C)建立的本地端口转发。而另一个值得注意的地方是,在上述连接中,(A)<-> (C) 以及 (B)<->(D) 之间的连接并不是安全连接,它们之间没有经过SSH的加密及解密。如果他们之间的网络并不是值得信赖的网络连接,我们就需要谨慎使用这种连接方式了。


相关内容