NAT

NAT

NAT 简介

通常所说的 NAT 指 NAPT(Network Address/Port Translator),即同时修改数据包的 IP 和 tcp / udp 端口。以下直接用 "NAT" 来指代 "NAPT"。

NAT 又分为锥型(Cone)和对称型(Symmetric),其区别在于:对于同一内网主机同一端口号,如果是锥型NAT,无论与哪一个外网主机通讯,都不改变所分配的端口号;而如果是对等型NAT,同一内网主机同一端口号,每一次与不同的外网主机通讯,就重新分配另一个端口号。锥型 NAT 又可以分为 "Full Cone","Restricted Cone" 和 "Port Restricted Cone" 三种。

NAT 实现原理

NAT 需要同时修改数据包第三层和第四层数据:

  • IP Header: 修改 src IP、IP 层的 checksum。
  • TCP / UDP Header: 修改 src PORT、TCP/UDP 层的 checksum。

NAT 类型

NAT 一共有以下类型:

  • Full Cone
  • Restricted Cone
  • Port Restricted Cone
  • Symmetic

Full Cone

这种NAT内部的机器A会在路由器上打开一个端口.然后外网的任何发到这个打开的端口的UDP数据报都可以到达A.
例如 A:192.168.8.100 NAT:202.100.100.100 C:292.88.88.88
A(192.168.8.100:5000) -> NAT(202.100.100.100 : 8000) -> C(292.88.88.88:2000)
任何发送到 NAT(202.100.100.100:8000)的数据都可以到达A(192.168.8.100:5000)

Restricted Cone

这种NAT内部的机器A连接过外网的机器C后,NAT打开一个端口.然后C可以用任何端口和A通信.其他的外网机器不行.
例如 A:192.168.8.100 NAT:202.100.100.100 C:292.88.88.88
A(192.168.8.100:5000) -> NAT(202.100.100.100 : 8000) -> C(292.88.88.88:2000)
任何从C发送到 NAT(202.100.100.100:8000)的数据都可以到达A(192.168.8.100:5000)

Port Restricted Cone

这种NAT内部的机器A连接过外网的机器C后,NAT打开一个端口.然后C可以用原来的端口和A通信.其他的外网机器不行.
例如 A:192.168.8.100 NAT:202.100.100.100 C:292.88.88.88
A(192.168.8.100:5000) -> NAT(202.100.100.100 : 8000) -> C(292.88.88.88:2000)
C(202.88.88.88:2000)发送到 NAT(202.100.100.100:8000)的数据都可以到达A(192.168.8.100:5000)
以上三种NAT通称Cone NAT.我们只能用这种NAT进行UDP打洞.

Symmetic

对称 NAT。对于这种NAT.连接不同的外部目标.原来NAT打开的端口会变化.而Cone NAT不会.虽然可以用端口猜测.但是成功的概率很小.因此这种NAT的UDP打洞基本无法实现.

Implement

Linux netfilter 的 SNAT/MASQUERADE 实现的是(动态的) Symmetic 类型 NAT。而 DNAT 实现的是静态的 Full Cone 类型 NAT (iptables -t nat -I PREROUTING -j DNAT)。

UPnP 协议允许动态创建 Full Cone NAT,但其在 Linux 上的实现本质上还是通过动态创建 iptables -j DNAT 规则方式。

NAT 穿透(打洞)

结论:如果通信双方 A 和 B 都位于 Symmetic NAT 之后,那么任何方法都无法可靠地保证打洞,只能依靠“猜测端口”方式,成功率无法保证。


Last update: 2018-06-29 08:33:06 UTC