隧道原理

隧道是一种把一种网络协议封装进另外一种网络协议进行传输的技术。这里我们研究ssh隧道,所以所有的网络通讯都是加密的。又被称作端口转发,因为ssh隧道通常会绑定一个本地端口,所有发向这个端口端口的数据包,都会被加密并透明地传输到远端系统。

隧道的类型

ssh隧道有3种类型:
  • 动态端口转发(Socks 代理)
  • 本地端口转发
  • 远端端口转发

ssh端口转发常用选项

-N #告诉SSH客户端,这个连接不需要执行任何命令。仅仅做端口转发
-f #告诉SSH客户端在后台运行
-L #本地转发
-R #远程转发
-D #动态转发
-C #数据压缩

动态端口转发

主机名 IP地址
A 111.111.111.111
B 111.111.111.112
C 192.168.0.4,91.85.113.211
D 102.168.0.1/24

假设A只能访问B,B只能访问C,C能访问所有,那么我们要从A访问C和D就只需要在B和C之间做一个动态转发,就可以把B作为代理来用,这样只要能访问B的机器都可以用B来设置代理。如果只想B本机本地使用代理,则本地地址绑定只需要设置为127.0.0.1

在B机器上执行如下代码开启动态转发

ssh -f -N -D 0.0.0.0:1080 [email protected] #如果配置了秘钥则无需输入,如果没秘钥则需要输入密码验证
#本地代理
ssh -f -N -D localhost:1080 [email protected]

注意点

如果主机C的ssh默认端口不是22,那我们需要在代理机上的.ssh/config目录中设置port=4521来实现设置默认连接端口
保持长时间连接:
有些路由器会把长时间没有通信的连接断开。SSH客户端的TCPKeepAlive选项可以避免这个问题的发生, 默认情况下它是被开启的。
如果它被关闭了,可以在ssh的命令上加上-o TCPKeepAlive=yes来开启。

本地端口转发

使用场景
假设X网络(192.168.18.0/24)有主机A(192.168.18.100),
Y网络(192.168.2.0/24)有主机B(192.168.2.100)和主机C(192.168.2.101),
已知主机A可以连接主机B,但无法连接主机C。A主机需要访问C主机的VNC服务(5900端口)
在A主机上建立本地转发端口5901  
ssh -L 5901:192.168.2.101:5900 [email protected] 
然后本地vnc客户端通过5901端口打开c主机的vnc服务 
open vnc://localhost:5901

通过SSH隧道,将一个远端机器能够访问到的地址和端口,映射为一个本地的端口。

命令格式:

ssh -L 本地端口:远程主机地址:远程主机开放端口 中转主机地址

示例:

ssh -L 1314:192.168.4.113:80 192.168.4.101 -Nf
#当访问本机的1314的端口时,被加密后转发到192.168.4.101的ssh服务,再解密被转发到192.168.4.113:80

优点:无需设置代理

缺点:每个服务都需要配置不同的端口转发

注意点

共享这个本地端口转发需要加上-g参数,或者在sshd_config中添加GatewayPorts yes并重启sshd服务


远程转发

使用场景

主机名 ip地址
A 192.168.0.17
B 95.169.18.91
C 98.142.141.59

注意点 \
A机器处于在层层NAT之下的内网;B机器拥有公网IP(称为IpB),可以被任意机器直接访问;A机器希望将本地端口PortA映射到B机器的端口PortB上,使得任何人访问B机器PortB端口等效于访问A机器的PortA端口。配置方法B机器配置要求B机器能够运行sshd之类的可以进行ssh登录的软件。ssh的配置要添加:GatewayPorts=yes,AllowTcpForwarding=yes然后清理掉所有ssh的会话进程,重启ssh服务。如果不是用的root用户建立隧道,那么在B机器上只能监听本地127.0.0.1端口。

需求说明

A机器处于在层层NAT之下的内网;B机器拥有公网IP(称为IpB),可以被任意机器直接访问;A机器希望将本地端口PortA映射到B机器的端口PortB上,使得任何人访问B机器PortB端口等效于访问A机器的PortA端口。

配置方法

B机器配置:

要求B机器能够运行sshd之类的可以进行ssh登录的软件。ssh的配置要添加:
GatewayPorts yes,AllowTcpForwarding yes.然后清理掉所有ssh的会话进程,重启ssh服务

这样使得B机器可以启用0.0.0.0的监听地址,否则B机器只能监听来自127.0.0.1的地址。

A机器配置

ssh的命令参数如下。也在-R前可以添加-C -f -N -g,使得ssh程序在后台运行。

ssh -R 0.0.0.0:PortB:127.0.0.1:PortA root@IpB
#具体案例:
ssh -fN -g -R 0.0.0.0:1027:127.0.0.1:22  [email protected]

然后在B机器上运行如下命令,即可检验是否生效。

netstat -lnp | grep PortB

这样就实现了需求的功能,即访问PortB等效于访问PortA,在C上执行

ssh [email protected] -p 1027 #即可连接到A机器的22端口,即实现了A端口22到B端口1027的映射