共计 4819 个字符,预计需要花费 13 分钟才能阅读完成。
第一部分 概述
场景一: 设想这样一个场景,当你挤了很久的公交,又辗转了几班地铁,终于拖着疲惫的身躯回到家中的时候,突然间接到了领导的电话,公司服务器上有某个重要的服务需要立马被关闭,而公司的内部网络与外部网络之间有防火墙,禁止 telnet 远程直接链接,这时你会怎么办呢?(吐槽一下,运维好苦逼 /(ㄒ o ㄒ)/~~)
场景二: 设想另外一种场景,在本地的一个服务器上运行着 SMTP 服务,而远程的一个主机需要访问这个 SMTP 服务,但是防火墙不允许不信任的外部访问,进入到局域网内部,而内部的主机却是可以正常的访问防火墙之外的网络,这种情况下,又应该如何去处理呢?
SSH 端口转发概述
首先,我们来了解一下 SSH 端口转发的概念。当我们通过 SSH 协议建立的通信通道之后,SSH 会自动给加密和解密客户端与服务器端之间的所有通信。同时,SSH 还提供了一个非常有用的功能,这就是端口转发。它能够将其他 TCP 端口的网络数据通过 SSH 链接来转发,并且自动提供了相应的加密及解密服务。这一过程有时也被叫做“隧道”(tunneling),这是因为 SSH 为其他 TCP 链接提供了一个安全的通道来进行传输而得名。例如,Telnet,SMTP,LDAP 这些 TCP 应用均能够从中得益,避免了用户名,密码以及隐私信息的明文传输。可以将 SSH 建立的通信链路理解为管道(隧道),不安全的 TCP 协议在隧道中传输数据,避免了明文的传输。而与此同时,如果您工作环境中的防火墙限制了一些网络端口的使用,但是允许 SSH 的连接,那么也是能够通过将 TCP 端口转发来使用 SSH 进行通讯。总的来说 SSH 端口转发能够提供两大功能:
加密 SSH Client 端至 SSH Server 端之间的通讯数据。
突破防火墙的限制完成一些之前无法建立的 TCP 连接。
SSH 的端口转发有着多种类型,同时在不同的场景中有着多种不同的应用,单靠文字解释,是说不明白的,所以接下来,我们通过几个实验来详细的解释一下 SSH 的端口转发功能。
第二部分 本地转发与远程转发
本地转发实例
在场景一中,我们描述了这样一个场景。我们需要在远程使用 telnet 协议链接到某个被防火墙保护的内部网络中去,那么我们应该如何实现呢?
答案无疑就是使用 SSH 的本地端口转发了。首先看一下下面的网络拓扑结构。
本地端口转发
SSH 的本地端口转发的格式如下所示
ssh -L local_port:remote_host:remote_host_port sshserver
本地端口转发有如下的常用选项。
-f
后台启用
-N
不打开远程 shell,处于等待状态
-g
启用网关功能
我们的实例实现如下所示。这一个过程是在外部主机(172.18.253.127)上进行的操作
# 这里进行一下解释
# 172.18.253.58 是我们需要远程到的服务器,也就是图中的数据库服务器
# 172.18.250.114 是我们的转发服务器,同时也是 SSH-Server
# 9527 是我们选择的本地监听端口
[root@localhost ~]# ssh -L 9527:172.18.253.58:23 -Nf 172.18.250.114
# 通过本地监听端口,使用 telnet 协议就可以访问到 远程的数据库服务器了
[root@localhost ~]#telnet 127.0.0.1 9527
我们选择了本地主机的 9527 端口作为监听端口,是因为,非管理员用户,是没有权限,管理 1 -1023 端口的,所以一般是选择 1024-65535 之间尚未被占用的端口来进行监听就可以了。这样的话,整个通信的流程,大体上就是下面的样子
我们在外部主机(127.0.0.1) 上的 telnet 应用在使用的时候将数据发送到本机的 9527 端口上
外部主机 (127.0.0.1) 上的 SSH-Client 会将 9527 端口收集到的所有的数据加密发送到 SSH-Server(也就是图中的管理服务器 172.18.250.114)上
SSH-Server(管理服务器 172.18.250.114) 会将解密后的数据,通过局域网发送到目标服务器(172.18.253.58)上
目标服务器 上的数据再原路返回,就完成了整个流程(图中省略了数据返回这一流程,避免引起理解上的歧义)。
这样,我们就解决了 场景一 中所面临的困境��而且,外部主机并没有直接链接到数据库服务器上,而是监听了一个本地端口,由 SSH 完成了剩下的所有的事情,比如加密,通讯,解密,转发等等。
同时有下面的注意点
SSH 端口转发是通过 SSH 连接建立起来的,我们必须保持这个 SSH 连接以使端口转发保持生效。一旦关闭了此连接,相应的端口转发也会随之关闭。
我们只能在建立 SSH 连接的同时创建端口转发,而不能给一个已经存在的 SSH 连接增加端口转发。
在主流的 SSH 实现中,谁建立的端口监听,谁就可以通过端口进行通讯,其他主机不能通过已经建立的端口进行链接。
为什么最后要使用,127.0.0.1 来进行远程链接呢?我们可以形象地理解为,一面墙上有一个通道,外面地人只能通过这个隧道的入口,与隧道另一端之外的人进行通信,那么就必须先进入这个隧道入口,而隧道入口就是端口 9527,那我们能够打开的门就是摆在我们面前 (127.0.0.1) 的门(9527)了。
这个实验的前提是,通过放火墙不能直接远程到我们需要链接的主机,但是防火墙却能够允许,SSH 协议进入到局域网内部,SSH 协议是安全加密通信协议。
远程转发实例
回到场景二中,如果我们使用 SSH 协议也无法进入到局域网内部怎么办?我们想要访问,某个局域网内部的 SMTP 服务器,但是防火墙隔离了我们的所有请求。而局域网内部的主机却可以通过防火墙访问到外部的主机,此时我们应该如何是好呢?答案应该就是使用 SSH 的远程端口转发了。首先看一下,远程端口转发的网络拓扑。
远程端口转发
SSH 的远程端口转发的格式如下所示
ssh -R sshserver_port:remote_host:remotehost_port sshserver
9527 端口将在远程主机上打开
我们的实例实现如下所示。这一个过程是在内部主机(172.18.250.114)上进行的操作
# 这里进行一下解释
# 172.18.253.58 是我们的 SMTP 服务器
# 172.18.253.127 是防火墙隔离之外的主机,在远程端口转发的案例中,承担了 SSHSERVER 的角色
# 9527 是我们选择的远程的端口,也就是说,当隧道建立成功之后,会在 172.18.253.127 的主机上开启 9527 端口,并进行通信
[root@CentOS6 ~]$ssh -R 9527:172.18.253.58:25 -Nf 172.18.253.127
此时我们切换到远程主机(172.18.253.127)使用
ss -nlt
命令查看一下当前的端口,就会发现开启了 9527 端口。如果此时我们使用 telnet 命令连接一下本地的端口,就能够像 SMTP 服务器发起 SMTP 请求了。
# 通过本地监听端口,使用 telnet 协议就可以访问到 远程的 SMTP 服务器了
[root@localhost ~]#telnet 127.0.0.1 9527
Trying 127.0.0.1...
Connected to 127.0.0.1.
Escape character is '^]'.
220 localhost.localdomain ESMTP Postfix
helo localdomain #开始进行邮件输入了 250 localhost.localdomain
mail from:mage@magedu.com
250 2.1.0 Ok
rcpt to:root
250 2.1.5 Ok
data
354 End data with <CR><LF>.<CR><LF>
subject:hello,ssh
ssh remote link
.
250 2.0.0 Ok: queued as A5B6C2003944
quit
221 2.0.0 Bye
Connection closed by foreign host.
和本地端口转发相比,这次的图中,SSH 的 server 主和 Client 相互换了换了位置。但是数据流还是类似的,还是从外部主机发送到内部网络上的服务器。数据的流程变成了下面的这个样子
由 SSH Client 也就是内部主机(172.18.250.114)发起 SSH 请求,建立 SSH 链接。
此时 SSH Server 也就是外部主机(172.18.253.127) 上就开启了 9527 端口,此时局域网内部就建立了一个与远程主机之间通信的管道。
远程主机(172.18.253.127)通过 telnet 链接就能够建立与 SMTP 服务器(172.18.253.58)的链接,并访问其 SMTP 服务,为了避免混淆,图中并没有画出访问 SMTP 的这条线。
那么到底,本地端口转发,和远程端口转发的区别到底在什么地方呢?
本地转发与远程转发的对比分析
我们还是可以结合上面的两个场景的实际用例来进行分析。首先,我们知道,SSH 的链接是有方向的,都是从 Client 到 Server,而我们的实例中有一个很明显的不同就是,9527 端口到底在哪个主机上打开了。因为我们都是通过 9527 端口发送的数据,所以我们应用(telnet)的方向,都是从 Client 端发送到 Server 端。如果我们通过 9527 端口发送的数据的方向与 SSH Client 端发送数据的方向一致的话,就是本地端口转发,否则就是远程端口转发。
第三部分 其他类型的转发
动态转发实例
设想这样一种场景。我们在防火墙内部想要访问放火墙外面的网站,但是防火墙给我们开放了很少的端口。那么我们如何访问墙外的美好世界呢?先来看一下下面的拓扑结构
如何解决上面场景中遇到的问题呢?答案是使用动态端口转发。为什么要使用动态端口转发呢?我们知道防火墙外面的主机能够访问到互联网上的多个服务,若干个服务可能需要不同的端口号来进行提供,而防火墙给我们提供的端口有限,所以我们不能直接墙外主机上的服务。另外,逐个建立本地端口转发也是意见非常麻烦的事情。
SSH 的动态端口转发的格式如下所示
# ssh server 指的就是我们在放火墙之外的代理服务器
# 1080 也可以是其他可用端口
ssh -D 1080 root@sshserver
我们为网内的主机设置一下动态代理
# 执行这条命令的是 172.18.253.127
[root@localhost ~]#ssh -D 1080 root@172.18.250.114
这时通过动态转发,可以将在本地主机发起的请求,转发到远程主机,而由远程主机去真正地发起请求。而在本地发起的请求,需要由 Socket 代理 (Socket Proxy) 转发到 SSH 绑定的 1080 端口。我们以火狐浏览器为例,配置本地的网络访问代理。找到设置 => 高级 => 网络 => 代理,然后设置成如下的内容。
这样的话,Firefox 浏览器发起的请求都会转发到 1080 端口,然后通过 SSH 转发到真正地请求地址。动态代理也就设置成功了。
X 协议转发实例
所有图形化应用程序都是 X 客户程序。
能够通过 tcp/ip 连接远程 X 服务器。
数据没有加密机,但是它通过 ssh 连接隧道安全进行
SSH X 协议转发的格式如下所示
# 所有的图形话应用程序都是 X 客户程序 例如 gedit
ssh -X user@remotehost X_APP
通过上面的介绍,我们就应该能够简单的了解了如何使用 SSH 转发机制来解决我们日常生产中的问题。比方说,解决防火墙或者网络应用带来的一些限制,以及在不是很安全的场景下如何加密自己的上网信息,从而达到自己安全上网的目的。
本文永久更新链接地址:http://www.linuxidc.com/Linux/2017-10/147355.htm