[点晴永久免费OA]stun_max:一个免费开源的 P2P 打洞工具,让两台电脑直接互联

你有没有遇到过这种情况:想远程连一下家里的电脑,结果发现没有公网 IP。用 TeamViewer 嫌慢,用 frp 要买服务器,用 ZeroTier 又被墙。
我就想:能不能让两台电脑直接连上,不经过任何中间服务器?
于是我花了几个小时,用 Go 写了 STUN Max —— 一个 P2P 打洞 + 端口转发工具。两台电脑加入同一个「房间」,自动打洞直连,转发任意端口。
· · ·
它能做什么
一句话:把远端机器的任意端口,映射到你本地。 中间走 P2P 直连,不经过服务器。
比如:
• 远程桌面:转发同事电脑的 3389 端口,直接 RDP 连过去
• 访问内网服务:转发公司 NAS 的 5000 端口到本地
• 调试远程接口:转发服务器的 8080 到 localhost

▲ 图 1:STUN Max 整体架构
打洞是怎么实现的
NAT 穿透这事,说起来简单,做起来全是坑。我的方案分四步:
第一步:STUN 发现公网地址
每个 client 启动后,向 STUN 服务器发一个 UDP 包。STUN 服务器告诉你:「外面的世界看到你的地址是 1.2.3.4:5678」。这就是你的公网映射地址。
第二步:交换端点 + 打洞
两个 client 通过信令服务器交换各自的公网地址,然后同时向对方发 UDP 包。这就是经典的「UDP Hole Punching」—— 双方同时往对方的 NAT 上「戳洞」。
我做了一些优化:20 个 PUNCH 包 / 500ms 快速突发,对 Symmetric NAT 还会用 Birthday Attack(8 个额外 socket 并行打洞)和端口预测。
第三步:TCP 直连升级
这是我踩了最多坑才想明白的一步。一开始我直接用 UDP 传隧道数据,结果丢包、乱序、加密竞态,各种问题。
UDP 不保证顺序,不保证到达。用它传 TCP 流数据,就像用卡车运水——洒一路。
最终方案:UDP 打洞成功后,在同一个 NAT 映射上建立 Direct TCP 连接。TCP 天然提供可靠传输 + 有序 + 流控。隧道数据走这条 TCP,稳如老狗。
第四步:自动 Relay 兜底
如果打洞失败(比如双方都是 Symmetric NAT),数据自动走 WebSocket Relay 中继。用户无感知,只是速度慢一点。

▲ 图 2:打洞 + TCP 升级完整流程
· · ·
踩过的坑
坑 1:UDP 分片导致数据乱序
一开始我把 64KB 的 TCP 数据分成 53 个 1200 字节的 UDP 包发出去。接收端每收到一个就直接写入 TCP。结果 UDP 包乱序到达,TCP 流就废了。HTTP 响应头都是乱码。
教训:UDP 不是 TCP 的替代品。要可靠传输,就用 TCP。
坑 2:加密密钥交换的竞态条件
打洞成功后我用 X25519 ECDH 交换密钥。问题是:A 发 KEY 给 B,B 立刻有了加密能力就开始发加密数据。但 A 还没收到 B 的 KEY_ACK,A 把加密数据当明文写入 TCP —— 全是垃圾。
内网尤其严重,因为延迟太低,KEY 和数据几乎同时到达。
坑 3:stun_info 覆盖已连接 peer 的地址
每次 peer 列表变化,都会重新交换 stun_info。如果已经打洞成功的 peer 地址被覆盖,接收端按新地址查加密密钥——查不到——解密失败——写入垃圾——断开。
修复很简单:if pc.Mode == "direct" { return } —— 已连接的 peer 忽略新的 stun_info。
· · ·
怎么用
● ● ● Bash
# 1. 部署信令服务器
./stun_max-server --addr :8080 --web-dir ./web
# 2. 两台电脑分别连接
./stun_max-cli --server ws://your-server:8080/ws \
--room myroom --password secret --name laptop-a
# 3. 转发端口
> forward laptop-b 127.0.0.1:3389
# 现在 localhost:3389 就是对方的远程桌面
也有 GUI 版本(Gio UI),Windows 和 Mac 都支持。连接信息自动保存,下次启动直接恢复。
· · ·
一些数字
8145
行 Go 代码
31
个源文件
12
次迭代修复打洞稳定性
· · ·
写在最后
这个项目从第一行代码到现在,经历了 UDP 数据路径 → 加密竞态修复 → Direct TCP 升级 → LAN 自动检测,每一步都是踩着坑过来的。
如果你也有「两台电脑直连」的需求,欢迎试试。代码完全开源:
https://github.com/uk0/stun_max
阅读原文:原文链接