SSH跳板机与代理模式

安全外壳协议(Secure Shell Protocol,简称SSH)是一种加密的网络传输协议,可在不安全的网络中为网络服务提供安全的传输环境。SSH通过在网络中建立安全隧道来实现SSH客户端与服务器之间的连接。(摘自维基百科)接触过服务器的人都应该知道,可以使用SSH来远程控制服务器,但这实际上这项功能并不是SSH的专利,提出这种功能的协议是1969年RFC 15的Telnet协议。SSH还可以建立正向代理、反向代理,以及到服务器的Socks5代理,这些代理的安全性由SSH密钥保证(通常为RSA或者ECDSA)。理论上来说,通过线下传输密钥的方式可以有效保证客户端到服务器之间通信的安全性,且不会受到中间人攻击的影响。以下就来详解这三种代理模式:

在生产环境中,往往会遇到想要控制的服务器处于内网,此时只有一个被称为跳板机,或是堡垒机的电脑可以同时访问外部网络和内部网络。为了保证跳板机的安全性,有时跳板机不提供Shell访问,即默认Shell为nologin,此时不可通过先访跳板机,再访问目标服务器的方式来访问目标服务器。这时通过SSH提供的正向代理或是动态代理(Socks5代理)功能来解决问题。

使用Telnet以外功能

SSH的-N参数可以让启动SSH连接时不启动shell,从而避免访问到nologin直接终止连接的问题。如果使用的是PuTTY,则可在SSH选项内框选Don't start a shell or command at all来起到相同的效果。

正向代理

OpenSSH

正向代理的命令是-L,如果跳板机的IP地址为11.45.1.4,跳板机SSH用户为jump,在跳板机所处的内网中,目标服务器的IP地址为192.168.1.3,SSH服务端口号均为22,那么此时使用如下SSH命令:

ssh -N -L 1919:192.168.1.3:22 jump@11.45.1.4

此时如果访问本地的1919端口,即可被转发到远程的192.168.1.3的22端口。在这种情况下,如果对本地的1919端口使用SSH连接,也就是连接到了内网中的192.168.1.3电脑。

PuTTY

在PuTTY中,tunnels里设置Local并填写对应的本地和远程端口即可

反向代理

OpenSSH

反向代理的命令是-R,我们的假设与如上相同,命令如下

ssh -N -R 80:127.0.0.1:81 jump@11.45.1.4

此时如果访问跳板机的81端口,访问将会被转发至本机的80端口,即实现了内网穿透的功能,让跳板机所在内网的服务器可以访问本机资源(如果本机所在的是另一个内网的话)。

PuTTY

在PuTTY中,tunnels里设置Remote并填写对应的本地和远程端口即可

动态代理

OpenSSH

动态代理的命令是-R,我们的假设与如上相同,命令如下

ssh -N -D 1080 jump@11.45.1.4

此时在本机的1080端口启动了一个Socks5代理服务,通过这个代理服务器即可连接到跳板服务器从而访问内网。

PuTTY

在PuTTY中,tunnels里设置Dynamic并填写对应的本地端口即可

SSH通过Socks5代理连接

试想另一种情况,我们的跳板机本身处于一个必须要通过socks5代理(不妨设这个代理连接为19.19.8.10:1080)才能访问的网络环境中,也就是说我们需要通过socks5代理连接到跳板机,再通过跳板机连接到内网,此时需要如何操作呢?

首先分析通过socks5代理连接到SSH服务器的命令

ssh -o ProxyCommand="nc -X 5 -x 19.19.8.10:1080 %h %p" jump@11.45.1.4

这里的ProxyCommand调用了netcat工具来建立一条使用了Socks5协议的端口转发,之后再通过这个转发之后的端口连接到跳板机,该命令工作的具体原理不在本文讨论范围内。但是试图使用-J命令通过跳板机连接到目标服务器,再加上ProxyCommand,我们会发现命令并不能被正常运行。这时候使用OpenSSH的跳板服务器连跳的技巧,在用户目录的.ssh目录下编辑config文件,如果没有则新建一个,编辑以下内容:

host jump1
  HostName 11.45.1.4
  User jump
  ProxyCommand nc -X 5 -x 19.19.8.10:1080 %h %p

host dest
  HostName 192.168.1.3
  User username
  ProxyJump jump1

之后直接使用ssh dest即可通过socks5代理,经由跳板机连接到目标服务器。

Published At
Tagged with