0x00 ssh支持的通用端口转发

一般我们使用ssh来远程登录主机,在上面执行命令.但是ssh还有port forward的功能,关于ssh的port forward的详细命令,可以看命令的man输出. 本文主要对ssh port forwarding的工作原理进行介绍.

ssh的通用端口转发分为local forward(本地端口转发),remote forward(远端端口转发),dynamic forward(动态端口转发). 还有X11 forward也是属于端口转发的一种,但是其是特殊用途的,不在这儿讨论.

0x01 ssh中的client和server

我们需要弄清楚local和remote的概念. ssh是典型的client,server架构,我们要连接的服务器是remote端,发起ssh连接的是client端. 在client端,我们常用的软件有: windows下面的xshell,putty,mobaxterm; linux下面自带的openssh-client,mac上也是openssh-client. 而在server端,一般就是各个发行版安装的openssh-server了.

0x02 ssh端口转发 local forword

下图是local forward的工作原理图: 其中client和client_1在本地网络的两台机器,相互直接是可以直接访问的. server和server_1是远端网络的两台机器,相互之间是可达的. 但是本地网络和远端网络是不可随意访问的(可能是路由本身有特殊设置,但是大部分情况下是因为防火墙的隔离设置),只有其中的client_1可以发起向server_1的22端口ssh连接.

使用ssh提供的local forward,从client可以访问到server的22端口,也就是从client可以直接登录到server上.

在client_1上我们输入命令,并保持这个窗口打开不关闭

如果是linux和mac,那么直接输入这个命令就可以了,其中的server和server_1换成相应的IP,如果是windows,可以下载一个mobaxerm,里面有openssh的完全实现也有这个命令. 当然windows下面的xshell,putty之类的软件也有相应的配置.

ssh -L 10000:server:22 server_1
端口转发原理和使用-端口转发原理和使用方法-编程知识网

此时会完成如下的事情:

  1. client_1完成到server_1的ssh连接,这条tcp通道就存在了
  2. 在client_1端的ssh进程会在本地的tcp:10000端口开启监听

然后在client上输入如下命令

ssh -p 10000 client_1

此时会完成如下的事情:

  1. client_1发起到client的10000端口连接
  2. client完成连接
  3. server_1上的sshd进程发起到server的22端口的连接
  4. 所有通过client到client_1的10000端口的数据通过client_1和server_1之间的连接到server_1上,然后接着到server 22端口上.回来的数据也是走这个通道.

也就是说,上面图中的3个实线箭头组成的链路通道相当于虚线箭头的通道.达到的效果是,在本地网络中任何client机器通过访问client_1的10000端口,就相当于访问了server的22端口了. 当然,这儿可以把22端口换成任何server上面的端口,比如80或者443之类的(不过这个web请求的访问最好还是用下面的动态转发)

0x03 ssh端口转发 remote forward

和local forward对应的是remote forward. 注意这儿的local和forward说的是端口是开在哪边的,如果是开在ssh(client)这边,就是local forward. 如果是开在sshd(server)那边,就是remote forward.

那local forward可以让我们跨过防火墙的限制,打一条通道到远端. 那么remote forward有什么用么?

1.既然远端可以有服务要被访问,那么本地端也可以有的,也就是让远端的机器可以跨过防火墙访问本端机器提供的服务.

2.一个更好的用处,如果想让开在自己本机的服务直接被公网访问到(这个在调试的时候很有用,让各种`实际`的流量进入自己的机器一会儿),那么remote froward可以帮上大忙.

命令和local forward类似,在client1上敲

ssh -R 10000:client:22 server_1

client_1和server_1建立ssh连接的过程都是一样的. 不过第二步开端口是server_1上的ssh进程开一个监听到tcp:10000的端口

然后在和server_1可达的网络中的机器server发起到server_1的10000端口的连接时,client_1上的ssh会将流量导入到client的22端口.

端口转发原理和使用-端口转发原理和使用方法-编程知识网

在解释一下第二个用处,server换成是客户的浏览器,server_1上的10000端口换成80端口,client换成是client_1,而且都是自己的电脑,client:22换成127.0.0.1:80. 效果就是客户的浏览器访问server_1的80端口时,流量直接进入到自己的PC的80端口了.

0x04 ssh端口转发 dynamic forward

local forward可以完成本地端口到远端端口的一对一访问.

dynamic forward就是socks5代理. 通过在client_1上敲

ssh -D 10000 server_1

前面client_1和server_1之间连接建立过程都是相同的. 此时在client_1上就会开启socks 5的10000端口.

端口转发原理和使用-端口转发原理和使用方法-编程知识网

我们在client上的web浏览器进行如下的代理设置,那么所有从server_1上能放到导的网址,在client上就能访问到了. 相当于把client放到了server_1的位置.

端口转发原理和使用-端口转发原理和使用方法-编程知识网

0xff 总结

openssh的端口映射是一个强大的功能.基本上防火墙都会让对环境中特定的机器的22端口可以通过,巧妙的使用ssh的port forward功能,可以让很多远程支持的事情变得可能. 如果再结合我上篇文章介绍的ProxyCommand功能,会发现我们可以把port forward的跳数继续延长下去,只要环境有一个洞可以通,那么最终我们就能访问到.