SSH隧道

一、本地ssh隧道
使用场景:
你自己的电脑不能访问一个国外的ftp(10.10.10.10)。你有一台服务器(20.20.20.20),服务器可以访问国外的ftp。你和你的服务器是可以互通的。
使用ssh的隧道功能来实现互通,在国外的ftp服务器上执行命令:
ssh -p 1022 -CfNg -L 2121:10.10.10.10:21 root@20.20.20.20
现在ssh隧道的2121端口,就能连接到10.10.10.10的21端口了,本地SSH隧道访问方式 (在服务器上执行):
ftp localhost:2121  
参数说明:
-p: 用来建立隧道的中间机器的ssh登陆端口号
-C:压缩数据传输
-f:ssh客户端在后台执行
-N:不执行脚本或命令,仅进行端口转发
-g:在-L/-R/-D参数中,允许远程主机连接到建立的转发端口,如果不加这个参数,只允许本地主机建立连接。
-L:做本地映射端口,被冒号分割的三个部分含义分别是:
需要使用的隧道端口号
需要访问的目标机器IP地址
需要访问的目标机器端口
用来建立隧道的中间机器的用户名和IP地址

二、远程ssh隧道
由于公司内网服务器不允许外网访问,内网服务器能访问外网,而有时候需要在外网去管理内网的服务器。
实现方式需要有一台外网服务器(20.20.20.20),内网服务器IP(192.168.10.10)
命令(以下三条命令都是开启远程ssh隧道命令):
ssh -p 1207 -CfNg -R 1022:127.0.0.1:22 root@20.20.20.20   #该命令在内部服务器上执行(本机的22端口映射到20.20.20.20的1022端口)
ssh -p 1207 -R 1022:127.0.0.1:22 root@20.20.20.20    #该命令在内部服务器上执行
ssh -p 1207 -CfNg -R 1022:192.168.10.10:22 root@20.20.20.20    #该命令在内网任一主机上执行时,执行命令的主机必需和192.168.10.10能互通(192.168.10.10的22端口映射到20.20.20.20的1022端口)
-R:
该参数的三个部分的含义分别是:
映射到远程机器使用的端口(1022)
需要映射的内部机器的IP地址(127.0.0.1)
需要映射的内部机器的端口(22)
最后的参数是登陆外网服务器的用户名和IP
在外网服务器上访问内网服务器命令
ssh root@localhost -p 1022

三、SSH建立socket服务
如果我们需要借助一台中间服务器访问很多资源,一个个映射显然不是高明的办法。幸好,SSH客户端为我们提供了通过SSH隧道建立SOCKS服务器的功能
通过下面的命令我们可以建立一个通过20.20.20.20的SOCKS服务器
ssh -N -f -D 1080 20.20.20.20 #将1080端口绑定在127.0.0.1上
ssh -N -f -D 0.0.0.0:1080 20.20.20.20 #将1080端口绑定在0.0.0.0上

四、SSH隧道使用问题及解决办法
1、自动重连
隧道可能因为某些原因断开,例如重启,长时间没有数据通信而被路由器切断等等。因此我们可以使用简单的循环或supervisor来控制隧道的重新连接。重连时要避免要求输入密码而卡死程序,对于密码登陆可以采用sshpass或免密登陆方式。如果通过其他程序控制隧道连接,应当避免将SSH客户端放到后台执行,也就是去掉-f参数。
2、保持长连接
有些路由器会把长时间没有通信的连接断开。SSH客户端的TCPKeepAlive选项可以避免这个问题的发生,默认情况下它是被开启的。如果它被关闭了,可以在ssh的命令上加上-o TCPKeepAlive=yes来开启。
另一种方法是,去掉-N参数,加入一个定期能产生输出的命令。例如: top或者vmstat。
ssh -R 2222:localhost:22 root@20.20.20.20 "vmstat 30"
3、检查隧道状态
有些时候隧道会因为一些原因通信不畅而卡死,例如:由于传输数据量太大,被路由器带入stalled状态。这种时候,往往SSH客户端并不退出,而是卡死在那里。一种应对方法是,使用SSH客户端的ServerAliveInterval和ServerAliveCountMax选项。 ServerAliveInterval会在隧道无通信后的一段设置好的时间后发送一个请求给服务器要求服务器响应。如果服务器在 ServerAliveCountMax次请求后都没能响应,那么SSH客户端就自动断开连接并退出,将控制权交给你的监控程序。这两个选项的设置方法分别是在ssh时加入-o ServerAliveInterval=n和-o ServerAliveCountMax=m。其中n, m可以自行定义。

五、将映射端口绑定到外网地址上
将映射端口绑定到127.0.0.1,在web服务器上执行命令:
ssh -R 8080:localhost:80 root@host147.aws.example.com
默认情况下,OpenSSH映射的端口只能绑定在127.0.0.1这个接口上。但是,可以修改GatewayPorts选项来控制它
vim /etc/ssh/sshd_config
#仅允许服务器主机连接到远程转发的端口
GatewayPorts no
#允许任何人都可以连接到转发的端口
GatewayPorts yes
#客户端指定可以连接到转发端口的IP地址
GatewayPorts clientspecified
命令如下:
ssh -R 52.194.1.73:8080:localhost:80 root@host147.aws.example.com    #仅允许52.194.1.73连接到转发端口8080。

注:
    在任一机器上执行开启远程隧道命令时,需要开远程隧道的机器能访问到被代理的服务器
    如在192.168.20.10机器上执行下面这条命令时需要192.168.20.10和192.168.10.10这两个IP能互通
    ssh -R 8080:192.168.10.10:80 root@8.8.8.8

参考链接:
       https://www.ssh.com/ssh/tunneling/example
       https://www.mls-software.com/opensshd.html      #openssh for windows
       https://github.com/PowerShell/Win32-OpenSSH/releases    #openssh for windows
       https://www.cnblogs.com/f-ck-need-u/p/10482832.html       # SSH隧道:端口转发功能详解

posted @ 2020-12-14 23:47  風£飛  阅读(331)  评论(0编辑  收藏  举报