一个简单的 Node.js 内网穿透隧道演示项目,展示了如何通过隧道将公网请求转发到内网服务。
本项目实现了一个基础的内网穿透功能,允许公网用户通过隧道服务器访问内网服务。这是一个概念验证(PoC)项目,帮助理解内网穿透的核心原理。
公网用户 (请求 :8080)
↓
隧道服务器 (:9000 隧道端口, :8080 公网端口)
↓ (通过隧道)
隧道客户端
↓
内网服务 (:3000)
-
tunnel-server.ts: 隧道服务器
- 端口 9000: 接收内网客户端的隧道连接
- 端口 8080: 接收公网 HTTP 请求并转发到隧道
-
tunnel-client.ts: 隧道客户端
- 连接到服务端的 9000 端口建立隧道
- 接收来自服务端的请求并转发到本地 3000 端口
- 具备自动重连机制
-
server.ts: 内网 Web 服务
- 监听 3000 端口
- 提供实际的 Web 服务
bun install需要开启 3 个终端窗口 分别运行不同的服务:
bun run src/server.ts预期输出:
Server running at http://127.0.0.1:3000/
bun run src/tunnel-server.ts预期输出:
【服务端】隧道监听在端口 9000
【服务端】公网 HTTP 监听在端口 8080
bun run src/tunnel-client.ts预期输出:
【客户端】成功连接到服务端,隧道已打通。
同时,终端2(隧道服务器)应该显示:
【隧道】内网客户端已连接,隧道建立成功。
在第 4 个终端窗口或浏览器中发起请求:
使用 curl 测试:
curl http://localhost:8080/test预期输出:
Request forwarded to internal network (PoC)
各终端日志:
-
终端1(内网服务) 应显示:
url: /test method: GET headers: { ... } -
终端3(隧道客户端) 应显示:
【客户端】收到公网请求数据,转发到内网服务... -
终端2(隧道服务器) 应显示:
(无额外日志,或可添加调试日志)
✅ 成功标志:
- 三个服务都正常启动
- 隧道客户端成功连接到服务器
- 通过 8080 端口的请求能到达 3000 端口的内网服务
- 内网服务能收到并打印请求信息
❌ 常见问题:
- 503 错误: 隧道未建立,检查客户端是否连接成功
- 连接被拒绝: 确保服务启动顺序正确(先启动服务器,再启动客户端)
- 端口占用: 确保 3000、8080、9000 端口未被占用
可以使用以下一键测试(在不同终端):
# 终端1
bun run src/server.ts
# 终端2
bun run src/tunnel-server.ts
# 终端3
bun run src/tunnel-client.ts
# 终端4 - 发送多个测试请求
curl http://localhost:8080/api/users
curl http://localhost:8080/api/data?id=123
curl -X POST http://localhost:8080/api/create -d '{"name":"test"}'- 运行时: Bun v1.3.0+
- 语言: TypeScript
- 核心模块: Node.js
net,http
存在的限制:
- 未实现请求-响应完整的双向通信
- 缺少请求 ID 匹配机制
- 没有身份验证和加密
- 未处理并发请求
- 错误处理不完善
通过本项目你可以学习到:
- TCP Socket 编程基础
- HTTP 协议的底层实现
- 内网穿透的核心原理
- 数据转发和代理机制
使用开发模式(自动重载):
bun run devMIT
This project was created using bun init in bun v1.3.0. Bun is a fast all-in-one JavaScript runtime.