【声明】本博客所有内容均为个人业余时间创作,所述技术案例均来自公开开源项目(如Github,Apache基金会),不涉及任何企业机密或未公开技术,如有侵权请联系删除
背景
上篇 blog
【Ubuntu】【远程开发】内网穿透:反向隧道建立(一)
分析了 SSH 建立反向隧道的关键选项 -R,并分析了 bind_address 的作用,下面继续
内网穿透
回到 -R 选项,还是第一种形式

bind_address上篇 blog 已经解释了port:公网端口,在远程服务器上监听的端口号host:主机 ip,这里直接填localhost即可,主机为本地服务器hostport:本地服务器上的端口(比如localhost:22是本地 SSH)
OK,再来看 -R 选项的详细描述,其功能可以在远程服务器(比如云主机)上监听一个端口,所有连到这个端口的流量,都会被 SSH 隧道转发回主动连接远程服务器的本地电脑里,举个形象点的比喻,就像在远程服务器上开一个门(端口),任何人敲这个门,SSH 就会通过加密隧道把请求转回到主动连接的本地机器上,连接到指定的服务

可以看到,其工作原理 就是 SSH 先在远程服务器上创建一个监听套接字 ,当有人连接这个端口时,SSH 就把这个连接通过已建立的加密隧道传回本地机器里,然后本地机器再根据指定的目标发起新的连接

如果想在服务器上监听特权端口的话,就必须用 root 用户登录服务器 ,关于特权端口的定义,可以参考 IANA 官方的端口分配策略(IANA 就是之前说过的负责分配互联网 IP 地址范围的机构)IANA Port Numbers

可以看到,端口范围被分成了三类
System Ports:范围0~1023,分配给系统级服务,比如HTTP/80,SSH/22等,一般和root权限绑定User Ports:范围1024~49151,可以注册给用户使用Dynamic/Private Ports:范围49152~65535,临时使用
所以可以看出来,端口号小于 1024 的是特权端口,比如 80,443,如果想在服务器上监听这些特权端口,就得用 root 用户登录服务器,不然只能用 ≥1024 的端口
-R 选项中,比较关键的,还有下面这段描述

默认情况下,SSH 在远程服务器上监听的 TCP 端口,只会绑定到回环地址 127.0.0.1,也就是 bind_address 为空的情况,bind_address 为空的情况,上篇 blog 【Ubuntu】【远程开发】内网穿透:反向隧道建立(一) 已经详细讲了,这样主要是出于安全考虑,防止无意中把内网服务暴露到公网
这个默认行为可以通过指定 bind_address 来覆盖(也就是改变绑定的 IP 地址),比如 0.0.0.0:(IPv4),::: (IPv6),*:(IPv4+IPv6),实践中几乎都用 *:或 0.0.0.0:,允许所有 IP 访问
这里最关键的是后面这句话,只有当服务器的 sshd 配置中启用了 GatewayPorts,指定的 bind_address(比如 0.0.0.0: 或 *:)才会生效,否则会被忽略,仍只绑定 127.0.0.1 回环地址
关于 GatewayPorts 的配置,在终端输入
bash
man 5 sshd_config
可以打开 sshd 配置的用户说明,找到 GatewayPorts 选项关键字

GatewayPorts 这个选项控制是否允许其他远程主机 连接到为客户端 设置的端口转发服务,这里有两个名词,一个是其他远程主机,一个是客户端,画个图就明白了

在准备搭建的内网穿透环境中,其他远程主机就是在外地的用户,客户端就是内网的服务器,云服务器作为 server 只是做一个转发功能,所以这里的
remote hosts:指除了云服务器和内网服务器以外的其他机器,比如在外地的用户ports forwarded for the client:这个词很常见了,在-R选项中,指内网服务器通过反向隧道在 SSH 云服务器上开启的监听端口
OK,本篇先到这里,如有疑问,欢迎评论区留言讨论,祝各位功力大涨,技术更上一层楼!!!更多内容见下篇 blog
【Ubuntu】【远程开发】内网穿透:反向隧道建立(三)