0%

ssh端口转发

下午闲了一会儿,想起前年实习搬服务器的时候,当时公司的服务器,被我们安装到某个地方的内网之后,没有外网IP只是通过NAT访问外网,但是公司服务器可以直接主动登陆上去操作,当时我还以为是端口转发,或者VPN,两个月之后运维主管离职,从某团空降来一个运维领导,试了一下iptables的端口转发。。。然后采用了VPN,无疑我感觉这很low逼。所以这项神秘的技术一直被我记到现在。。

下边先介绍下ssh的端口转发

SSH 会自动加密和解密所有 SSH 客户端与服务端之间的网络数据。但是,SSH 还同时提供了一个非常有用的功能,这就是端口转发。它能够将其他 TCP 端口的网络数据通过 SSH 链接来转发,并且自动提供了相应的加密及解密服务。这一过程有时也被叫做“隧道”(tunneling),这是因为 SSH 为其他 TCP 链接提供了一个安全的通道来进行传输而得名。例如,Telnet,SMTP,LDAP 这些 TCP 应用均能够从中得益,避免了用户名,密码以及隐私信息的明文传输。而与此同时,如果您工作环境中的防火墙限制了一些网络端口的使用,但是允许 SSH 的连接,那么也是能够通过将 TCP 端口转发来使用 SSH 进行通讯。总的来说 SSH 端口转发能够提供两大功能:

  • 加密 SSH Client 端至 SSH Server 端之间的通讯数据。

  • 突破防火墙的限制完成一些之前无法建立的 TCP 连接。

本地端口转发

格式 ssh -L <local port>:<remote host>:<remote port> <SSH hostname>

例如 我们将本地8000端口转发到提供LDAP服务的主机Ldapserver_host1 的389端口(ldap_server默认端口)可以这样写

ssh -L 7001:localhost:389 LdapServer_host1

这个时候netstat -tpln

tcp        0      0 127.0.0.1:7001              0.0.0.0:*                   LISTEN           15889/ldap

本地端口已经起来了 ,但是只允许在本机访问,这个时候区别的机器用 nmap扫描是看不到7001端口的

但是怎么让别的主机也可以使用呢?

SH 同时提供了 GatewayPorts 关键字,我们可以通过指定它与其他机器共享这个本地端口转发。

ssh -g -L <local port>:<remote host>:<remote port> <SSH hostname> 

这个时候可以使用ssh 提供的Gateway Port关键字-g

ssh -g -L 8001:0.0.0.0:22 localhost

我们把这台主机的22端口转发到本机的8001端口

然后这时候我们可以到另一台机器上 nmap发现本机 8001端口已经打开了 然后试下 ssh -p 8001 是可以登得上的。

远程端口转发

其实这就是所谓的ssh反向隧道

主机介绍:

主机名 是否有外网地址 地址 用户
server1 123.21.201.189 fanquqi
server2 localhost fanquqi
server3 localhost fanquqi

主要参数

  • -R 反向代理
  • -N 不执行远程指令
  • -f 后台执行

命令格式

ssh -NfR 6789:localhost:22 fanquqi@123.21.201.189

在server2上执行上述命令,执行完输完密码之后,我们可以在server1上看下端口 正常6789端口已经是监听了的。

然后 我们可以在 这台外网地址机器上执行

ssh -p 6789 fanquqi@localhost

即可连接到连接到NAT后面的server2。。

可以看到上面列出了三台机器,第三台还没有用到。我们来用一下,试下让两台没有外网的机器建立连接。

先杀掉server1上6789端口。
server3上执行

ssh -fN -R 123.21.201.189:6789:localhost:22 fanquqi@123.21.201.189

然后在server1上确认6789打开

这时候在server2上就可以连接server3了
只需要运行

ssh -p 6789 fanquqi@123.21.201.189

即可。其实不止server1,是任何有网络的机器

其实我们还可以把公钥互相传一下 就不用来回输密码了。 如果nat后面那台主机不在手边,经常上不去 建议使用autossh提供隧道断开自动重连功能。或者更改ssh配置文件~/.ssh/config

ServerAliveInterval 
ServerAliveCountMax 

更改如上两个参数

第一个参数表示如果服务器(外网)没数据发来则过一段时间客户端(内网)会发送一个空包到服务器,以保持tcp长连接,默认值为0,表示不会发心跳包,这里可以设置一分钟。。
第二个参数表示,如果服务器(内网)没有收到心跳包指定次数,就中断连接。可以设置为无限大。