SSH端口转发
最近公司改变了必须通过web方式登录中间机器然后连接Linux开发环境的限制,可以从自己的Windows机器上直接用SSH客户端登录到中间机器,这样可以通过登录脚本省去每次登录开发机都需要输入密码的麻烦。但是,新的策略生效后,需要每次输入动态口令,登录脚本似乎没法起作用,不过导师马上想到可以采用SSH隧道的方式,保持一条从自己的Windows机器到中间机器的SSH连接,和开发机的通信都走这条通道。自己对这方面还不太熟悉,于是先照着步骤搭好,然后了解了下相关知识。
SSH作为一种安全的加密传输协议,协议数据在传输过程中以加密的形式出现。如果建立一条SSH传输通道,在这条通道上传输其它协议数据,即其它协议的数据通过SSH端口进行转发,SSH连接作为其它协议传输的通道(隧道),所以这种方式也叫做SSH端口转发或SSH隧道。SSH隧道一般有两大功能:
加密传输数据
突破防火墙的限制(当然前提是防火墙打开了SSH端口)
SSH端口转发的核心是建立一条SSH通道。如下图所示,应用A想和应用B进行数据通信,但是被防火墙阻止,已经知道A和C之间、B和D之间可以连通,如果可以建立C到D之间的SSH连接,则A到B之间的通信可以由A-C-D通路完成,且通信过程会被加密(仅限C和D之间,A和C、B和D之间的通信不被加密)。图中的ABCD表示应用,可以部署在相同或者不同的物理机器上。
根据SSH连接建立的方向和数据传输方向的不同,可以分为本地转发(local forwarding)和远程转发(remote forwarding)。
如果应用的传输方向和SSH连接建立的方向相同,则称为本地转发,如上图中应用连接建立是从A到B,而SSH连接建立的方向是从C到D,实际的数据通路是A-C-D-B,可以理解为数据通过SSH隧道进行转发。反之,如果应用的传输方向和SSH连接建立的方向相反,则称为远程转发。上图中如果SSH连接的方向是从D到C时就是这种情况。
其实不管是应用连接还是SSH连接都是双向的,区分本地转发还是远程转发只是看建立连接的方向,一旦连接建立,数据的传输可以是双向的。之所以要有这种区分,是因为在实际的环境中开放SSH端口的应用所处的位置是有差别的:开放SSH端口的应用在远端附近,隧道建立后,在本地附近监听某个端口,数据转发到该端口,通过到SSH连接传输到远端;开放SSH的端口在本地附近,需要在远端反向主动发起连接建立隧道。无论何种方式的端口转发,发起端总在本地附近(图中的C)。
Linux下的SSH工具已经自带了端口转发功能,Window下有plink.exe程序可用(在putty包中),其它的GUI客户端,如securecrt也有端口转发功能。命令行的工具参数如下:
本地转发:ssh –L <local-port>:<remote-host>:<remote-port> ssh-host
远程转发:ssh –R <local-port>:<remote-host>:<remote-port> ssh-host
端口转发的建立在C上完成,根据SSH端口开放在D上还是C上,选择本地转发或者远程转发的方式。
除了以上两种方式之外,还有一种动态转发的方式,SSH服务器端收到应用消息后,由应用消息本身决定从SSH服务器连接到应用程序的端口,这种方式提供了通路中SSH一段的加密功能,SSH隧道充当SOCKS代理的作用。命令格式:
ssh –D <local-port> ssh-host
个人总结一下:
几种转发方式的共同点是先建立SSH连接,应用数据在此连接上进行加密传输。如果该SSH连接的两端正好处于防火墙内外,那么应用程序有可能通过这条SSH连接绕过防火墙限制。不同点是SSH连接建立的方向(和应用程序相同或者相反),以及应用数据穿过SSH隧道后,选择到达目的地的方式(固定端口或者动态端口)。