🔄 NAT 与端口转发:跨越内外网边界的流量转换
NAT(Network Address Translation,网络地址转换) 是 IPv4 时代最伟大的“续命”发明,其核心规范定义于 RFC 1631 和 RFC 3022。
由于私有 IP 地址(如 192.168.x.x 或 10.x.x.x)在公共互联网的骨干路由器上是绝对不可路由的,局域网内的设备必须借用网关的公共 IP 地址才能与外界通信。NAT 的本质,就是网关路由器对流经它的 IP 数据包报头进行动态的拦截、篡改与重写。
从流量方向来看,NAT 主要分为三大核心工作模式:SNAT、DNAT 以及应对特殊拓扑的 Hairpin NAT。
1. 出站通信:SNAT 与伪装 (Masquerade)
Section titled “1. 出站通信:SNAT 与伪装 (Masquerade)”当局域网内的主机主动向公共互联网发起请求时,路由器执行的是 源地址转换(Source NAT, SNAT)。在动态 IP 环境(如家庭宽带拨号)中,这种技术也常被称为伪装(Masquerade)。
1.1 报文重写逻辑
Section titled “1.1 报文重写逻辑”- 拦截阶段:客户端
192.168.10.5使用源端口54321向公网服务器8.8.8.8:53发送 UDP 报文。报文到达网关。 - 重写阶段(修改源):网关发现目标是公网,于是将报文的源 IP 地址篡改为网关自己的 WAN 口公网 IP(如
203.0.113.1),并将源端口映射为一个新的随机高位端口(如60001)。- 此时,报文的结构从
[192.168.10.5:54321 -> 8.8.8.8:53]变成了[203.0.113.1:60001 -> 8.8.8.8:53]。
- 此时,报文的结构从
- 记录状态表(State Table):网关在内存中记录下这条映射关系。
- 接收回包:当
8.8.8.8返回数据时,目标地址是网关的203.0.113.1:60001。网关查阅状态表,执行反向操作,将目标地址重新改回192.168.10.5:54321并投递给局域网主机。
工程学意义:通过 SNAT,成百上千台内网设备可以安全地共享唯一一个公网 IP 上网。对于外部服务器而言,所有的流量看起来都像是从网关这“一台”设备发出的,内网拓扑被完美隐藏。
2. 入站通信:DNAT 与端口转发 (Port Forwarding)
Section titled “2. 入站通信:DNAT 与端口转发 (Port Forwarding)”SNAT 解决了“内部主动访问外部”的问题。但如果公共互联网上的用户,想要主动访问局域网内部提供的一项服务(例如一台监听在 192.168.10.100:443 的 Web 服务器),由于该服务器没有公网 IP,外部流量根本无法寻址。
此时,必须在网关上配置 目的地址转换(Destination NAT, DNAT),在消费级路由器中,这被称为**端口转发(Port Forwarding)**或虚拟服务器。
2.1 报文重写逻辑
Section titled “2.1 报文重写逻辑”- 监听公网端口:网络管理员在网关上配置规则:“凡是访问网关公网 IP
203.0.113.1的 TCP443端口的流量,一律交给内网的192.168.10.100:443”。 - 重写阶段(修改目的):当外部客户端
198.51.100.2尝试连接203.0.113.1:443时,网关拦截该SYN报文。 - 篡改目的坐标:网关将报文的目的 IP 地址修改为
192.168.10.100,并可以按需修改目的端口。- 报文结构从
[198.51.100.2:12345 -> 203.0.113.1:443]变成了[198.51.100.2:12345 -> 192.168.10.100:443]。
- 报文结构从
- 内部投递:被篡改后的报文在局域网内路由,精准抵达 Web 服务器。服务器在回复数据时,网关再次介入,将源地址从内网 IP 伪装回公网 IP。
3. 架构痛点:Hairpin NAT (NAT 回环 / 发夹)
Section titled “3. 架构痛点:Hairpin NAT (NAT 回环 / 发夹)”在部署了 DNAT(端口转发)的网络中,经常会遇到一个极其诡异的连通性故障: “外网用户可以通过公网 IP 或域名正常访问内网服务器,但内网用户在同一个局域网下,使用相同的公网 IP 或域名,却死活连不上该服务器。”
这个现象被称为 NAT Reflection(NAT 反射) 失败,解决它的技术叫做 Hairpin NAT(发夹 NAT)。
3.1 导致连通失败的底层原因(非对称路由)
Section titled “3.1 导致连通失败的底层原因(非对称路由)”假设内网客户端 A(192.168.10.5)和服务器 B(192.168.10.100)在同一个网段。网关的公网 IP 是 203.0.113.1,并配置了向 B 的 DNAT 端口转发。
- 客户端 A 试图通过域名访问服务器 B。DNS 解析返回了公网 IP
203.0.113.1。 - A 向网关(
203.0.113.1)发送SYN报文。 - 网关收到报文,触发 DNAT 规则,将目的 IP 修改为 B 的内网 IP(
192.168.10.100),并扔回给内网(此时数据包的源 IP 依然是 A 的192.168.10.5)。 - 服务器 B 收到报文,发现源 IP 是
192.168.10.5。因为 A 和 B 在同一个子网内,B 在回复SYN-ACK报文时,直接通过交换机二层 MAC 地址把包塞给了 A,根本不经过网关! - 灾难发生:客户端 A 当初请求的是公网 IP
203.0.113.1,现在却莫名其妙收到了来自192.168.10.100的回复。TCP 状态机直接崩盘,A 认为这是一个非法的幽灵报文,立刻发送RST强行阻断连接。
3.2 Hairpin NAT 的终极解法:双向欺骗
Section titled “3.2 Hairpin NAT 的终极解法:双向欺骗”为了打破这种不对称路由,网关必须配置 Hairpin NAT(双向 NAT 转换)。
在上述第 3 步中,网关不仅要执行 DNAT(修改目的为 B),还要同时执行 SNAT(修改源为网关自己的内网 IP 192.168.10.1)。
这样一来,服务器 B 收到报文时,会认为请求是网关发出的,回包也会老老实实地交还给网关。网关再进行两次反向翻译,最终把数据交回给客户端 A。虽然这让路由器多了一次繁重的“发夹式”转发损耗,但彻底解决了内网访问公网域名的逻辑死锁。
4. NAT 规则配置速查表
Section titled “4. NAT 规则配置速查表”在企业级防火墙(如 iptables、Netfilter、pf)中,NAT 规则被严格划分在独立的链(Chains)中执行。
| NAT 类别 | 执行时机 (Hook) | 篡改对象 | 典型应用场景 | 防火墙配置术语 |
|---|---|---|---|---|
SNAT | POSTROUTING (路由决策之后,出接口之前) | 源 IP / 源端口 | 内网设备访问公共互联网。 | MASQUERADE, Source NAT |
DNAT | PREROUTING (入接口之后,路由决策之前) | 目的 IP / 目的端口 | 将公网接口的特定端口流量导入内网服务器。 | Port Forwarding, Destination NAT |
Hairpin NAT | 同上结合使用 | 源与目的双重篡改 | 内网设备使用公网域名访问内网服务。 | NAT Reflection, NAT Loopback |
1:1 NAT | PREROUTING / POSTROUTING | 源或目的 IP (不改端口) | 将一个公网 IP 完全映射给一个内网主机(类似 DMZ)。 | BINAT, One-to-One NAT |
📚 权威规范参考 (RFCs)
Section titled “📚 权威规范参考 (RFCs)”- RFC 3022: Traditional IP Network Address Translator (传统 NAT 架构规范)
- RFC 4787: Network Address Translation (NAT) Behavioral Requirements for Unicast UDP (详细定义了 NAT 处理 UDP 的行为规范)