临时穿透内网,我不想再养一台中转服务器了:gonc 折腾记

内网穿透这事我折腾过不少方案。要么在公网机器上常驻一个服务端,把内网端口反向代理出去;要么搭一套自托管的组网工具,给每��设备发个虚拟 IP,组一张大内网。这些方案都能用,但共同点是——都要先立起一个”基础设施”:一台一直开着的中转机、一份配置文件、一套证书或密钥。为了偶尔传个文件、临时连一次远程桌面,养一整套东西,多少有点重。

最近翻到一个叫 gonc 的小工具,思路正好相反:不养服务端,不发虚拟 IP,两台机器约定一句口令,就能自己找到对方、打穿 NAT、建立一条加密直连。用完就散。我拿它在家里的宽带和外面的手机热点之间试了几回,感觉这才是”临时穿透”该有的样子。记下来。

gonc NAT 穿透演示

它到底是个什么东西

作者把 gonc 定义成”一个会自动穿透 NAT 的 netcat”。netcat(nc)老网工都熟,就是那个能读写任意 TCP/UDP 连接的瑞士军刀。gonc 用 Go 重写了 nc 的核心能力,然后在上面加了三样东西:

  • 自动 NAT 穿透:零配置。两端只要约定同一句口令,程序会自己去探测各自的 NAT 类型、交换地址,然后打洞建立点对点连接。
  • 端到端加密 + 双向认证:TCP 走 TLS,UDP 走 DTLS,口令同时用来做身份校验和证书派生,中间人插不进来。
  • 灵活的服务挂载:连接建立后,你可以往这条管道里塞任何东西——一个 shell、一个 SOCKS5 代理、一个 HTTP 文件服务、或者纯粹的端口转发。

它是开源的,MIT 协议,纯 Go 单二进制,Windows / Linux / macOS 都能跑。核心逻辑就一个可执行文件,扔哪都行。

为什么它不一样:没有中继,要么直连要么失败

大部分穿透工具在打洞失败时会退回到”中继”——数据绕一圈公网服务器再转发给你。方便,但意味着你的流量要经过别人的机器,而且那台机器得一直开着。

gonc 的态度很干脆:它默认不做中继,也不提供兜底。要么真正打通点对点,要么这次连接就失败。它的打洞过程是这样的:

  • 同时用多个公共 STUN 服务器探测本地的 TCP/UDP NAT 映射,智能判断 NAT 类型;
  • 通过公共 MQTT 服务器交换地址信息,用口令派生出的哈希当作双方的”暗号频道”;
  • 按 IPv6 TCP > IPv4 TCP > IPv4 UDP 的优先级尝试直连。

换句话说,它借用的是公共的、无状态的第三方服务(STUN 找地址、MQTT 传暗号),这些都不碰你的实际数据,真正的流量只在你们两台机器之间走。这跟”自己养一台中转服务器”是两码事——你不用维护任何东西。

gonc 打洞过程演示
家宽(硬 NAT)与手机热点(对称 NAT)之间的打洞演示

上面这张图是官方演示:一边是家里宽带(硬 NAT),一边是手机移动网络(对称 NAT),两个都是不好打的类型,gonc 照样把洞打穿了。我自己实测,家宽这头是”easy”类型,手机热点是”hard”,一次就通了;如果两边都是最难的对称 NAT,那确实会失败——这时它建议让其中一端挂个支持 UDP 的 SOCKS5 代理当”跳板”,把自己的 NAT 行为”降级”成容易穿的类型,数据仍然端到端加密。

怎么用:几个我真正用得上的场景

gonc 的参数不少,但常用的就那么几组。先说最简单的:查自己的 NAT 类型,穿透前先摸底:

gonc -nat-checker

它会列出你 IPv4/IPv6 各自的 TCP/UDP NAT 映射,末尾标注 easy / hard / symm。symm(对称)最难打,看到它就要有心理准备。

场景一:两台机器之间传文件。发送端起一个 HTTP 文件服务,把要分享的目录暴露出去:

gonc -p2p 口令 -httpserver /path/to/share

接收端可以直接整个目录递归下载,中断了重跑还能断点续传:

gonc -p2p 口令 -download /path/to/save

或者不自动下,本地开个端口用浏览器挑着下。我平时给家里的 NAS 往外发几个大文件就用这个,不用先传到网盘再下回来。

场景二:把远端网络的服务代理到本地。一端等着建隧道,另一端起一个本地 SOCKS5 / HTTP 代理,就能访问对面内网的东西:

gonc -p2p 口令 -link "3080;none"

之后本地连 3080 这个代理,就能摸到远端内网的机器。这个对我来说很实用——人在外面,想连家里内网某台设备的管理页面,起个隧道就行,不用把那台设备暴露到公网。

场景三:反向 shell / 远程终端。UNIX 系支持伪终端,TAB 补全、Ctrl+C 都能用:

gonc -exec ":sh /bin/bash" -p2p 口令

另一端 gonc -pty -p2p 口令 就拿到一个交互式 shell。全程 TLS 1.3 加密,口令做认证。

不想碰命令行?有个图形版

作者还做了个配套的 gonc-gui,桌面(Windows)和安卓都有。逻辑一样,但不用敲命令:双方共享一句口令,或者扫个二维码,就能跨设备直连传文件。

gonc-gui 桌面端演示
gonc-gui 桌面端:共享口令或扫码即可直连传文件

手机端界面也是同一套,安卓上直连传文件、扫码配对,操作挺直白:

gonc-gui 安卓端界面

对不想折腾命令行的人,GUI 版本降低了门槛;但要玩转 SOCKS5 代理、端口转发、给 WireGuard 打辅助这些进阶用法,还是得回到命令行。

有哪些坑,先说在前面

用下来有几点值得注意:

  • 对称 NAT 是硬伤。如果你和对端都处在对称 NAT 后面,纯 P2P 大概率打不通。这不是 gonc 的锅,是 NAT 打洞的物理限制。解决办法是至少一端有个能跑 SOCKS5 UDP 的公网跳板——但那样又回到”得有台公网机器”的老问题上了,只是它只当跳板、不碰明文数据。
  • 依赖公共 STUN / MQTT 服务。穿透过程要用到 Cloudflare、Google 的公共 STUN 和作者提供的 MQTT/STUN 服务器来交换地址。这些只传”暗号”和地址、不传数据,但如果你所在网络把这些都墙了,穿透就发起不了。介意的话可以自建 STUN/MQTT 替换。
  • 它是工具,不是常驻服务。gonc 的定位是”临时打一条隧道”,不是”一直挂在那当反代网关”。如果你要的是稳定长期对外提供服务,成熟的反向代理 / 组网方案更合适。gonc 的甜区是临时、点对点、用完即走
  • 口令就是一切。口令既用来发现对方、也用来派生证书。口令泄露等于门户大开,所以别用弱口令——它自带 gonc -psk . 生成高熵口令,老老实实用它生成的。

小结

我对 gonc 的好感,主要来自它的”轻”。它没打算取代我已有的那套反代和组网工具——那些负责长期、稳定、对外的服务;gonc 补的是另一块:两台机器之间偶发的、临时的、点对点的直连需求。传个大文件、临时连一次远程桌面、给内网某个服务开个临时通道——这些事,以前要么绕网盘要么开隧道服务,现在一句口令就完了,用完进程一关,什么都不留下。

对于家里已经有一台 NAS、时不时要在外面够一下内网的人,把它扔进工具箱不亏。它不是那种”装上就一直跑”的基础设施,而是”需要时随手一用”的趁手家伙。这个定位,我挺喜欢。

发表评论