前言:为什么总是“连不上”?相信很多人第一次接触“内网穿透”,都是因为这样一个问题:
“我在家写了个网页想让朋友访问,结果他连不上。”
或者更常见的:
“我在学校写了个小游戏服务器,结果公网的同学都进不来。”
于是有人告诉你:“映射个端口就行”,你照做了,但 NAT、局域网、防火墙、ISP 限制……各种问题接踵而来。
结果是:
端口映射成功了,但别人依旧连不上。
花半天折腾花生壳、ngrok,依旧超时。
最后你开始怀疑人生:“这破玩意到底是怎么穿的?”
其实问题的根源很简单:
互联网并不是“所有设备互通”的网络。
在 NAT(网络地址转换)和内网的世界里,你的电脑其实是“被墙在家里的”。
而“内网穿透(NAT Traversal)”,就是用各种巧妙的技术手段,让“墙里的设备”也能被外部世界访问。
一、内网穿透到底穿了什么?要理解内网穿透,先要理解我们常说的“内网”是什么。
1.1 内网与外网的区别类型
地址范围
能否直接访问公网
举例
内网 (Private Network)
10.x.x.x / 172.16.x.x / 192.168.x.x
❌ 否
家用路由、公司局域网
外网 (Public Network)
任意公网 IP
✅ 是
网站服务器、云主机
你家电脑的 IP 大概率长这样:192.168.1.103。
而百度服务器的 IP 是 220.181.38.148。
区别在于:
内网 IP 不能直接被外部访问;
外网 IP 是全球唯一的“门牌号”。
这也意味着,如果你要让别人访问你的电脑(例如访问你开的 HTTP 服务器),就必须让请求从公网绕进内网。
这,正是内网穿透要“穿”的那堵墙。
二、NAT 的罪与罚2.1 NAT 是怎么“卡你”的?NAT(Network Address Translation)翻译成中文就是“网络地址转换”。
它的本意是节省公网 IP,让多个设备共享一个外网出口。
简单来说:
家里所有设备都通过同一个公网 IP 上网,
NAT 设备(也就是路由器)负责“谁发的包谁收回来”。
但是这就引出了一个严重的问题:
NAT 只记录内网主动访问外网的连接;
外网主动访问内网的连接会被丢弃。
也就是说,你访问百度没问题,但百度访问你就完全不行。
NAT 是单向的,它阻止了外部主动发起的连接请求。
于是你的服务(HTTP、游戏服务器、SSH)就被挡在了外面。
三、内网穿透的基本原理想让外部访问到内网设备,无非就三种思路:
让外网“主动找上你” → 不现实(NAT 不允许)
让你“主动去找外网”,然后借道返回 → ✅ 可行
找一个“中间人”帮你转发 → ✅ 最常见
于是,“中继服务器(Relay Server)”登场。
3.1 “中继”式穿透(最常见)在这种方案下,你运行一个内网客户端,它主动连接到公网的中继服务器。
服务器则作为代理,把外部请求转发进来。
代码语言:javascript代码运行次数:0运行复制[公网用户] <--> [中继服务器] <==TCP隧道==> [你的电脑]例如:
你在家开了个 localhost:8080 的网站;
用 frp、ngrok、花生壳等工具连接公网节点;
工具会告诉你一个地址:https://xxxx.ngrok.io;
外部用户访问这个地址,就能访问到你的本地服务。
这,就是最经典的内网穿透模式。
四、常见穿透方案对比名称
类型
是否开源
延迟
配置难度
特点
FRP
TCP/HTTP 隧道
✅ 开源
中等
中
功能强、部署灵活
Ngrok
HTTP/HTTPS 隧道
✅ 开源(老版)
中等偏低
易
一键上手
ZeroTier
虚拟局域网
✅ 开源
低
中
P2P+中继混合
Tailscale
虚拟局域网
❌ 商业版
极低
低
自动 NAT 打洞,免配置
花生壳
TCP/HTTP 隧道
❌ 商业
较高
低
简单易用但免费版有限制
可以看到:
对于开发测试,frp、ngrok 是最常用的;
对于远程办公、跨地域连接,ZeroTier/Tailscale 更理想;
对于小白用户,花生壳最简单但灵活性差。
五、frp:内网穿透界的瑞士军刀5.1 frp 是什么?frp(Fast Reverse Proxy)是国人开发的开源内网穿透工具,
它通过 TCP/UDP/HTTP 等多种方式,把内网服务映射到公网。
一句话总结:
“frp 就是你自己的 ngrok。”
5.2 架构代码语言:javascript代码运行次数:0运行复制[frps] <---公网服务器--->
↑
|
[frpc] <---内网客户端--->frp 包含两部分:
frps:运行在公网服务器上的服务端;
frpc:运行在你本地电脑上的客户端。
两者通过一个端口(默认 7000)建立连接,
然后将外部请求转发给你的本地服务。
5.3 配置示例服务端(frps.ini):
代码语言:javascript代码运行次数:0运行复制[common]
bind_port = 7000
vhost_http_port = 8080客户端(frpc.ini):
代码语言:javascript代码运行次数:0运行复制[common]
server_addr = your.server.com
server_port = 7000
[web]
type = http
local_port = 8080
custom_domains = demo.yourserver.com启动后,访问 http://demo.yourserver.com,
就能访问你本地的 localhost:8080 服务。
六、P2P 打洞:不靠中继,直连更快中继服务器虽然简单,但有个问题——贵且慢。
于是聪明的工程师想出了更高效的方式:P2P 打洞(Peer-to-Peer NAT Traversal)。
6.1 核心思路 双方都向一个“信令服务器”报告自己的公网出口;
利用 NAT 的“连接保持”特性,双方同时发包;
让 NAT 认为是“内部请求”,从而允许穿透。
简单示意:
代码语言:javascript代码运行次数:0运行复制[主机A] -> [信令服务器] <- [主机B]
↘ ↙
<----打洞通信---->这就是 WebRTC、Tailscale、ZeroTier 背后的“打洞机制”。
6.2 打洞的局限性 部分 NAT 类型(如对称 NAT)根本无法打洞;
公网出口经常变化(如校园网、4G 网络);
有时仍需回退到中继模式。
这就是为什么:
真正可靠的内网穿透系统,都会“P2P + 中继”双管齐下。
七、内网穿透 ≠ 翻墙这两个概念经常被混为一谈,但其实完全不同。
项目
内网穿透
VPN
目的
让外部访问你的内网
让你访问外网资源
通信方向
外部 → 内部
内部 → 外部
实现方式
隧道 + 中继
虚拟网卡 + 隧道
常用工具
frp、ngrok、ZeroTier
OpenVPN、WireGuard、Tailscale
常见用途
远程调试、文件访问、私有服务
安全上网、企业内网接入
一句话总结:
VPN 是“出去”,内网穿透是“进来”。
八、现代方案:ZeroTier 与 Tailscale 的崛起如今的内网穿透不再局限于单点映射,而是朝着“虚拟局域网”方向发展。
这类方案让世界各地的设备组成一个“逻辑上的同一个网段”。
比如:
你的笔记本 IP 是 10.147.5.2
你的家用 NAS 是 10.147.5.3
你的手机是 10.147.5.4
虽然它们分布在不同城市、不同运营商,
但它们都能直接互 ping、ssh、访问共享文件。
这就是 ZeroTier、Tailscale、Nebula 的魅力:
“跨越地理边界的内网。”
九、常见问题与踩坑记录❌ 端口映射失败 多层 NAT(校园网 → 宿舍路由 → 电脑)
ISP 禁止公网访问
运营商 CGNAT(共享公网 IP)
解决:使用中继式穿透(frp/ngrok),或使用虚拟局域网(ZeroTier)。
❌ 延迟太高 中继服务器距离过远;
TCP 隧道开销过大;
使用 HTTP 协议导致额外头部。
解决:尽量选择就近节点;或改用 UDP 隧道。
❌ 打洞不稳定 不同 NAT 类型不兼容;
防火墙阻断 UDP;
移动网络频繁断开。
解决:选择支持自动回退的方案(Tailscale/ZeroTier)。
十、结语:让网络变得“无墙可挡”回到最初的问题:
“为什么我开的服务器别人连不上?”
答案其实很简单:
因为整个互联网并不是对称的。
内网穿透的意义,不仅是“让别人访问你”,
更是让开发者理解:
网络连接从来不是“理所当然”的;
一切通信背后都有复杂的协议与权衡;
而能在这种复杂中“打洞”,才是真正的技术浪漫。
也许有一天,IPv6 普及、NAT 消失、所有设备都有公网地址,
那时“内网穿透”这个词会被历史淘汰。
但在那之前,
每一个能让本地服务“走出内网”的程序员,
都在和整个互联网的边界对抗。
作者观点:
“内网穿透,不只是技术问题。
它是一种对网络结构的反思——
在一个封闭的世界里,
我们总会想办法找到那条通向外面的路。”