什么是对称型NAT?具体定义是什么?

网络地址转换(NAT)是互联网协议中一项广泛使用的技术,它允许一个私有网络中的多个设备共享一个公共IP地址连接到互联网。NAT根据其处理外部连接请求和传入数据包的方式,可以细分为不同的类型。其中,

对称型NAT(Symmetric NAT)是NAT类型中最严格的一种。它的核心特点可以用一句话概括:对于同一个内部地址和端口,它使用一个特定的外部地址和端口,并且这个外部地址和端口只与第一个发送数据的目的地址和目的端口绑定。

换句话说,如果您内部网络的一台设备(比如IP地址为 `192.168.1.100`,使用源端口 `50000`)首先向服务器A(IP地址 `1.1.1.1`,端口 `80`)发送了一个数据包,对称型NAT设备会为其分配一个临时的外部IP和端口(比如 `203.0.113.5:60000`),并在其内部维护一个映射表:(192.168.1.100:50000, 1.1.1.1:80) <-> 203.0.113.5:60000

随后,如果同一台内部设备(依然是 `192.168.1.100:50000`)尝试向服务器B(IP地址 `2.2.2.2`,端口 `443`)发送数据包,对称型NAT会重新分配一个不同的外部IP和端口(比如 `203.0.113.5:60000` 已经是之前映射所用,可能会分配一个新的端口,例如 `203.0.113.5:60001`),并创建另一个映射表项:(192.168.1.100:50000, 2.2.2.2:443) <-> 203.0.113.5:60001

这里的关键是:同一个内部地址和端口,去往不同的目的地址和端口,会使用不同的外部地址和端口进行映射。这种“一对一、绑定特定目的地”的映射规则,是区分对称型NAT与其他NAT类型(如全锥型、受限锥型、端口受限锥型)的最核心特征。

对称型NAT是如何工作的?详细过程是怎样的?

对称型NAT的工作流程主要体现在它如何建立和维护连接的映射关系,以及如何处理外部发起的(或与现有映射不完全匹配的)传入数据包。

外发连接的处理过程:

  1. 内部设备发起连接: 内部设备 A (Int_IP:Int_Port) 想连接外部服务器 X (Ext_IP_X:Ext_Port_X)。
  2. NAT设备接收并查找映射: NAT设备收到来自 A 的数据包。它检查其内部映射表,看是否已经存在一个针对 (Int_IP:Int_Port, Ext_IP_X:Ext_Port_X) 的映射。
  3. 创建新映射(如果不存在): 如果没有找到匹配的映射,NAT设备会从其可用的外部IP和端口池中选择一个可用的外部端口 (Nat_Port),并使用其外部IP (Nat_IP)。然后,它创建一个新的映射表项:(Int_IP:Int_Port, Ext_IP_X:Ext_Port_X) <-> (Nat_IP:Nat_Port)
  4. 转换数据包并发送: NAT设备修改数据包的源IP地址为 Nat_IP,源端口为 Nat_Port,然后将数据包发送到外部服务器 X。
  5. 处理同一内部端口去往不同目的地: 如果内部设备 A (Int_IP:Int_Port) 随后想连接另一个外部服务器 Y (Ext_IP_Y:Ext_Port_Y),NAT设备会重复步骤2-4。但由于目的地不同 (Ext_IP_Y:Ext_Port_Y 而非 Ext_IP_X:Ext_Port_X),NAT设备会为其分配一个**新的**、**不同的**外部端口 (Nat_Port_Y),并创建映射表项:(Int_IP:Int_Port, Ext_IP_Y:Ext_Port_Y) <-> (Nat_IP:Nat_Port_Y)。这就体现了其“对称”或“目的地依赖”的特性。

传入数据包的处理过程:

  1. NAT设备接收传入数据包: NAT设备收到一个从外部IP:端口 (Src_Ext_IP:Src_Ext_Port) 发送过来,目的地址为 NAT外部IP:端口 (Nat_IP:Nat_Port) 的数据包。
  2. 查找匹配的映射: NAT设备查找其内部映射表,寻找一个精确匹配以下所有条件的项目:

    • 外部IP和端口是 Nat_IP:Nat_Port
    • 内部IP和端口是某个 Int_IP:Int_Port
    • 关联的目的地(即发起该连接的外部主机)是 Src_Ext_IP:Src_Ext_Port
  3. 转发或丢弃:

    • 如果找到了完全匹配的映射表项 (Int_IP:Int_Port, Src_Ext_IP:Src_Ext_Port) <-> (Nat_IP:Nat_Port),则说明这个数据包是之前由 Int_IP:Int_Port 发起、并发送给 Src_Ext_IP:Src_Ext_Port 的连接的响应数据包。NAT设备会转换数据包的目的地址为 Int_IP,目的端口为 Int_Port,然后将数据包转发给内部设备 A。
    • 如果没有找到完全匹配的映射表项,则说明这个数据包不是针对现有连接的预期响应,或者它来自一个与原始连接目的地不同的源。在这种情况下,即使存在一个外部端口为 Nat_Port 的映射,但如果它的关联目的地不是 Src_Ext_IP:Src_Ext_Port,这个传入的数据包也会被**丢弃**。

正是这个严格的传入过滤规则(只接受来自原始连接目的地的响应),使得对称型NAT在某些应用场景下(尤其是P2P通信)带来了挑战。

为什么很多情况下对称型NAT难以实现P2P通信?(涉及打洞问题)

对称型NAT对P2P通信的挑战主要在于其“目的地依赖”的映射和过滤规则,这使得“UDP打洞”(UDP Hole Punching)技术难以成功。

UDP打洞的基本思想是:通信双方(比如在不同NAT后面的A和B)都先连接到一个公共的第三方服务器(比如S)。服务器S得知A和B各自的外部IP和端口后,将这些信息互相告知。然后A和B尝试直接向对方的外部IP和端口发送UDP包,希望通过NAT设备上之前创建的“洞”来建立直接连接。

问题出现在对称型NAT上:

  1. A连接服务器S:A的对称型NAT(NAT_A)会为其内部地址端口 A_int:Port_A 分配一个外部地址端口 A_ext:Port_A’,但这个映射 (A_int:Port_A, S_IP:S_Port) <-> A_ext:Port_A' 是专门绑定到服务器S的。
  2. B连接服务器S:B的对称型NAT(NAT_B)会为其内部地址端口 B_int:Port_B 分配一个外部地址端口 B_ext:Port_B’,这个映射 (B_int:Port_B, S_IP:S_Port) <-> B_ext:Port_B' 绑定到服务器S。
  3. 服务器S交换信息:S告诉A,B的外部地址是 B_ext:Port_B’;告诉B,A的外部地址是 A_ext:Port_A’。
  4. A尝试直接连接B:A现在尝试向 B_ext:Port_B’ 发送数据包。当这个包到达 NAT_A 时,由于目的地是 B_ext:Port_B’ (而不是 S_IP:S_Port),NAT_A 会为 A_int:Port_A 分配一个**新的**、**不同的**外部端口,比如 A_ext:Port_A”,并创建映射 (A_int:Port_A, B_ext:Port_B') <-> A_ext:Port_A''。然后使用 A_ext:Port_A” 作为源地址发送数据包给 B_ext:Port_B’。
  5. B尝试直接连接A:B也尝试向 A_ext:Port_A’ 发送数据包。当这个包到达 NAT_B 时,由于目的地是 A_ext:Port_A’ (而不是 S_IP:S_Port),NAT_B 会为 B_int:Port_B 分配一个**新的**、**不同的**外部端口,比如 B_ext:Port_B”,并创建映射 (B_int:Port_B, A_ext:Port_A') <-> B_ext:Port_B''。然后使用 B_ext:Port_B” 作为源地址发送数据包给 A_ext:Port_A’。
  6. 数据包到达对方NAT:

    • 来自 A (现在源地址是 A_ext:Port_A”,目的地址是 B_ext:Port_B’) 的数据包到达 NAT_B。NAT_B 查找映射表,期望找到一个由 B_int:Port_B 发起、去往 A_ext:Port_A” 并且绑定到 B_ext:Port_B’ 的映射。但是,NAT_B 当前为 B_int:Port_B 去往 A_ext:Port_A’ 创建的映射是 (B_int:Port_B, A_ext:Port_A') <-> B_ext:Port_B''。传入数据包的源 (A_ext:Port_A”) 与这个映射的目标地址 (A_ext:Port_A’) 不匹配,**因此 NAT_B 丢弃数据包**。
    • 来自 B (现在源地址是 B_ext:Port_B”,目的地址是 A_ext:Port_A’) 的数据包到达 NAT_A。NAT_A 查找映射表,期望找到一个由 A_int:Port_A 发起、去往 B_ext:Port_B” 并且绑定到 A_ext:Port_A’ 的映射。但是,NAT_A 当前为 A_int:Port_A 去往 B_ext:Port_B’ 创建的映射是 (A_int:Port_A, B_ext:Port_B') <-> A_ext:Port_A''。传入数据包的源 (B_ext:Port_B”) 与这个映射的目标地址 (B_ext:Port_B’) 不匹配,**因此 NAT_A 丢弃数据包**。

可以看到,由于对称型NAT对不同目的地使用不同的外部端口,并且严格要求传入数据包的源IP和端口与原始连接的目的IP和端口完全匹配,A和B尝试直接互相发送的数据包会被对方的对称型NAT无情地丢弃,导致打洞失败。

为什么有些设备或网络会采用对称型NAT?它的优点在哪里?

尽管对称型NAT给P2P通信带来了困难,但它依然被广泛采用,尤其是在某些特定的网络环境中。这主要是因为它具有以下几个潜在的优点:

  • 增强的安全性(无意中的副作用): 对称型NAT的严格过滤规则意味着,只有那些完全匹配现有内部发起连接的目的地和端口的传入数据包才会被允许通过。任何来自其他源IP/端口、或者与现有映射目的地不符的传入流量都会被默认丢弃。这无意中提供了一种非常强大的内置防火墙功能,极大地限制了外部主机未经请求地访问内部设备,从而提高了网络的安全性。
  • 简化某些状态管理: 虽然对称型NAT需要为每个“内部源 + 外部目的”对维护一个独立的映射,这可能导致映射表项更多,但在某些实现中,这种严格的分离可能简化了查找和管理逻辑。它避免了处理来自不同外部IP但通过同一个外部端口进入的复杂情况。
  • 资源分配的明确性: 每个“内部源 + 外部目的”对都获得一个独立的外部端口,这使得跟踪哪些外部端口正被哪些内部连接用于与哪个外部服务通信变得非常清晰。这对于故障排除和资源监控可能有所帮助。
  • 易于作为默认配置: 在一些通用路由器或运营商级NAT (CG-NAT) 设备上,对称型NAT可能是为了实现上述安全性或简化某些内部管理而选择的默认模式。

对称型NAT通常在哪里被使用?

对称型NAT可以在多种网络环境中遇到:

  • 家用路由器: 许多现代消费级无线路由器可能会将对称型NAT作为其默认的NAT类型,或者是在其固件更新后变为这种类型。这可能是出于提升安全性的考虑,尽管用户可能并未意识到这对某些应用(如在线游戏、VoIP、文件共享等)会造成影响。
  • 移动运营商网络(CG-NAT): 随着IPv4地址资源的枯竭,移动运营商广泛部署了运营商级NAT (CG-NAT)。在CG-NAT环境中,大量的移动设备共享少量的公共IPv4地址。为了有效地管理这些大量的连接并隔离用户流量,对称型NAT或其变种经常被采用。这就解释了为什么在使用手机流量连接时,某些P2P应用或服务可能难以正常工作。
  • 企业网络: 虽然大型企业网络通常会有更复杂的防火墙和网络配置,但在某些特定的分支机构或某些特定的安全区域,出于隔离和安全考虑,也可能部署使用了对称型NAT的设备。
  • 某些软件防火墙: 一些个人或服务器端的软件防火墙在配置NAT功能时,也可能采用对称型NAT的策略。

判断自己网络是否使用了对称型NAT,通常需要借助专门的工具(如STUN客户端)来探测NAT类型。

如何知道我的网络是否使用了对称型NAT?如何应对它的限制?

要确定您的网络是否使用了对称型NAT,最常见的方法是使用一个STUN(Session Traversal Utilities for NAT)客户端。STUN服务器能够帮助客户端发现自己的外部IP地址和端口,以及识别NAT的类型。通过与多个STUN服务器或同一个STUN服务器的多个地址/端口进行交互测试,STUN客户端可以根据NAT设备响应的行为模式来判断其类型。如果测试结果显示NAT对来自不同服务器IP或端口的请求使用了不同的外部端口进行映射,那么很可能就是对称型NAT。许多在线NAT类型检测工具或支持STUN的应用程序都可以提供这种信息。

应对对称型NAT的限制(主要是P2P通信困难)通常不是通过改变NAT本身的配置(因为用户往往没有权限或选项),而是通过应用层或网络穿越技术:

  • 使用中继服务器(TURN): TURN(Traversal Using Relays around NAT)是一种更复杂的网络穿越技术。如果STUN检测表明是对称型NAT且打洞失败,应用程序可以回退到使用TURN服务器。在这种模式下,通信双方不直接互相发送数据,而是将所有数据发送给TURN服务器,再由TURN服务器转发给对方。虽然这解决了连接问题,但增加了延迟和服务器成本,因为它消耗了服务器的带宽和处理能力。
  • 通用打洞技术(ICE): ICE(Interactive Connectivity Establishment)是一个综合性的框架,它结合了STUN、TURN以及直接连接尝试等多种技术。应用程序会尝试多种方法来建立连接(包括UDP打洞、TCP连接、通过TURN中继等),并选择最有效的一种。ICE使得应用程序在面对不同类型的NAT时具有更好的鲁棒性。许多VoIP、视频会议和在线游戏应用都使用了ICE。
  • 端口映射/转发(Port Forwarding): 对于需要外部主动发起连接的服务(如架设Web服务器、FTP服务器、或某些P2P应用的种子/Peer端),如果用户有权限配置NAT设备,可以设置端口映射规则。但需要注意的是,即使设置了端口映射,对称型NAT的严格过滤可能仍然意味着只有发往特定端口的流量会被转发,但可能不如其他NAT类型那样灵活(例如,不能接受来自任意源IP的连接,除非NAT设备有更精细的控制)。而且,对于随机性强的P2P连接,手动端口映射通常不现实。

对称型NAT需要维护多少状态信息?这会影响性能或容量吗?

相比于全锥型NAT,对称型NAT需要维护更多的状态信息。

  • 全锥型NAT: 只需为每一个内部IP地址和端口维护一个外部IP和端口的映射(Int_IP:Int_Port <-> Ext_IP:Ext_Port)。无论内部设备尝试连接哪个外部目的地,都使用这同一个外部映射。
  • 对称型NAT: 需要为每一个“内部IP:端口 + 外部目的IP:端口”的组合维护一个独立的外部IP和端口映射((Int_IP:Int_Port, Ext_IP_Dest:Ext_Port_Dest) <-> (Nat_IP:Nat_Port))。

这意味着如果一个内部设备使用同一个源端口同时连接100个不同的外部服务器(每个服务器的IP或端口不同),全锥型NAT只需要维护1个映射表项,而对称型NAT需要维护100个不同的映射表项。

因此,对称型NAT通常需要NAT设备具备更多的内存来存储这些映射表项。在用户量巨大且每用户连接大量不同外部服务的网络环境(如CG-NAT)中,对称型NAT的状态表可能会变得非常庞大,对NAT设备的内存和处理能力提出更高的要求。

此外,每个映射都消耗一个外部端口。由于外部端口数量是有限的(理论上每个IP有65535个端口,但实际可用范围可能更小),在大量内部用户同时连接大量不同外部目的地的情况下,对称型NAT可能比其他NAT类型更快地耗尽可用的外部端口资源,导致新的连接请求被拒绝。这也是CG-NAT部署中需要仔细规划和管理的挑战之一。


对称型nat