手撕TCPMux单端口多路复用以及小记SSH隧道
发布于2025-07-26 03:37:31,更新于2025-07-28 01:10:04,标签:devops tcp 文章会持续修订,转载请注明来源地址:https://meethigher.top/blog我的公网服务只有一个端口,我想让TCP连接也能实现类似Nginx的HTTP反向代理的功能,可以通过一个端口将内网的服务全部转发出来。
这就涉及到一个概念了—— TCP Port Service Multiplexer (TCPMux)。
一、手撕TCPMux
1.1 概念
本节参考RFC 1078 - TCP port service Multiplexer (TCPMUX)
RFC 1078 提出了一种机制:访问任何TCP服务,只要访问端口1即可。
工作流程(极简版)
1.) 客户端 → 服务器 1 号端口:发送SSH<CRLF>
2.) 服务器 检查本地有没有叫 “SSH” 的服务
- ✅ 有:回
+ 非必填的消息说明<CRLF>
,然后直接把连接交给真正的 SSH 程序。 - ❌ 无:回
- 非必填的消息说明<CRLF>
并断开连接。
3.) 特殊服务名
- 发送
HELP
:服务器列出它能转接的所有服务名,然后礼貌地挂电话。
这是理论定义上的TCPMux。
1.2 实现
我的需求就像最初提到的。
我的公网服务器只有一个端口可对外。我希望通过这一个端口,将公网服务器的所有TCP服务都转发出来。这就需要使用到类似TCPMux的工具了。
该功能使用SSH隧道即可实现,可以参照我下文记录。但是由于服务器的SSH隧道自身有限制,因此只得弃用,FRP也可以,但最后还是决定自己手撕一个。
源码
- meethigher/tcp-reverse-proxy: 基于Vert.x实现的网络库。支持HTTP反向代理、TCP反向代理、TCP内网穿透、TCP单端口多路复用
- meethigher/http-proxy-boot: JDK8开箱即用的反向代理工具。支持HTTP反向代理、TCP反向代理、TCP内网穿透、TCP单端口多路复用
实现思路时序图
实际场景使用示例
二、SSH隧道
2.1 开启SSH隧道
cat /etc/ssh/sshd_config
,修改如下参数
1 | # 允许tcp转发,该项决定 -L / -R / -D 是否能使用转发。 |
systemctl restart sshd
,重启服务即可生效
2.2 三种模式
2.2.1 本地端口转发(TCPMux)
场景
- 公司内网服务器有 MySQL(10.0.0.20:3306),但是公司只有一台机器可通过 SSH (10.0.0.30:22)访问
- 你笔记本在家,需要连接 MySQL 开发。
在你的笔记本上执行如下命令
1 | # -p 22,指定10.0.0.30机器的ssh端口 |
该模式对应meethigher/tcp-reverse-proxy的TCP单端口多路复用
2.2.2 远程端口转发(内网穿透)
场景
- 你笔记本有 MySQL(127.0.0.1:3306),你有一台公网服务器 SSH (10.0.0.30:22)
- 你要把你笔记本你的 MySQL,通过公网服务器穿透出去,通过公网服务器的 3306 端口即可访问你的 MySQL
在你的笔记本上执行如下命令
1 | # -p 22,指定10.0.0.30机器的ssh端口 |
该模式对应meethigher/tcp-reverse-proxy的TCP内网穿透。
2.2.3 动态端口转发(Socks5代理)
场景
- 评论时,记录IP。
- 你希望使用你的笔记本,通过你的另一个地区的服务器(10.0.0.30:22)进行访问,以便达到你评论的IP不是你的真实IP的目的。
在你的笔记本上执行如下命令
1 | # -p 22,指定10.0.0.30机器的ssh端口 |
在浏览器发起请求时,配置Socks5代理即可。此处我以curl为例。
1 | # winddows使用set,linux使用export |
打赏