内网穿透到底是个什么东西?
如果你是一个开发者,或者是一个热衷于折腾 NAS 和树莓派的技术爱好者,你一定遇到过这个问题:
“我在家里的局域网能用 SSH 连上我的服务器,但在公司或者出差时,怎么连都连不上。”
这时候,老手们会丢给你一个词:“做个内网穿透吧。”
这一篇博客将避开晦涩的教科书定义,面向有一定计算机基础的读者,从网络底层原理出发,讲清楚内网穿透到底穿的是什么“墙”,透的又是哪层“膜”。
为什么你“失联”了?
在讨论如何“穿透”之前,我们必须先理解“阻隔”我们的是什么。
公网 IP 与 IPv4 的枯竭
在互联网设计的最初愿景里,每一个设备都应该有一个全球唯一的 IP 地址(公网 IP)。如果大家都有公网 IP,根本不需要内网穿透,你只需要输入 ping 对方IP,就能直接握手。
但现实是残酷的:IPv4 地址只有约 43 亿个,早就被瓜分殆尽。
为了让全球几百亿台设备都能上网,工程师们发明了 NAT(Network Address Translation,网络地址转换) 技术。
NAT:路由器的“换皮”魔法

现在,运营商通常不会给你分配独立的公网 IP,而是把你划入一个巨大的局域网。你家里的路由器(或者光猫)成为了这一层网络的边界。
当你的电脑(内网 IP: 192.168.1.5)想访问百度时,数据包经过路由器,路由器会做一件关键的事:修改数据包的头部。
- 路由器把“源地址”从你的内网 IP,修改为路由器 WAN 口的公网 IP。
- 路由器在自己的小本本上记下一笔帐(这就是 NAT 映射表)。
- 百度收到数据,以为是路由器发给它的,于是把数据回传给路由器。
- 路由器查小本本,发现“哦,这是刚才
192.168.1.5要的数据”,于是把数据转发给你。

核心矛盾:NAT 的“单向阻隔”
NAT 完美解决了上网问题,但它带来了一个巨大的副作用:连接必须由内网主动发起。
这里我们需要引入一个比喻来理解这个困境:
比喻:
把互联网想象成一个巨大的邮政系统。
- 公网 IP 是拥有独立门牌号的别墅。
- 内网 IP 是住在酒店里的房间号(如 101 房)。
- 路由器(NAT) 就是酒店的前台。
当你(101 房)要给外面寄信时,前台会把你的信封换成酒店的信封寄出去,对方回信寄给酒店,前台知道这是给你的。
但是,如果此时有一个陌生人(你在公司的电脑)直接给酒店寄一封信,上面写着“转交 101 房”,前台会直接把信扔进垃圾桶。
为什么? 因为酒店里可能并没有人要在此时收信,或者出于安全考虑,前台规定:“只有住客先寄出去的信,对应的回信我才接收;任何莫名其妙从外面寄来的信,一律拒收。”

这就是你连不上家里服务器的原因:你的请求到达了家里的路由器(公网 IP),但路由器查不到对应的“映射记录”,直接丢弃了你的连接请求。
看到这里,你脑子里可能冒出了一个巨大的问号:
“你说路由器会拦截外部的数据,那为什么我在家打开 B 站,视频流能哗哗地传进来?这不也是从外网发给我的数据吗?”
这就触及到了 NAT 最核心的“状态机制”。
简单来说,路由器虽然是个冷酷的门卫,但它遵循一条铁律:“谁先撩谁”。
情况 A:你主动撩别人(正常上网)
当你点击 B 站视频时,是你的电脑先发起了一个请求:“我要看这个视频”。
- 这个请求经过路由器。
- 路由器看了一眼,记在小本本上:“注意!我也住客(内网 IP)主动找了 B 站服务器(外网 IP),大概 1 秒后 B 站会回信,这封回信是合法的,允许通行。”
- 当 B 站的视频数据回来时,路由器查到了这条“放行记录”,于是视频就顺利进来了。
结论:只要是你主动发起的连接,回来的数据就能通过。
情况 B:别人主动撩你(内网穿透要解决的问题)
现在的场景是:你在公司,想连家里的电脑。
- 此时,家里的电脑在发呆,没有任何动作(没有主动撩你)。
- 你在公司,直接给家里路由器的公网 IP 发了一个数据包。
- 数据包到达家里路由器。路由器翻开小本本,发现一片空白——没有任何住客刚才请求过这个公司 IP。
- 路由器判断:“这是骚扰拦截”,直接把数据包丢进垃圾桶。
总结一下:
- 出站(Outbound):你找别人,路由器会自动建立临时白名单,通。
- 入站(Inbound):别人找你(且你没提前打招呼),路由器默认视而不见,堵。
这就是为什么你平时上网没感觉,但一做服务器就歇菜的原因——内网穿透,就是要想办法打破这个“只能我找人,不能人找我”的僵局。
实战自检:我有公网 IP 吗?(光猫、路由器与 ISP 的三角关系)
在决定使用哪种内网穿透方案之前,我们需要先搞清楚自己处于什么样的网络环境中。这涉及到家庭网络的三个核心角色:ISP、光猫和路由器。

物理层面的“接力赛”
当我们说“上网”时,数据其实经历了一个三级跳的过程:
- ISP (互联网服务提供商):
- 这是你的运营商(电信/联通/移动)。他们构建了骨干网,并掌握着全球公网 IP 资源。
- 核心作用:分配 IP。你的“门牌号”(IP 地址)是他们租给你的。
- 光猫 (Optical Modem):
- 这是运营商入户的第一个盒子。
- 核心作用:信号转换(调制解调)。ISP 的骨干网传输的是光信号,而你的电脑和路由器识别的是电信号。光猫负责在两者之间进行翻译。
- 注意:现代光猫通常自带路由功能(拨号),这意味着它也是一层 NAT。
- 路由器 (Router):
- 这是你自己买的带有天线的设备。
- 核心作用:网关与 NAT。它负责管理家里的所有设备(手机、电脑),并通过 NAT 技术让它们共享同一个上级分配的 IP 上网。
如何检测是否有公网 IP?(“找不同”法)
判断你是否拥有公网 IP,最准确的方法是进行双向比对。我们需要获取两个数值:“外界看到的你” 和 “你自己以为的你”。
步骤一:获取“外界看到的 IP” 在连接家里 Wi-Fi 的电脑或手机上,直接访问搜索引擎(百度/Google)搜索关键词:“IP”。 或者访问专业网站如 ip138.com。
- 假设你看到的地址是:
A = 113.108.x.x
步骤二:获取“路由器 WAN 口 IP” 登录你的路由器管理后台(通常是 192.168.1.1 或 192.168.0.1),在“系统状态”或“上网设置”中找到 WAN 口 IP 地址。
- 假设你看到的地址是:
B
步骤三:结果判定
- 情况 1:A 与 B 完全一致
- 结论:🎉 恭喜,你拥有真正的公网 IPv4 地址。
- 意义:你的路由器直接暴露在公网上。你不需要复杂的内网穿透软件,只需要在路由器上设置简单的端口映射 (Port Forwarding),即可直接从外网访问家里。
- 情况 2:A 与 B 不一致
- 结论:❌ 你没有公网 IP(处于内网中)。
- 意义:你的路由器上级还有设备(光猫或运营商的局端设备)在做 NAT。外部请求无法到达你的路由器。
警惕“假”公网 IP:CGNAT (100.x.x.x)
在查看 WAN 口 IP (数值 B) 时,如果你发现它属于以下范围,那么不用比对,直接判定为内网:
100.64.0.0-100.127.255.255- 这是 IETF 标准定义的 运营商级 NAT (Carrier-Grade NAT, CGNAT) 专用地址段。
- 如果你看到
100开头的 IP,说明运营商像个“二房东”,把你和隔壁小区的几千个用户关在了一个巨大的局域网里,共用极少数的公网 IP 出口。这是目前全中国最常见的家庭宽带状态。
10.x.x.x,172.16.x.x,192.168.x.x- 这是标准的私有地址。如果你路由器的 WAN 口是这些 IP,说明你的路由器接在了光猫(或其他路由器)下面,你需要去检查上一级设备。
终极救星 IPv6?理想丰满,现实骨感
读到这里,敏锐的读者可能已经想到了一个终极解决方案:
“大家都说 IPv4 枯竭了,那不是还有 IPv6 吗?听说 IPv6 的地址多到能给地球上的每一粒沙子都分一个 IP,那我直接给家里的服务器配个 IPv6 不就行了吗?还要什么内网穿透?”
答案是:理论上完美,但实操中有三个“隐形大坑”。
虽然国内运营商(ISP)的宽带目前基本都下发了 IPv6 地址,但要把它用作远程连接,你得过五关斩六将。
坑一:单向的“半残”网络(客户端环境不支持)
这是目前最致命的问题。 就算你把家里的服务器配置好了 IPv6 公网地址,这只代表“家里有门”。 但是,当你身处公司、酒店、咖啡厅或者使用公共 Wi-Fi 时,你所在的网络环境未必支持 IPv6。
- 场景:你在公司想连回家。
- 现实:公司的内网为了安全或设备老旧,通常是纯 IPv4 环境。
- 后果:你在纯 IPv4 的环境下,根本找不到通往 IPv6 地址的路由。这就好比你拿着一部只能拨打 7 位数号码的老电话(IPv4),试图拨打一个 128 位的超长号码(IPv6),根本拨不出去。
除非你时刻开着手机热点(蜂窝移动网络通常支持 IPv6)给电脑用,否则 IPv6 的连通性极不稳定。
坑二:光猫与防火墙的“黑箱”
有了 IPv6 地址,不代表大门是开着的。
- 光猫拦截:大多数运营商的光猫默认工作在“路由模式”,自带的防火墙策略极严,往往会拦截所有入站的 IPv6 流量。你通常需要把光猫改成“桥接模式”,用自己的高性能路由器拨号,才能获得控制权。
- 裸奔风险:IPv6 没有 NAT 的保护。一旦你在路由器上放行了 IPv6 防火墙,你的服务器就是赤裸裸地暴露在公网上的。每一个端口的开放都需要极其谨慎,否则就是给黑客送肉机。
坑三:动态变化的地址(需要 DDNS)
虽然 IPv6 是公网地址,但运营商给你的依然是动态 IP(Dynamic IP)。
- 路由器每重启一次,或者运营商每隔几天强制刷新一次,你的 IPv6 地址(尤其是前缀 Prefix)就会变。
- 解决成本:你必须配置 DDNS v6(动态域名解析),还得写脚本让服务器定期向 DNS 服务商汇报:“老板,我的新 IP 是这个,快更新一下域名指向。”
如何“穿墙”?(内网穿透模式)
所谓的“内网穿透”,核心目的只有一个:在路由器(前台)拒绝外部请求的情况下,建立一条能从外面连进来的通路。
目前主流的技术方案主要分为两类。
模式一:反向代理 / 中继(FRP, Ngrok)

这是最传统、最稳健,但成本最高的方案。
原理:
既然路由器只允许“从内向外”发起连接,那我们就顺着它来。
我们需要一台拥有公网 IP 的服务器(VPS)作为中介。
- 主动“挂号”:你家里的内网服务器启动一个客户端,主动向公网 VPS 发起一个长连接(TCP 连接)。因为是内网主动发起的,路由器会放行,并维持这个连接。
- 流量转发:当你在公司想连回家时,你其实是连向那台公网 VPS。
- 借道传输:VPS 收到你的请求后,通过刚才建立的那条长连接,把数据“透传”给家里的内网服务器。
特点:
- 稳定性:极高。只要 VPS 不挂,连接就在。
- 缺点:你需要购买 VPS,且速度受限于 VPS 的带宽(数据都要去 VPS 绕一圈,这叫“流量中转”)。
模式二:P2P 打洞 / UDP Hole Punching (Tailscale, ZeroTier)

这种模式是现代组网工具(如 Tailscale, ZeroTier)的首选方案。它的核心不再是“绕过”NAT,而是利用 NAT 设备处理 UDP 协议时的状态机逻辑,通过诱导双方 NAT 设备建立合法的 Session 映射,从而实现端对端(Peer-to-Peer)直连。
技术原理:
这一过程依赖于中间的一个信令服务器(Signaling Server / Coordination Server)(如 STUN Server 或 Tailscale Control Plane),以及 NAT 设备对 UDP 会话的状态检测(Stateful Packet Inspection)机制。
整个打洞过程可以拆解为三个微秒级的同步步骤:
第一步:端点发现与信令交换 (Endpoint Discovery & Signaling)
由于双方(Client A 和 Client B)都位于 NAT 之后,无法直接获知对方的公网入口。
- 连接信令服务器:A 和 B 分别与公网上的信令服务器建立连接。
- 获取 Server-Reflexive Address:信令服务器观测 A 和 B 的请求来源,识别出它们经过 NAT 映射后的公网 IP 和端口(Public Endpoint)。
- 交换信息:信令服务器通过侧链(Side-channel),将 A 的公网地址告诉 B,将 B 的公网地址告诉 A。
第二步:双向同步发包 (Simultaneous Open)
这是“打洞”最关键的一步。双方获得对方地址后,几乎同时向对方发起 UDP 通信。
- A -> B 发包:
- Client A 向 Client B 的公网地址发送一个 UDP 包。
- NAT A 的行为:NAT A 检测到内网有出站流量,于是并在 NAT 映射表中创建一条 Session 记录(五元组:
Src:A_Int, Dst:B_Pub),允许 B 的回包通过。 - NAT B 的行为:此时 B 尚未向 A 发包,NAT B 上没有关于 A 的记录。因此,A 的包到达 NAT B 时,会被防火墙规则(Default Deny)直接丢弃。
- 结果:数据包丢失,但在 NAT A 上留下了“洞口”(Session)。
- B -> A 发包(与上一步几乎同时发生):
- Client B 向 Client A 的公网地址发送一个 UDP 包。
- NAT B 的行为:NAT B 检测到出站流量,创建针对 A 的 Session 记录,允许 A 的回包通过。
- NAT A 的行为:B 的数据包到达 NAT A。NAT A 进行查表操作,匹配到了上一步 A 发包时创建的 Session 记录。
- 结果:NAT A 认为这是 A 请求的“合法响应”,允许数据包通过并转发给 Client A。
第三步:隧道建立与保活 (Connection & Keep-alive)
一旦 Client A 成功收到了 Client B 的数据包(或者反之),一条双向的 UDP 通道即宣告建立。
- 隧道封装:上层的应用数据(如 SSH 的 TCP 流量)会被封装在这些 UDP 包中直接传输。
- 心跳保活:由于 NAT 设备的 UDP Session 超时时间较短(通常 30s-120s),客户端必须定期发送 Keep-alive 包以刷新 NAT 表中的 TTL,防止映射关系被回收。
技术局限性:Symmetric NAT (对称型 NAT)
P2P 打洞并非 100% 成功。其成功率取决于运营商和路由器使用的 NAT 类型。
- Cone NAT (锥型 NAT):对所有目标 IP 使用相同的出口端口映射,打洞成功率极高。
- Symmetric NAT (对称型 NAT):对于不同的目标 IP,NAT 会分配不同的公网端口。
- 场景:Client A 告诉信令服务器自己在端口 10000。但当 Client A 向 Client B 发包时,Symmetric NAT 会将其映射为端口 10001。Client B 依然向 10000 发包,导致打洞失败。
- 解决方案:当检测到一端为对称型 NAT 且无法预测端口时,协议会自动降级为模式一(中继模式 / TURN),通过中转服务器转发流量。
你可能存在的疑问
为什么不直接打 TCP 洞?
TCP 协议的设计初衷是“可靠的、面向连接的流”,这导致其打洞难度远高于 UDP。
严格的状态机限制:
- TCP 连接建立必须遵循严格的 三次握手 (SYN -> SYN/ACK -> ACK)。
- NAT 设备通常具备 状态检测 (Stateful Inspection) 功能。如果 NAT 在
LISTEN或SYN_SENT状态下收到一个意外的入站SYN包(序列号不在预期窗口内),它会直接丢弃该包甚至回复RST重置连接。 - 要实现 TCP 打洞,必须利用 TCP 同时打开 (Simultaneous Open) 这一罕见特性,要求两端在毫秒级的误差内同时发送
SYN包。这在不可靠的公网环境中极难协调。
相比之下,UDP 是无状态的。NAT 设备对 UDP 的处理逻辑仅仅是“有去就有回”,不需要维护复杂的握手状态,打洞成功率呈指数级上升。
虽然将 TCP 封装在 UDP 中(Tunneling)解决了连通性问题,但这种“协议套娃”引入了新的物理层面的问题:
- 问题一:MTU 黑洞与分片 (Fragmentation)
- 物理网络通常限制数据包最大为 1500 字节(MTU)。
- 原本一个 1500 字节的 TCP 包,现在被套上了
IP头(20) + UDP头(8) + WireGuard/VPN头(几十字节)。 - 后果:总长度超出了 1500 字节。路由器必须将包分片 (Fragment) 传输,或者直接丢弃并返回 ICMP 错误。IP 分片会严重降低传输效率,且许多防火墙会拦截分片包,导致连接卡顿或中断。
- 问题二:运营商 QoS 限速
- 国内部分运营商(ISP)会对高带宽的 UDP 流量(常见于 BT 下载、游戏)进行 QoS (Quality of Service) 降级或丢包。
- 后果:你可能发现 SSH 连接虽然通了,但打字经常卡顿,或者文件传输速度极慢,远低于带宽上限。
结语
总结一下:
- 计算机网络理论告诉我们:由于 IPv4 短缺和 NAT 的存在,外网无法直接访问内网。
- 内网穿透告诉我们:
- 要么找个有公网 IP 的中介(FRP/中继模式),稳定但费钱。
- 要么利用规则欺骗路由器(P2P/打洞模式),快速且免费。
对于大多数个人开发者,Tailscale 或 ZeroTier 这种基于 P2P 打洞的方案是首选;如果你要搭建一个给很多人访问的网站,那么 FRP 配合一台大带宽 VPS 则是更稳妥的选择。

