跳转到内容

知乎问答-什么是内网穿透?如何实现无公网ip内网穿透?

要解答这个问题,我们要首先明白为什么要进行内网穿透?

主要是想通过互联网访问内网中的节点或者服务,使原来不可达的内部资源,变得可达。

将原来不可达的资源变为可达,大致有以下几种方式可以实现。

第一种:有公网 IP,直接做端口映射

这是最简单的一种情况。

假设家里有一台 NAS:

192.168.1.100

它运行了一个 Web 服务:

192.168.1.100:8080

这个地址只能在家里的局域网中访问。

如果家里的路由器拥有一个公网 IP,例如:

1.2.3.4

并且你能够配置这台路由器,那么完全可以做一条端口映射:

1.2.3.4:8080
      ↓
192.168.1.100:8080

这样互联网中的客户端访问:

1.2.3.4:8080

路由器就会把流量转发给内网中的 NAS。

严格来说,这种方式更准确地应该叫:

NAT 端口映射或者端口转发。

因为这里并没有什么神秘的“穿透”。

公网本来就能访问你的路由器,只不过需要告诉路由器:

收到这个端口的数据以后,应该转发给内网中的哪台机器。

真正麻烦的是:

你连这个公网 IP 都没有。


第二种:没有公网 IP,让内网设备主动连接出去

现在很多家庭宽带、移动网络甚至企业网络都会使用 CGNAT。

网络可能变成:

NAS
192.168.1.100
    ↓
家庭路由器
    ↓
运营商 CGNAT
    ↓
Internet

这时候真正的公网 IP 在运营商手里。

你能够管理自己的家庭路由器,却管理不了运营商的 NAT 设备。

所以即使你在家里的路由器上做了:

8080
 ↓
192.168.1.100:8080

互联网中的客户端依然找不到你。

因为在你的路由器之外,还有一层你无法控制的 NAT。

怎么办?

这里就出现了一个非常重要的思路:

既然互联网无法主动连接进来,那就让内网中的设备主动连接出去。

例如准备一台具有公网 IP 的服务器:

Public Server
1.2.3.4

然后让家里的 NAS 主动连接这台服务器:

NAS
192.168.1.100
      │
      │ 主动连接
      ▼
Public Server
1.2.3.4

因为“访问互联网”本来就是 NAT 最擅长处理的事情,所以这条连接通常能够正常建立。

连接建立以后,公网服务器就和内网设备之间有了一条已经存在的通信路径。

外面的电脑再访问公网服务器:

Laptop
   ↓
Public Server
   ↓
已经建立的连接
   ↓
NAS

这样,本来无法从互联网直接访问的 NAS,就变得可以访问了。

这也是 FRP、SSH Remote Forwarding、Cloudflare Tunnel 等很多方案背后的基本思路。

看起来是:

Internet
   ↓
Internal Host

但真正建立连接的方向其实是:

Internal Host
   ↓
Internet

这个区别非常重要。

所谓“穿透”,很多时候并不是从外面硬闯进 NAT,而是利用内网允许向外建立连接这个条件,反过来建立访问路径。


第三种:两个 NAT 后的设备直接通信——NAT Traversal

还有一种更有意思的情况。

假设 Alice 和 Bob 都没有公网 IP:

Alice
  │
 NAT A
  │
  ▼
Internet
  ▲
  │
 NAT B
  │
 Bob

正常情况下:

Alice 不能直接连接 Bob。

Bob 也不能直接连接 Alice。

但是双方都可以主动访问互联网。

这时候可以先找一台公网服务器作为“介绍人”。

Alice 主动连接服务器,服务器就能看到 Alice 经过 NAT 以后表现出来的公网地址和端口。

Bob 也是如此。

例如:

Alice → 1.1.1.1:50001

Bob   → 2.2.2.2:40001

公网服务器把双方的信息交换一下:

告诉 Alice:

Bob 在 2.2.2.2:40001


告诉 Bob:

Alice 在 1.1.1.1:50001

接下来 Alice 和 Bob 可以尝试同时向对方发送数据。

双方的 NAT 因为看到了主动发出的流量,就可能建立对应的 NAT 状态。

最终有机会形成:

Alice ←────────→ Bob

这就是 NAT Traversal 中常见的 Hole Punching,也就是“打洞”。

这里公网服务器可能只负责:

让两个人找到彼此。

真正的业务流量并不一定经过服务器。

可以把它理解成一个媒人:

Alice → 媒人 ← Bob

找到彼此以后:

Alice ←────→ Bob

这也是为什么很多 P2P、视频通信、游戏、虚拟组网产品都希望优先建立 Direct Connection。

因为一旦建立直接连接:

  • 延迟通常更低;

  • 速度通常更快;

  • 服务器不需要承担所有业务流量。


如果打洞失败怎么办?

问题是:

NAT Traversal 并不是百分之百成功。

不同运营商、不同路由器、不同 NAT 类型、防火墙策略,都可能导致双方无法建立直接连接。

那么怎么办?

最简单粗暴的办法就是:

中继。

变成:

Alice
  │
  ▼
Relay Server
  │
  ▼
Bob

双方都主动连接公网服务器。

服务器负责把 Alice 的数据转给 Bob,再把 Bob 的数据转给 Alice。

于是:

Alice → Relay → Bob
Bob   → Relay → Alice

这种方式的最大优势是:

简单,而且对网络环境要求比较低。

但是缺点也很明显。

所有流量都经过服务器。

所以速度会受到:

  • 中继服务器带宽;

  • 服务器所在地区;

  • 运营商线路;

  • 跨境网络;

  • 服务器负载;

等因素影响。

这也是为什么有些免费的内网穿透服务:

能用,但是速度并不理想。

尤其是你的设备在中国,而中继服务器却在欧洲、美国甚至其他地区的时候,数据可能需要绕很远的路。


所以,无公网 IP 怎么实现内网穿透?

到这里答案其实已经很清楚了。

如果没有公网 IP,大致有三条思路:

无公网 IP
    │
    ├── NAT Traversal 成功
    │       ↓
    │      P2P
    │
    ├── 内网设备主动连接公网服务器
    │       ↓
    │   Reverse Tunnel
    │
    └── 无法直接通信
            ↓
          Relay

对于普通用户来说,最简单的办法当然是直接使用成熟产品。

因为它们已经帮你处理好了:

  • NAT 探测;

  • 节点发现;

  • Hole Punching;

  • 加密;

  • 身份认证;

  • 中继;

  • 连接保持;

这些问题。

你只需要安装客户端。


免费服务为什么可能比较慢?

如果打洞成功:

电脑 ←────────→ 家里 NAS

真正的数据基本直接走双方之间的网络。

这时候厂商服务器承担的流量很少。

但如果打洞失败:

电脑
 ↓
厂商服务器
 ↓
家里 NAS

所有数据都经过厂商服务器。

服务器带宽就是真金白银。

所以很多免费的内网穿透服务会:

  • 限制带宽;

  • 限制流量;

  • 限制中继速度;

  • 限制节点数量;

或者免费节点本身离你比较远。

这并不是技术上“穿不快”,而是:

只要业务流量需要经过第三方服务器,中继服务器的线路和带宽就会成为整个连接的一部分。


不想依赖第三方,可以自己买 VPS

如果对速度、稳定性和控制权要求比较高,也可以自己购买一台具有公网 IP 的 VPS。

例如:

VPS
1.2.3.4

让家里的机器主动连接 VPS:

Home Server
192.168.1.100
       │
       ▼
VPS
1.2.3.4

然后外部访问:

Laptop
   │
   ▼
VPS
   │
   ▼
Home Server

这个时候:

公网节点是你自己的。

服务器放在哪里、带宽多少、走什么线路,都可以自己选择。

FRP 就非常适合做这种事情。

例如:

家里
frpc
  │
  ▼
Internet
  │
  ▼
VPS
frps

外面的客户端只需要访问 VPS,FRP 再通过已经建立好的连接,把流量转回内网。

这也是比较经典的自建内网穿透方式。


最后再重新理解一下“内网穿透”

很多人第一次接触内网穿透时,会觉得:

NAT 后面的机器明明不能被访问,软件到底是怎么“穿”进去的?

其实理解 NAT 以后就会发现,并没有那么神秘。

核心无非是利用了几种办法:

有公网 IP
→ 端口映射

无公网 IP
→ 内部主动建立连接

两个 NAT 后节点
→ NAT Traversal / Hole Punching

直接连接失败
→ Relay

不想用别人的服务器
→ VPS 自建

所以我更愿意把内网穿透理解成:

当一个内部节点没有直接的公网入站路径时,想办法重新为它建立一条从外部可达的通信路径。

而不是某一个具体软件或者协议。

FRP、Tailscale、ZeroTier、Cloudflare Tunnel,甚至 SSH 的 Remote Port Forwarding,采用的技术路线可能完全不同。

它们真正共同解决的,只有一个问题:

原本从互联网访问不到的东西,怎么让它变得可以访问。

但最后还要补一句。

能够访问,和能够安全地访问,是两回事。

一旦你把一个原来封闭在内网里的服务变得互联网可达,也就相当于改变了原来的网络边界。

认证、授权、加密、暴露范围和访问日志,这些问题也必须一起考虑。

所以内网穿透真正解决的只是:

可达性。

至于安全性,则是另外一个问题。