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)

总结:在一个新会话建立了公网/内网端口绑定之后,全锥形NAT接下来会接受对应公网端口的所有数据,无论是来自哪个(公网)终端。全锥NAT有时候也被称为“混杂”NAT(promiscuous NAT)。

这种类型的 NAT 就是端口映射,Linux 上实现方式是 iptables -t nat PREROUTING -j DNAT。

Restricted Cone

从同一私网地址端口192.168.0.8:4000发至公网的所有请求都映射成同一个公网地址端口1.2.3.4:62000,只有当内部主机192.168.0.8先给服务器C 6.7.8.9发送一个数据报后,192.168.0.8才能收到6.7.8.9发送到1.2.3.4:62000的数据报。

总结:受限锥形NAT只会转发符合某个条件的输入数据包。条件为:外部(源)IP地址匹配内网主机之前发送一个或多个数据包的结点的IP地址。受限NAT通过限制输入数据包为一组“已知的”外部IP地址,有效地精简了防火墙的规则。

Port Restricted Cone

从同一私网地址端口192.168.0.8:4000发至公网的所有请求都映射成同一个公网地址端口1.2.3.4:62000,只有当内部主机192.168.0.8先向外部主机地址端口6.7.8.9:8000发送一个数据报后,192.168.0.8才能收到6.7.8.9:8000发送到1.2.3.4:62000的数据报。

总结:端口受限锥形NAT也类似,只当外部数据包的IP地址和端口号都匹配内网主机发送过的地址和端口号时才进行转发。端口受限锥形NAT为内部结点提供了和对称NAT相同等级的保护,以隔离未关联的数据。

以上三种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: 2020-07-27 04:33:16 UTC