十年踩坑路:我是如何用Go语言穿透内网封锁的

2014年,我在大学宿舍架设了人生第一台NAS。当我兴奋地告诉远在老家的朋友可以远程访问时,现实给了我一记重锤——家庭宽带没有公网IP。十年踩坑路:我是如何用Go语言穿透内网封锁的 IT技术

此后数年,这个问题反复出现在我的工作中:开发机无法远程调试、工厂设备无法远程运维、客户现场无法即时演示。内网穿透,成了我每年都要面对的必修课。

直到我遇见了frp。

问题的本质:穿透不是变魔术

很多人对内网穿透存在误解,以为它能凭空创造出一个公网IP。事实上,标准答案是:穿透的本质是搭建桥梁

frp全称FastReverseProxy,由Go语言编写。它的架构极其清晰:一台有公网IP的云服务器作为中转站(服务端frps),你的内网设备作为待访问目标(客户端frpc)。外部请求先到云服务器,frps再将流量转发给潜伏在内网的frpc。

整个链路是:用户→公网IP:端口→frps→frpc→内网服务。

为什么是Go?三个无法拒绝的理由

我见过用Python、Node.js甚至Shell实现的内网穿透方案,但Go语言让frp成为了完全不同量级的工具。

第一,极致轻量。编译后是单个静态二进制文件,不依赖任何系统库。我曾在一台16MB内存的嵌入式ARM设备上成功运行frpc。

第二,并发能力惊人。Go的goroutine机制让frp处理十万级并发连接时,内存占用依然稳定在100MB以下。对比某些用Python写的方案,差距肉眼可见。

第三,协议支持全面。TCP、UDP、HTTP、HTTPS、P2P模式全覆盖。TOML配置文件语义清晰,开发者几乎不需要查阅文档就能完成基础配置。

三分钟部署:从入门到生产

我的标准部署流程从未超过三分钟。

服务端(云服务器)只需准备一份frps.toml:

bindPort填入frps监听端口,auth.method设为token,auth.token设置强密码。执行./frps-c./frps.toml,服务端即刻就绪。

客户端(内网设备)配置frpc.toml:

serverAddr指向云服务器公网IP,serverPort对应frps监听端口。[[proxies]]段落定义代理规则:name是代理名称,type选择tcp或udp,localIP和localPort指向你的真实服务,remotePort是外部访问端口。

运行./frpc-c./frpc.toml后,访问http://服务器IP:remotePort,流量自动穿透到内网。

这些场景,让frp的价值最大化

穿透不仅是Web服务。SSH远程登录是最常见场景——在咖啡馆里通过公网端口直接连回实验室服务器。工业视觉场景中,车间边缘节点运行YOLO推理,通过frp映射后,办公室工程师实时查看识别结果。开发调试场景下,微信/钉钉回调直抵本地IDE,改完代码立刻验证。

安全是底线,这些配置不能省

把内网服务暴露到公网,安全性必须放在第一位。Token认证必须启用且使用强密码。务必开启TLS加密(transport.tls.enable=true),否则流量明文传输形同裸奔。本地服务只监听127.0.0.1而非0.0.0.0。带宽敏感场景考虑xtcp模式,实现P2P直连规避服务器流量。

总结

frp证明了开源社区的力量。一台几十元/月的云服务器,加上一个单文件二进制程序,就能解决困扰开发者多年的内网穿透难题。如果你还在为这个问题交学费,现在该换个思路了。