ssh隧道

一.概述

由于工作原因,总是要连接到各种不能直接访问的环境,所以大部分环境必须要使用ssh隧道进行访问。其实只是简单的会用,说道具体的原理和方式不是很清楚,所以我通过这篇文章来深入学习一下ssh隧道,也让各位可以了解下。
下面是一个最简单也是最常见的一种情况:


ssh隧道

client为了访问到server的服务,但是由于网段不同(内外网不同)或者防火墙的阻拦,这就用到了ssh隧道。

二.理解

本质上就是端口转发。它能够将其他 TCP 端口的网络数据通过 SSH 链接来转发,并且自动提供了相应的加密及解密服务。这一过程也被叫做“隧道”(tunneling),这是因为 SSH 为其他 TCP 链接提供了一个安全的通道来进行传输而得名。
SSH 端口转发能够提供两大功能:
1.加密 SSH Client 端至 SSH Server 端之间的通讯数据。
2.突破防火墙的限制完成一些之前无法建立的 TCP 连接。

三.本地转发和远程转发

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

1.本地连接

正向本地转发

例如:如果server段运行着mysql服务但是只监听着127.0.0.1,可在client搭建ssh隧道

ssh -N -f -L 3306:localhost:3306 $server_ip

这时转发数据流是:

  • client上的应用客户端将数据发送到本地的3306端口上
  • client上的ssh客户端将本地3306端口收到的数据发送到server端的ssh server上
  • SSH Server 会解密收到的数据并将之转发到监听的3306端口
  • 最后再将从mysql返回的数据原路返回以完成整个流程。

2.远程连接

反向本地转发

例如还是上面的访问mysql的,反向的话,在server段执行

ssh -N -f -R $(client port):localhost:$(server port) $(client ip)

进阶

上面说的都只涉及到2台机器,还是没有说明开篇说的那个问题。下面说下进阶版的端口转发。本地转发命令中的 <remote host> 和 <SSH hostname> 可以是不同的机器的。

本地

这种就是开篇说的那种常见的情况,服务在第三台机器上,在client端访问$(client port),就相当于访问到了remote server。


正向远程转发

例如:

ssh -N -f -L $(client port):$(remote server ip):$(remote server port) $(sshserver ip)

远程

同理,也是在server端执行。在client端访问$(client port),就相当于访问到了remote server


反向远程转发
ssh -N -f -R $(client port):$(remote server ip):$(remote server port) $(client ip)

四.动态转发

当你看到这里时,有没有想过我们之前讨论的本地转发,远程转发,前提都是要求有一个固定的应用服务端的端口号,例如前面例子中的mysql服务端的3306端口。那如果没有这个端口号怎么办?什么样的应用会没有这个端口号呢?比如说用浏览器进行 Web 浏览,比如说 MSN 等等。

当我们在一个不安全的 WiFi 环境下上网,用 SSH 动态转发来保护我们的网页浏览及 MSN 信息无疑是十分必要的。让我们先来看一下动态转发的命令格式:

$ ssh -D <local port> <SSH Server>

例如:

$ ssh -D 7001 <SSH Server>
动态转发

我们依然选择了 7001 作为本地的端口号,其实在这里 SSH 是创建了一个 SOCKS 代理服务。之后的使用就简单了,我们可以直接使用 localhost:7001 来作为正常的 SOCKS 代理来使用,直接在浏览器或 MSN 上设置即可。在 SSH Client 端无法访问的网站现在也都可以正常浏览。

五.多主机转发

你会发现之前建立的ssh隧道监听的端口都是127.0.0.1,所以只能client一台主机进行连接。如果想让client同网段的其他主机也能访问到呢,那就需要加一个参数 -g。加了这个参数监听的ip就是0.0.0.0,这样同网段的其他主机可以访问client的相应端口即可。

六.xshell搭建ssh隧道

大部分情况下我们的client可能不是linux系统,而是windows系统,需要使用xshell等客户端去连接。这里介绍建立隧道的方式。
在我们通过xshell连接到了ssh server后,在查看--隧道窗格--转移规则--右键添加会出现下面的窗口:


xshell转发

通过上面的讨论,这里就一目了然了。
类型就是local 本地连接,remote 远程连接(一般不用,因为用xshell的都是client),dynamic 动态连接
源主机就是client本地,例如localhost
监听端口就是client自定义的端口
目标主机和端口就是需要访问的ip和端口

推荐阅读更多精彩内容