写在前面
前十一篇把五层模型从链路一路讲到了应用层:以太网与 ARP、IP 编址与路由、TCP/UDP、HTTP/DNS。但有一个非常现实的问题一直没正面回答——
你的电脑 IP 多半是 192.168.1.x,这明明是个"私网地址",为什么能访问公网? 公司里几千台机器共用一个出口 IP,外网的响应是怎么精确回到你这台的? 还有,这个 IP 是谁分配给你的,为什么重启路由器可能就变了?
这些问题的答案就是 NAT 和 DHCP——两个支撑整个现代互联网"最后一公里"的地址机制。本篇把它们一次讲透。
一、为什么需要 NAT
NAT(Network Address Translation,网络地址转换)诞生的直接原因就一个:IPv4 地址不够用了 。
IPv4 总共约 43 亿个地址,扣掉组播、保留、特殊用途,能分给终端的更少。2011 年 IANA 的全球地址池就发完了,APNIC(亚太)等区域注册局也先后告急。与此同时,联网设备却爆炸式增长——每台手机、每台电视、每个智能插座都要 IP。怎么办?
NAT 的思路很朴素:不需要每台设备都有公网 IP,让一群设备共用一个(或少数几个)公网 IP 出网 。具体做法是在内网和公网的边界(家用路由器、企业防火墙)上做地址改写:
- 内网用私网地址,设备之间互相访问;
- 出网时,NAT 把源地址从私网改成公网,返回流量再改回来。
这就引出两个配套概念:私网地址段(内网用什么 IP),以及转换表(怎么把流量对回正确的内网主机)。
NAT 还顺带带来了一个工程上的副作用:隐藏内网结构 。公网看到的全是出口 IP,内网拓扑对外不可见,某种程度上也算一层隔离(但别把它当安全机制用)。
二、私网地址段与公网:RFC 1918
既然内网不走公网路由,就得有一段"大家都能随便用、但不会被公网路由"的地址。这就是 RFC 1918 定义的三个私网地址段:
| 私网地址段 | CIDR | 范围 | 典型场景 |
|---|---|---|---|
| 10.0.0.0/8 | A 类 | 10.0.0.0 – 10.255.255.255 | 企业内网、数据中心(地址多) |
| 172.16.0.0/12 | B 类 ×16 | 172.16.0.0 – 172.31.255.255 | 中等规模内网、容器网络 |
| 192.168.0.0/16 | C 类 ×256 | 192.168.0.0 – 192.168.255.255 | 家庭网络、小型办公 |
这三个段全球任何组织都可以重复使用,因为它们不会出现在公网路由表里——运营商会在边界丢弃目的为私网地址的流量。你家是 192.168.1.x,邻居家也是,互不冲突,因为各自都在自己的 NAT 后面。
规范细节:RFC 1918 地址不应在公共互联网中传播路由。访问
192.168.1.1时,主机会根据本地路由把流量交给本地链路或私网下一跳,而不会靠公网路由去寻找其他组织中重复使用的同名地址;VPN、重叠私网或更具体的本地路由仍可能改变实际去向。
与之相对的是公网地址(也叫可路由地址、全球单播地址),由 IANA → RIR → NIR → ISP 层层分配,全球唯一,能在公网被路由。
除了 RFC 1918,还有几段容易混淆的特殊地址,顺带记住:
| 地址段 | 含义 |
|---|---|
| 127.0.0.0/8 | 环回(loopback),本机自测,最常用 127.0.0.1 |
| 169.254.0.0/16 | 链路本地(link-local),DHCP 拿不到 IP 时操作系统自动配的 |
| 0.0.0.0 | “本机所有地址”,常出现在监听(0.0.0.0:80)和默认路由 |
知道这些段,后面排查"为什么我的 IP 是 169.254.x.x"(答:DHCP 失败了)就不会懵。
三、NAT 工作原理:NAPT
最简单的 NAT 是"一对一"——一个公网 IP 对一个内网 IP,但这等于没省。实际家网、企业网用的几乎都是 NAPT(Network Address Port Translation,也叫 PAT),它同时改 IP 和端口,让多个内网主机共用一个公网 IP。
一次出网的全过程
假设你家出口公网 IP 是 203.0.113.5,内网两台机器同时访问 8.8.8.8:53(DNS):
| |
NAT 在内部维护一张转换表(NAT session table),把"内网 IP:端口"映射到"公网 IP:端口":
| 方向 | 源 | 目的 | 协议 |
|---|---|---|---|
| 内→外(改写前) | 192.168.1.10:5000 | 8.8.8.8:53 | UDP |
| 外→内(公网看到的) | 203.0.113.5:30001 | 8.8.8.8:53 | UDP |
| 内→外(改写前) | 192.168.1.20:5000 | 8.8.8.8:53 | UDP |
| 外→内(公网看到的) | 203.0.113.5:30002 | 8.8.8.8:53 | UDP |
关键点:
- 即便两台内网机器用了相同的源端口(都是 5000),NAT 通过分配不同的外部端口(30001 / 30002)也能区分开来——这就是 NAPT 省地址的精髓。
- 返回流量到达
203.0.113.5:30001时,NAT 查表反查出192.168.1.10:5000,改写目的地址(DNAT)后送回内网。 - 这张表是有状态的,条目有空闲超时(TCP 几小时、UDP 几十秒到几分钟不等),超时未用就清除。
这种出网改源地址的叫 SNAT(Source NAT)。后面端口映射那种"进网改目的地址"的叫 DNAT(Destination NAT)。家用路由器做的 NAPT 本质是 SNAT。
NAT 让公网 IP 消耗骤降——一个家庭、一栋楼甚至一个小区可以共用少数公网 IP。但它的代价也很明显:打破了 IP 端到端的语义 。公网主机没法主动发起连接到内网主机(因为 NAT 表里没有对应条目,包到不了),这直接导致了后面的 P2P 问题。
四、端口映射 / 端口转发
NAPT 解决了"内网出去",但反过来"公网进来"呢?默认情况下,公网主动发起到你出口 IP 的连接,NAT 不知道该转给谁,只能丢弃。
端口映射(port forwarding,也叫端口转发) 就是为这个场景准备的:在 NAT 上配一条静态规则,把"公网某个端口"固定转发到"内网某台主机的某端口"。
| |
常见场景:
- 自托管:在家用宽带搭个博客、游戏服务器,把公网 80/443/25565 映射到内网那台机器;
- 远程访问:把 22(SSH)或 3389(RDP)映射到内网某台主机,出门在外也能连回家;
- 容器 / 虚拟机:Docker 的
-p 8080:80、VirtualBox 的端口转发,本质都是同一个机制,只是在宿主机上做了一层 DNAT。
配置方式各家不同,但概念一致:一条固定的 公网端口 → 内网 IP:端口 规则 。和 NAPT 的动态转换表不同,端口映射是手动写死的、长期有效的。
注意端口映射能成立的前提是你得有公网 IP 。下面马上说,现在很多家网已经没有公网 IP 了。
五、NAT 对 P2P 的阻碍与打洞:STUN / TURN / ICE
NAT 帮我们省了地址,却给 P2P(点对点)通信 添了大麻烦。
P2P 的前提是"两台主机互相直接发包"。但 NAT 后面的主机对外不可见,A 想连 B,B 的 NAT 会直接丢包——因为表里没有 A 的条目。语音通话(WebRTC)、BT 下载、游戏联机这类强 P2P 场景全受影响。
要理解怎么解决,先要知道 NAT 的映射与过滤行为并不完全相同。工程资料常沿用 RFC 3489 的经典分类,从宽松到严格列成下表:
| NAT 类型 | 行为 | 能否打洞 |
|---|---|---|
| Full Cone(完全锥型) | 最宽松:内网主机从内出去后,任何公网主机往那个映射端口发包都能进 | 容易 |
| Restricted Cone(限制锥型) | 只允许发往"内网主机曾访问过的那个公网 IP"的包进来 | 可打洞 |
| Port Restricted Cone(端口限制锥型) | 还限制"必须是那个 IP 的那个端口" | 可打洞 |
| Symmetric(对称型) | 最严格:对不同目的分配不同外部端口,外部几乎无法预测 | 很难,通常要中转 |
术语演进:RFC 3489 后来被 RFC 5389 取代,RFC 4787 / RFC 5780 等文档改用**映射行为(mapping behavior)和过滤行为(filtering behavior)**两个维度描述 NAT。两者必须分别判断;端口保持、hairpinning 和映射超时也会影响连通性。工程里老叫法仍然流行,因此这里只把它当作历史速记。
针对这个困境,业界提出了三件套:
- STUN(Session Traversal Utilities for NAT):客户端向公网的 STUN 服务器发请求,STUN 回包告诉它“你在公网看来是哪个 IP:端口”。这个服务器反射地址可作为 ICE 候选之一;打洞能否成功还取决于双方 NAT 的映射、过滤、端口保持和超时行为,不能只用“是否对称型”一个标签判断。
- TURN(Traversal Using Relays around NAT):当打洞失败(典型是对称型 NAT),就退而求其次,让一台公网中继服务器转发两端流量。能连通,但代价是延迟增加、中继服务器带宽吃紧。
- ICE(Interactive Connectivity Establishment):一套编排框架,把直连、STUN 打洞、TURN 中继都列成候选路径,按优先级依次尝试,选第一个能通的。WebRTC 就是基于 ICE 来协商 P2P 媒体通道的。
一句话:STUN 负责发现公网映射、尝试打洞;TURN 在打不通时当中继;ICE 负责把两者和直连编排起来选最优路径 。
六、CGNAT:为什么家网没有公网 IP
如果你试过在家宽带路由器上配端口映射,却怎么也连不上——很可能你的宽带已经在 CGNAT(Carrier-Grade NAT,运营商级 NAT)后面了,你拿到的根本不是公网 IP 。
CGNAT 是运营商部署的大规模 NAT,目的和家网 NAT 一样:省公网地址。结构上是两层 NAT 串联:
| |
- 你家路由器拿到的是运营商分配的"伪公网 IP",通常是 RFC 6598 定义的共享地址段
100.64.0.0/10(100.64.0.0 – 100.127.255.255); - 这个段专门给 CGNAT 用,和 RFC 1918 私网段区分开,避免和企业内网冲突;
- 你的流量到运营商 CGNAT 后,再被改写成真正的公网 IP 出网。
后果就是:你家路由器做的端口映射,只把端口开到了 100.64.x.x 那一层,公网根本到不了 。这种情况下想做自托管、被外网主动访问,基本只能靠内网穿透(frp、ngrok、Tailscale 之类)走中继了。
怎么判断自己是不是在 CGNAT 后面?先看路由器 WAN 地址是否位于
100.64.0.0/10或 RFC 1918 私网段,再与外部网站看到的出口地址对比。两者不一致是“中间还存在 NAT、代理或 VPN”的强烈迹象,但不能单凭这一点断定就是运营商 CGNAT;双路由、企业出口和 VPN 也会造成类似现象。必要时再结合 traceroute 和运营商信息确认。
CGNAT 的大量部署,本身就是 IPv4 地址枯竭的直接证据。彻底解决要靠 IPv6(它有 2¹²⁸ 个地址,足以让每粒沙子都有公网 IP),但 IPv6 的全面替换依旧是个漫长的工程。
七、DHCP:自动分配 IP(DORA 四步)
讲完了地址转换,再说地址怎么来的。手动给每台机器配 IP 显然不现实——办公网络、Wi-Fi、容器都要求"插上网线 / 连上 Wi-Fi 就能上网"。这件事由 DHCP(Dynamic Host Configuration Protocol,动态主机配置协议)完成。
DHCP 不只分配 IP,还一次性把这几样都下发:
- IP 地址 + 子网掩码(告诉你 IP 和网络范围);
- 默认网关(去往外网的下一跳,详见路由那篇);
- DNS 服务器(域名解析用谁);
- 租约时间(lease time,这个 IP 借你用多久)。
DORA 四步
DHCP 获取地址的过程叫 DORA,是四个报文的首字母:Discover → Offer → Request → Acknowledge。
| |
几个关键点:
- 端口:服务器监听 UDP 67,客户端监听 UDP 68 。Discover 是广播(因为客户端还不知道服务器在哪),Offer / ACK 通常也是广播或单播取决于实现。
- 为什么 Request 要广播:可能网络里有多个 DHCP 服务器都回了 Offer,客户端广播 Request 既是在"认领"选中的那个,也是在告诉其余服务器"我没选你,你可以回收那个 IP"。
- 竞态:客户端发 Discover 后可能收到多个 Offer,一般选最先到达的。
租约与续约
DHCP 给的 IP 不是永久的,而是租约(lease) ,到期不续就回收。续约过程:
- 到租约的 50%(T1),客户端向原服务器单播 Request 续约;
- 到 87.5%(T2),若原服务器没响应,客户端进入 rebinding,向任意 DHCP 服务器广播求续;
- 若到 100% 还没续上,客户端必须释放 IP,重新走一遍 DORA。
这就是为什么"重启路由器 IP 会变"——租约可能到期被回收,再申请时拿到的是池里另一个 IP。同样,ifconfig 看到自己 IP 是 169.254.x.x(链路本地地址),说明 DHCP 整个过程失败了,操作系统给自己随便配了个地址应急。
DHCP 的初始发现依赖广播,但服务器并非“无状态”:它需要维护地址池、客户端标识、租约和到期时间。服务器短时不可用时,客户端通常仍可在现有租约有效期内使用地址,但续租和重新分配会受影响。同一网段可以部署经过协调的多个 DHCP 服务器,却不能随便接入未授权服务器;交换机的 DHCP Snooping 会限制只有信任端口能够发送服务器侧报文,防止私接 DHCP 把终端带到错误网络。
小结
- NAT 的本质是在私网/公网边界改写地址,让多台设备共用一个公网 IP,缓解 IPv4 地址枯竭;实际用的 NAPT 同时改 IP 和端口,靠一张有状态的转换表把流量对回正确主机。
- RFC 1918 定义了三个可重复使用的私网地址段(10/8、172.16/12、192.168/16);RFC 6598 的
100.64.0.0/10专给运营商 CGNAT 用,CGNAT 是家网"没有公网 IP"的根因。 - 端口映射(DNAT)把公网端口固定转发到内网,用于自托管;前提是真公网 IP。
- NAT 破坏了端到端,给 P2P 制造障碍;STUN 打洞、TURN 中继、ICE 编排 是 WebRTC 等场景的标准解法,对称型 NAT 通常只能靠 TURN 中继。
- DHCP 用 DORA 四步(Discover/Offer/Request/Acknowledge)自动下发 IP、掩码、网关、DNS,配合租约机制管理地址池;端口是 UDP 67(服务器)/ 68(客户端)。
下一篇是系列收官:TCP/IP(十三):抓包与网络诊断方法论 ——把前面学的所有协议落到工具上,给一套分层的连通性排障方法论,再把整个系列串一遍。
参考: