NAT 网络地址转换
为什么需要 NAT
IPv4 地址只有 43 亿个,全球人口 80 亿,平均两人分一个 IP。但 NAT(Network Address Translation,网络地址转换)让一个公网 IP 可以服务数千台内网设备,缓解了地址枯竭。
NAT 的核心思想:修改 IP 包中的地址字段,让私有地址的设备能访问公网,也让公网能访问内网服务器。
NAT 的三种基本类型
1. 静态 NAT(Static NAT)
一对一固定映射:
内网 192.168.1.10 ↔ 公网 203.0.113.10
内网 192.168.1.11 ↔ 公网 203.0.113.11
用途:服务器对外提供服务,每台服务器独占一个公网 IP。 缺点:不节省地址,一个内网 IP 消耗一个公网 IP。
2. 动态 NAT(Dynamic NAT)
从公网地址池中动态分配:
地址池:203.0.113.10 ~ 203.0.113.20(共 11 个)
内网 100 台设备同时上网,最多 11 台能获得公网 IP
第 12 台想上网?排队等别人释放
缺点:并发数受限于地址池大小,仍不解决根本问题。
3. NAPT / PAT(网络地址端口转换)
真正的救星。不仅转换 IP 地址,还转换端口号,让多个内网设备共享一个公网 IP。
内网设备 A: 192.168.1.10:50000 → NAT → 203.0.113.1:60001
内网设备 B: 192.168.1.11:50000 → NAT → 203.0.113.1:60002
内网设备 C: 192.168.1.12:443 → NAT → 203.0.113.1:60443
四元组映射表:
| 内网地址 | 内网端口 | 公网地址 | 公网端口 | 目的地址 |
|---|---|---|---|---|
| 192.168.1.10 | 50000 | 203.0.113.1 | 60001 | 8.8.8.8:53 |
| 192.168.1.11 | 50000 | 203.0.113.1 | 60002 | 1.1.1.1:53 |
| 192.168.1.12 | 443 | 203.0.113.1 | 60443 | 0.0.0.0:0(等待入站) |
生活例子:一栋公寓楼只有一个门牌号(公网 IP),但每户有独立的信箱号(端口号)。邮递员按"门牌号+信箱号"就能准确送达。
NAPT 的核心是四元组映射表:内网地址+端口 ↔ 公网地址+端口。多个内网设备可以共用同一个公网 IP,只要端口号不同,NAT 路由器就能准确区分和转发。
SNAT vs DNAT
| 类型 | 方向 | 修改字段 | 场景 |
|---|---|---|---|
| SNAT(Source NAT) | 内网 → 公网 | 修改源 IP/Port | 内网设备上网 |
| DNAT(Destination NAT) | 公网 → 内网 | 修改目的 IP/Port | 外网访问内网服务器 |
| NAPT | 双向 | 同时修改源和目的 | 家用路由器 |
SNAT 流程(内网访问百度)
PC (192.168.1.10:50000) → 路由器
路由器查 NAT 表,无匹配,新建条目:
192.168.1.10:50000 ↔ 203.0.113.1:60001
修改包:
源 IP: 192.168.1.10 → 203.0.113.1
源 Port: 50000 → 60001
发送到百度
百度回复到 203.0.113.1:60001 → 路由器
路由器查 NAT 表:60001 → 192.168.1.10:50000
修改目的 IP/Port,转发给 PC
DNAT 流程(外网访问内网 Web 服务器)
外网用户访问 203.0.113.1:80
路由器配置 DNAT:203.0.113.1:80 → 192.168.1.100:80
修改包:
目的 IP: 203.0.113.1 → 192.168.1.100
目的 Port: 80 → 80
转发给内网服务器
服务器回复给外网用户
路由器同时做 SNAT(如果服务器网关是路由器)
源 IP: 192.168.1.100 → 203.0.113.1
SNAT 的关键在于出向流量触发映射建立:内网主机第一次访问外网时,NAT 路由器动态创建四元组映射条目,后续该会话的所有往返流量都依据此表转换。条目通常有超时时间(如 5 分钟无流量则删除)。
CGNAT:运营商级 NAT
家用路由器做 NAT 是"第一层 NAT",但公网 IP 还是不够。运营商在核心网再做一次 NAT,称为 CGNAT(Carrier-Grade NAT,RFC 6598)。
NAT444 模型
你的手机 (10.0.0.5)
→ 基站 NAT (100.64.0.1) 【CGNAT,运营商】
→ 公网 IP (203.0.113.5)
- 第一层:你的路由器(如果有)
- 第二层:运营商 CGNAT
- 结果:两层 NAT,端到端彻底断裂
CGNAT 专用地址:100.64.0.0/10(100.64.0.0 ~ 100.127.255.255)。如果你查到的公网 IP 落在这个范围,说明你在运营商 CGNAT 后面,没有真正的公网 IP。
NAT 的副作用与穿透
副作用 1:破坏端到端原则
互联网设计之初,任何两台主机可以直接通信。NAT 后,内网主机没有公网 IP,别人找不到它。
副作用 2:协议嵌入 IP 地址时失效
FTP 协议在数据通道中嵌入了自己的 IP 地址,NAT 只改首部不改载荷,导致 FTP 在 NAT 后经常出问题。需要 ALG(Application Layer Gateway) 特殊处理。
副作用 3:P2P / VoIP / 游戏联机困难
两台内网主机想直接视频通话?互相不知道对方的公网映射地址。
NAT 穿透技术
| 技术 | 原理 | 适用场景 |
|---|---|---|
| STUN | 向公网 STUN 服务器查询自己的公网映射地址 | 知道公网地址后尝试直连 |
| TURN | 通过公网 TURN 服务器中继转发 | 直连失败时的兜底 |
| ICE | 综合 STUN+TURN,自动选择最优路径 | WebRTC 标准方案 |
| UPnP / NAT-PMP | 内网主机请求路由器自动开放端口映射 | 家用路由器 |
STUN 示例:
内网 PC (192.168.1.10:50000) → STUN 服务器 (stun.l.google.com:19302)
STUN 服务器回复:"我看到你来自 203.0.113.1:60001"
PC 就知道自己的公网映射是 203.0.113.1:60001
ICE(Interactive Connectivity Establishment)是 WebRTC 的标准方案,它会同时尝试所有可能的连接路径:先尝试直连(同一局域网),再尝试 STUN 打洞,最后兜底用 TURN 中继。这种"并行探测 + 择优选择"的策略最大化 P2P 成功率。
IPv6 与 NAT
IPv6 地址空间充足,设计初衷是取消 NAT,恢复端到端通信。每个设备都能获得全球唯一的公网 IPv6 地址。
但现实中 NAT66 仍存在:
- 企业安全策略要求隐藏内部拓扑
- 多宿主(Multi-homing)场景需要地址统一
- 某些过渡方案需要地址转换
本篇小结
- NAT 让私有地址设备共享公网 IP,缓解 IPv4 枯竭
- NAPT/PAT 通过端口复用,实现多对一映射
- SNAT 改源地址(内网上网),DNAT 改目的地址(外网访问内网)
- CGNAT 是运营商级双层 NAT,使用 100.64.0.0/10
- NAT 破坏端到端,P2P 需要 STUN/TURN/ICE 穿透
- IPv6 设计取消 NAT,但 NAT66 仍有特定场景
动手实践
查看家用路由器 NAT 表(如果有 Web 管理界面,找"会话表"或"连接跟踪")
Linux 查看 NAT 连接跟踪:
sudo conntrack -L # 或 sudo cat /proc/net/nf_conntrack | head -20查看本机是否处于 CGNAT:
curl ifconfig.me # 如果返回 100.64.x.x ~ 100.127.x.x,说明在 CGNAT 后测试 STUN:
# 安装 stun-client stun stun.l.google.com:19302思考:为什么 FTP 在 NAT 后容易出问题?ALG 是如何解决的?