【Cryptography】ssh的本地端口转发与远程端口转发
原因
下午上密码学,看到讲解ssh端口转发的内容,书中讲的实在太模糊了,于是上网找相关内容自学
本文实现目标
1、ssh本地端口转发讲解
2、ssh远程端口转发讲解与windows上演示
正文
1、ssh本地端口转发
适合的状况
本地主机hostLocal(图中左边)无法访问私网主机hostPrivate(图中右边)本地主机可以访问云服务器私网主机可以访问云服务器云服务器可以访问私网主机(非常重要啊,能和下面的远程端口转发区分开)云服务器无法访问本地主机
为了实现的目标
- 让
本地主机可以访问私网主机 
思路
- 因为
本地主机可以连接到云服务器,那可以借助云服务器,近一步访问到私网主机 
整体流程
- 在
本地主机设置一个端口(假如为)2233(目的是,以后本地主机可以通过端口2233访问私网主机) - 给目标
私网主机设置一个端口(假如为)7788(目的是:可以在此端口运行web服务网页,当然也可以设置为FTP协议对应的21端口)。当然,私网主机也有一个私网ip嘛,假如为52.77.56.16。- 先明确一点:
云服务器是可以访问到这个私网ip:52.77.56.16,以及对应的7788端口 
 - 先明确一点:
 云服务器也有公网ip(假如为)39.45.55.12。而且开放了默认的、用来给ssh连接的端口22,当然这个端口也可以修改成其它的号码- 本地主机
运行ssh命令 - 本地主机访问2233端口,会访问到私网主机的web服务。完成
 
注意
- 虽然,我这里叫私网主机为“私网”,但这个私网,可以是任何的、相对于本地主机来说“不能访问的网络”。如:国内用户要翻墙就是这个原理
 - 所以,我上面的私网Ip,并没有写一个“局域网ip”,而是一个公网主机Ip,但这个公网主机可能无法直接连接
 
原理
本地主机通过ssh协议连接上云服务器的公网ip:端口22,让本地主机与云服务器创建了一条隧道,并且本地主机的ssh将监听2233端口收到的所有请求。本地主机如果对2233端口进行访问,ssh将这个请求会通过隧道,转发到云服务器。云服务器再将这个请求,转发到私网主机的7788端口- 私网主机接收
请求,将回应发送到云服务器 - 云服务器再将
回应,通过隧道转发到本地主机 
至此,所有的理论就解释完成。
ssh命令实操
这条命令在本地主机执行
1  | ssh -L [本地主机ip:]2233:52.77.56.16:7788 root@39.45.55.12  | 
这个看着十分混乱,对应的解释为
| 本地ip | 本地端口 | 私网主机ip | 私网主机端口 | 云服务器ip | 
|---|---|---|---|---|
| 可选的 | 2233 | 52.77.56.16 | 7788 | root@39.45.55.12 | 
| 自定义端口 | 必须是云服务器能访问的ip | 自定义端口 | root是用户名 | 
- 这个私网主机是
相对云服务器而言的,如果这个私网主机是云服务器里面运行的docker程序,那私网ip应该是localhost。再比如,下面使用本地转发翻墙时,也会用localhost。 
结果
- 当
本地主机访问2233端口时,相当于访问了私网主机的7788端口服务 
2、ssh远程端口转发
适合的状况
任意主机(图中左侧)无法访问私网主机(图中右边)任意主机可以访问云服务器私网主机可以访问云服务器云服务器无法访问私网主机(这一条与上面的本地端口转发不同)云服务器无法访问任意主机
为了实现的目标
- 让
任意主机可以访问私网主机 
思路
- 因为云服务器无法访问私网主机,无法做本地端口转发,但私网主机可以连接云服务器,于是,还是可以让云服务器成为跳板
 
整体流程
私网主机设置一个端口开放为4000(后面会在此端口开放web程序或其它传输服务)云服务器的公网ip如39.45.55.12,并设置一个端口为6789。那39.45.55.12:6789是一个公网ip+端口,可以让任意主机访问- 在
私网主机运行ssh命令(后面会配置) - 在
私网主机的4000端口开放一个web服务,如运行了一个网页 - 在
任意主机打开浏览器,输入39.45.55.12:6789,会访问在私网主机运行的web服务。完成 
原理
私网主机通过ssh协议连接上云服务器的公网ip:端口22,让任意主机与云服务器创建了一条隧道,并且私网主机的ssh将监听4000端口收到的所有请求,注意:私网主机在端口4000开放了一个web服务- 当
任意主机访问云服务器的39.45.55.12:6789时,云服务器会将任意主机的请求通过上面建立的隧道转发到私网主机的4000端口 私网主机再将响应回复给云服务器云服务器再将响应转发到任意主机
ssh命令
因为这条命令是在私网主机上运行,所以,localhost是指私网主机的本地网络服务
1  | ssh -R [远程ip]:6789:localhost:4000 root@39.45.55.12  | 
对应的解释为
| 云服务器端口允许访问的ip | 云服务器端口 | 私网主机ip | 私网主机端口 | 云服务器ip | 
|---|---|---|---|---|
| 0.0.0.0 | 6789 | localhost | 4000 | root@39.45.55.12 | 
| 让所有ip都可以访问 | 自定义端口 | 不用修改 | 自定义端口 | root是用户名 | 
注意
- 
如果云服务器是linux,需要在私网主机上设置
[远程Ip]为0.0.0.0,因为默认情况下,linux不允许各种外网的ip都能访问本地的网络服务。 - 
另外,需要在云服务器上修改
sshd_config,将里面的GateWayPort为yes,如下图 
1  | vim /etc/ssh/sshd_config  | 
结果
- 当
任意主机访问公网ip+端口39.45.55.12:6789时,相当于访问了私网的4000端口服务- 如下图所示,我在
私网主机打开了hexo的web服务,理伦上来说,只能私网主机自己能访问。但经过上面的远程端口转发后,任意主机访问公网后,也能访问私网的web服务 
 - 如下图所示,我在
 
两种转发的用处
本地端口转发
- 最直接的,做
正向代理,翻墙 - 如果把上面“本地端口转发”的教程中,“私网”修改成“国外网”,私网主机Ip修改成国外网的ip,那……不是就相当于,国内的主机,通过云服务器访问国外网吗???(当然这个云服务器要可以访问国外网)
 
ssh翻墙举例
如果我们的翻墙服务器的地址是123.222.111.54,用户名是ss,翻墙服务器开放的端口是1111,使用下面的命令:
1  | ssh -L 2233:localhost:1111 ss@123.222.111.54  | 
我们就可以将我们本地的2233端口映射到翻墙服务器的端口1111上,服务器上无需安装其它服务即可实现翻墙。
当然,还需要将自己浏览器的代理,设置成使用本地2233端口。
我推荐用SwitchyOmega这个浏览器插件,安装好这个插件后,配置如下图即可,端口要自行修改。
注意
但这种方式并不真正的安全,很早前就被GFW能检测到,只有万不得已的情况下使用
- 这条命令中,使用的是localhost,表示“相对于翻墙服务器的localhost”其实就是
翻墙服务器自己的ip。 - ssh翻墙相关教程:https://www.codewoody.com/posts/11710/
 - 如果想看其它翻墙方式,我的另一篇文章"v2ray安装":https://blog.lthero.cn/2022/05/20/v2ray-install/
 
远程端口转发
- 可以在本地电脑上
部署一些web应用,在本地电脑执行上面的ssh命令(注意开放好服务器的对应端口和本地电脑的端口) 
随后,任意电脑或手机就可以直接访问云服务器,间接地访问本地电脑的web服务,这应该是内网穿透吧。
并且,用了远程端口转发后,
服务器其实根本没有运行什么web服务,只是个网络转发工具
- 
家用的NAS,应该可以通过这种方式,让远程的各种设备访问家里的硬盘
 - 
关于搭建个自己的【个人网盘】,可以看我的另一篇文章 https://blog.lthero.cn/2022/06/17/Frp-Mount-Windows-Share/
 
云服务器充当的角色
本地端口转发
- 在本地端口转发中,云服务器应该是
正向代理服务器,因为需要本地手动设置代理的服务器地址和真正想要访问的地址。 
远程端口转发
- 在远程端口转发中,云服务器是
反向代理服务器,因为真正访问云服务器的手机或电脑,不知道自己访问的是代理服务器,以为访问的就是真正的web服务器(或其它服务)。而且,这些手机或电脑无需做任何设置。 
还有个透明代理的概念啊,这里并没有用上……
下面是转载自阮一峰
SSH其它的参数
N参数
表示只连接远程主机,不打开远程shell;T参数,表示不为这个连接分配TTY。这个两个参数可以放在一起用,代表这个SSH连接只用来传数据,不执行远程操作。
1  | ssh -NT -D 8080 host  | 
f参数
表示SSH连接成功后,转入后台运行。这样一来,你就可以在不中断SSH连接的情况下,在本地shell中执行其他操作。
1  | ssh -f -D 8080 host  | 
要关闭这个后台连接,就只有用kill命令去杀掉进程。
参考
b站up主DavyCloud的讲解:https://www.bilibili.com/video/BV1C7411P7Er?p=1
阮一峰ssh解读:https://www.ruanyifeng.com/blog/2011/12/ssh_port_forwarding.html











