NAT 网络地址转换
NAT 网络地址转换
一个问题:公网 IP 不够怎么办
1990 年代初,互联网开始商业化。中国第一批网民拿到的不是公网 IP,而是 10.0.0.0/8 这种私有地址。运营商出口设备做一件事:把内部私有 IP 翻译 成公网 IP,再把外网回来的包翻译回去。用户的电脑不知道这件事,外部服务器也以为在跟一个普通公网 IP 通信。
这就是 NAT(Network Address Translation)——网络地址转换。它是 IPv4 枯竭的"创可贴",让互联网多撑了 20 多年。今天中国家庭宽带 100% 是 NAT,企业出口 90% 是 NAT。如果没 NAT,IPv4 早就用完了,IPv6 会被迫提前 10 年普及。
但 NAT 不是没有代价。它违反了"端到端"原则——公网上的主机无法主动发起连接到一个 NAT 内部的主机。这让 P2P、视频通话、SSH 反向连接、IPFS 都变得困难。
NAT 的工作原理
你家路由器就是一台 NAT 设备。假设你电脑 192.168.1.100 想访问 8.8.8.8(Google DNS):
图注:路由器把源 IP 从私有地址改成公网 IP,源端口也改了。Google 看到的源是公网 IP,不知道内网私有地址的存在。
关键点:
- 你的电脑用私有 IP 发包,路由器把源 IP 改成自己的公网 IP
- 路由器还会改源端口(54321 → 8888),让一个公网 IP 能对应多个内网主机
- Google 看到的源是
100.64.10.20:8888,以为是这台公网主机在访问它 - Google 回包到
100.64.10.20:8888,路由器查 NAT 表,知道这是192.168.1.100:54321的会话,改目的 IP 转发回去 - 你的电脑以为在直接和 Google 通信
NAT 表长这样:
| 协议 | 内部 IP:Port | 公网 IP:Port | 目的 IP:Port |
|---|---|---|---|
| TCP | 192.168.1.100:54321 | 100.64.10.20:8888 | 8.8.8.8:53 |
| TCP | 192.168.1.101:60001 | 100.64.10.20:8889 | 8.8.8.8:53 |
| UDP | 192.168.1.102:45000 | 100.64.10.20:8890 | 1.1.1.1:53 |
每条会话一条记录。TCP 连接关闭或 UDP 静默几分钟(典型 5 分钟)后记录被清掉。
三种 NAT 类型
完全圆锥型(Full Cone NAT)
- 内部主机 X:N 给外部 Y:Z 发包后,任何外部主机都能通过 NAT 的公网 IP 找到 X:N
- 路由器把所有从 Y:Z 来的包都翻译给 X:N
- 优点:外部主机可以主动连进来
- 缺点:安全性差
地址限制圆锥型(Address-Restricted Cone NAT)
- 内部主机 X:N 给 Y 发包后,只有 Y(任意端口)能连回 X:N
- 路由器只允许来自 Y 的包进入
- 优点:比 Full Cone 稍安全
- 缺点:外部 Y 主动发包能进,但其他主机进不来
端口限制圆锥型(Port-Restricted Cone NAT)
- 内部主机 X:N 给 Y:Z 发包后,只有 Y:Z(同一端口)能连回 X:N
- 路由器严格匹配 IP+端口
- 优点:最严格
- 缺点:P2P 通信需要打洞
对称型 NAT(Symmetric NAT)
- 内部主机 X:N 给 Y1:Z1 发包用公网 IP:Port1,给 Y2:Z2 发包用公网 IP:Port2
- 每次目的不同,公网映射就变
- 优点:最安全
- 缺点:几乎无法 P2P 穿透
NAT 穿透:P2P 怎么工作
微信视频通话、Zoom 会议、BT 下载都是 P2P 流量。但 P2P 双方都在 NAT 后面,没有公网 IP,怎么连?
STUN 方案:
- 双方都连 STUN 服务器(公网服务器)
- STUN 服务器告诉 A:"你的公网 IP 是 X:N1"
- STUN 服务器告诉 B:"你的公网 IP 是 Y:N2"
- A 尝试给 Y:N2 发包,Y:N2 上的 NAT 收到后查 NAT 表——发现之前 B 主动连过 A 的公网端口,允许回包
- 这叫 NAT 打洞(NAT Hole Punching)
STUN 只对 Full/Restricted Cone NAT 有效。对称 NAT 每次目的不同都换端口,没法用 STUN。
TURN 方案:
- 双方 P2P 连不上时,让所有流量都走 TURN 服务器中转
- TURN 服务器是公网中继,分配公网端口给双方
- A 发包给 TURN,TURN 转给 B;B 回包给 TURN,TURN 转给 A
- 优点:100% 穿透
- 缺点:服务器压力大、延迟高、流量全部走服务器(成本高)
WebRTC 默认 STUN + TURN 组合。视频会议软件(Zoom、腾讯会议)会用 TURN 中转作为兜底。
CGNAT:运营商的双重 NAT
问题:家庭用户用 NAT 已经把公网 IPv4 复用几倍。但移动用户爆炸式增长,运营商自己也没公网 IP 了。怎么办?
CGNAT(Carrier-Grade NAT):运营商在城域网出口再做一层 NAT。家庭路由器的"公网 IP"其实是运营商内部地址(100.64.0.0/10 段,RFC 6598 规定),真正的公网 IP 在运营商 CGNAT 设备后面。
这意味着:
- 你
curl ifconfig.me看到的 IP 是 CGNAT 出口的公网 IP,可能几千个用户共享 - 同一时刻不同 CGNAT 用户的"出口 IP"可能不同,登录态难保持
- 游戏玩家、视频主播、自建服务器的人特别痛——NAT 嵌套让内网穿透几乎不可能
怎么判断自己是不是 CGNAT:
- 登录路由器看 WAN 口 IP,
100.64.x.x或10.x.x.x是 CGNAT - 路由器 WAN 口是公网 IP,但登录同一个网站看
ip.sb显示另一个 IP——也是 CGNAT - CGNAT 用户开 FTP、SSH 主动服务都做不了
真实场景:为什么 P2P 软件越来越难连
2005-2015 年是 P2P 的黄金时代。BT、电驴、PPTV 满天飞。那时候家庭路由器还是 Full Cone NAT 多,P2P 穿透率高。
2015 年以后运营商大规模部署 CGNAT,加上 IPv4 枯竭,运营商开始给家庭路由器分对称 NAT 或端口限制 NAT。P2P 穿透率从 80% 跌到 30%。
后果:
- 视频通话软件(微信视频、QQ 视频)经常失败,要么走服务器中转(延迟高、画质差)
- BT 下载慢到 0,因为连不上 DHT 网络里的其他 peer
- IPFS 几乎跑不起来,节点间连不通
- 游戏联机匹配到 P2P 模式时延迟大
行业应对:HTTP/3 协议(基于 QUIC)天然适合 NAT 环境,因为 QUIC 用 0-RTT 握手和连接复用,不依赖 NAT 表快速建立。Cloudflare、Akamai 推 QUIC 一部分原因就是这个。
IPv6 终极方案
NAT 是 IPv4 不够用的"创可贴"。真正的解药是 IPv6——128 位地址,地球上每粒沙子都能分到几个 IP。
IPv6 时代家庭路由器不需要 NAT,每个设备都有公网 IPv6 地址。运营商默认给 64 位前缀,下面的设备全用 SLAAC 自动配置全球唯一地址。
中国 IPv6 部署率 2024 年已超 70%。访问 test-ipv6.com 看自己是否走 IPv6。如果走 IPv6,你的设备是直接和外部通信,没有 NAT,性能更好、P2P 穿透率 100%。
但 IPv6 部署有惯性——老应用不支持 IPv6,运营商只给局域网 IPv6 出口,部分中间设备改造不彻底。所以未来 5-10 年 NAT 仍然是主流,IPv6 渐进式替换。
思考题
- 一个公司有 1000 台员工电脑,都从公司 NAT 出口。公司想给员工开内部 FTP 服务(公网 IP:21 端口)。为什么这不可行?技术上怎么解决?(提示:端口映射/静态 NAT)
- 你在酒店用 Wi-Fi 上网,看
ip.sb显示的 IP 和家里不一样。这能说明酒店在用 NAT 吗?不一定,为什么?(提示:IP 可能被多台设备复用或 IP 池分配) - WebRTC 优先用 STUN,失败后用 TURN。但 TURN 服务器的带宽成本很高。视频会议软件怎么降低 TURN 带宽成本?(提示:选择性中转、SFU/MCU 架构、分层编码 SVC)
- 中国移动宽带用户在 NAT 后面,但中国电信机房服务器想主动推送消息给移动用户。有什么办法实现?(提示:长连接、心跳穿透、消息推送服务)
延伸阅读
- 《深入浅出计算机网络》(高军)第 4 章
- RFC 3022: Traditional NAT
- RFC 3489: STUN - Simple Traversal of User Datagram Protocol
- RFC 5766: TURN
- RFC 6598: IANA-Reserved IPv4 Prefix for Shared Address Space (CGNAT)
- 动手实验:在 Linux 用 iptables 配置一个 SNAT 规则
- 动手实验:访问 test-ipv6.com 看自己是否支持 IPv6