
不知道你有没有遇到过这种时刻——本地localhost:8080跑得好好的产品突然说给我看一眼客户说你发个链接我点一下或者你接 Stripe、GitHub 的 webhook对方死活推不进来因为你的服务躲在localhost后面公网根本摸不到门。传统办法要么自己搞 Nginx 域名 证书折腾半天要么用 ngrok好用但免费版限制多自定义域名还要付费。前阵子我翻到一个叫Tunnelto的小工具用 Rust 写的试了一下基本就是装好 → 一条命令 → 拿到公网 URL的体验。下面把我的使用过程和踩到的点都记下来给有同样需求的人参考。说明一下我是普通用户视角不是项目开发者。下面的描述来自我实际试用 翻它的文档和源码不代表官方立场。先说清楚内网穿透到底是个啥怕有人第一次听这个词先一句话解释内网穿透[把藏在你本机或局域网里的服务借一个公网中转服务器探出去让外面的人也能访问到你本机的端口]打个比方。你住在一个小区局域网外卖员外部用户进不来也找不到你家门牌。内网穿透就像你在大门口放了一个对外营业的收发室公网服务器你跟收发室拉了一根内部对讲机控制连接。外面的人把包裹送到收发室收发室通过对讲机喊你你再从家里把东西递出去。外面的世界始终只跟收发室打交道根本感知不到你的真实位置。Tunnelto 干的就是帮你开这个收发室 拉这根对讲机的活。装好就能跑最小使用示例安装有三种常见方式挑顺手的# macOS 用 Homebrewbrewinstallagrinman/tap/tunnelto# 如果你装了 Rust 工具链也可以直接 cargo 装cargoinstalltunnelto# 其他平台Windows / Linux去 GitHub Releases 下载二进制就行装完假设你本地有个服务跑在 8000 端口就这么一行tunnelto--port8000跑起来后终端大致长这样具体字符串是随机生成的接下来任何人访问https://abc123.tunnelto.dev实际打到的是你本机localhost:8000。你改代码、刷新对方看到的都是实时结果——特别适合联调。想要一个好记的地址加个参数tunnelto--port8000--subdomainmyapp这样就能拿到https://myapp.tunnelto.dev。子域名[主域名前面的那段比如 myapp.tunnelto.dev 里的 myapp] 这个能力在 ngrok 里是要付费的Tunnelto 免费给。甚至本地不是127.0.0.1、或者想指定协议也行tunnelto--port3000--host127.0.0.1--schemehttps它内部是怎么把流量搬过来的我好奇它怎么做到的翻了下源码和文档结构其实不复杂就三个角色你本机的客户端Client就是你执行的那个tunnelto命令。云端的服务器Server官方提供的tunnelto.dev或者你自己部署的那台。控制通道Control WebSocket[一种长连接协议客户端和服务器之间始终保持一根热线能随时双向发消息]客户端启动后先跟服务器用 WebSocket 握个手说我要开个隧道。之后真实的请求流转是这样的外部用户访问https://xxx.tunnelto.dev→ 打到服务器服务器一看这个子域名知道背后是你就通过那根控制通道通知你的客户端有人来访问了你本机的客户端再去连你真正的本地服务比如localhost:8000请求和响应在这两端之间被双向转发。关键点是你本机不需要公网 IP也不需要对外开放任何端口。所有进出流量都先过服务器这一道再由客户端拉回本地。为什么用 Rust Tokio[Rust 的异步运行时可以理解成一个高效调度大量等待中任务的发动机]说白了就是为了省资源、扛并发。异步 IO 的好处是单线程就能同时照看成千上万个连接不用为每个连接开一个线程那样内存和切换开销会爆炸。对一个中转站来说这点很关键。和 ngrok、localtunnel 比怎么选我用过的几个同类工具横向摆一摆评价偏主观按需取用维度Tunneltongroklocaltunnel性能Rust 异步 IO很能打Go 写的也强Node.js一般够用上手难度一条命令一条命令一条命令自托管完全支持文档齐全基本要付费才有支持但功能弱自定义域名免费付费不支持开源协议MIT全开源部分开源MIT资源占用极低较低中等我的看法如果你只是偶尔演示一下三个都能用但如果你在意数据走谁家的服务器、想要免费自定义域名、或者想自己部署一套那 Tunnelto 的性价比就出来了。ngrok 胜在生态成熟、文档稳localtunnel 胜在零门槛Node 环境里一行就能起。不想数据过别人家服务器可以自托管这点我觉得是对隐私敏感的同学最该看的。Tunnelto 开源了服务端代码你可以自己搭。官方给了两条路单实例编译成 musl 静态二进制就是把依赖全部打进一个文件里拷到服务器就能跑或者用 Docker 起一个容器。Docker[把应用和它所依赖的环境打包成一个可移植盒子到哪都能原样运行] 方式对新手最友好。分布式官方自己是用 Fly.io 的私有网络 Gossip 协议做服务发现的多实例负载均衡。这个属于进阶玩法一般个人用不太到。几个关键的环境变量配在服务器端ALLOWED_HOSTS允许哪些主机名进来防域名被乱绑CTRL_HOST/CTRL_PORT控制通道监听的地址和端口CTRL_TLS_OFF本地测试时可以关掉 TLS 加密省事。哪些场景它真的能救命挑几个我身边最常见的给客户/产品演示不用先部署到测试环境本地改两笔直接发链接对方点开就是最新效果。接第三方 webhook[别人系统主动给你的地址推消息比如支付成功通知、CI 构建结果而不是你去反复查]Stripe、GitHub Actions 这类必须给一个公网可达的回调地址。localhost收不到Tunnelto 一接就通。OAuth 回调[用微信/Google 登录时授权完成后对方要跳回你指定的地址]本地调试第三方登录几乎是刚需。移动端真机测试手机连外网访问你电脑上的页面测响应式、测真机兼容性比开模拟器真实。前端联调前端同事连你本机的 API不用你先推到远程。安全这块别忽略工具再方便把本机暴露出去总得留个心眼。Tunnelto 提供几层保障API Key 认证可以设一个密钥没有密钥的人连不上你的隧道防止被路人扫到乱用。默认 HTTPS公网那一段是加密的TLS数据在传输途中不会被明文截获。主机名白名单服务端能配置ALLOWED_HOSTS避免别人把你的子域名绑到别处去。我的习惯演示完、联调完顺手把隧道关掉。别让它一直开着。一点使用感受优点很直接安装简单、命令短、免费送自定义子域名、还能自托管对隐私党友好。Rust 写的中转站资源占用确实低我开着它基本感觉不到存在。要说不足项目最近更新不算特别活跃最新稳定版是 0.1.18生态和文档丰富度比不上 ngrok另外官方公共服务器是别人提供的介意数据路径的请务必走自托管。总归它适合想一条命令把本地服务甩到公网、又不想被收费项卡脖子的开发者。如果你正好被 webhook / 演示 / 联调这类事烦着可以拉下来试五分钟不行再卸也不亏。项目地址GitHubhttps://github.com/agrinman/tunnelto官网https://tunnelto.dev