前言:为什么总是“连不上”?相信很多人第一次接触“内网穿透”,都是因为这样一个问题:

“我在家写了个网页想让朋友访问,结果他连不上。”

或者更常见的:

“我在学校写了个小游戏服务器,结果公网的同学都进不来。”

于是有人告诉你:“映射个端口就行”,你照做了,但 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 消失、所有设备都有公网地址,

那时“内网穿透”这个词会被历史淘汰。

但在那之前,

每一个能让本地服务“走出内网”的程序员,

都在和整个互联网的边界对抗。

作者观点:

“内网穿透,不只是技术问题。

它是一种对网络结构的反思——

在一个封闭的世界里,

我们总会想办法找到那条通向外面的路。”