当前位置: 首页 > news >正文

TCPIP详解 卷1协议 七 防火墙和网络地址转换

7.1——防火墙和网络地址转换

为防止终端系统不被攻击,需要一种方法来控制互联网中网络流量的流向。这项工作由防火墙来完成,它是一种能够限制所转发的流量类型的路由器。

随着部署防火墙来保护企业,另一个问题变得越来越重要:可用的IPv4地址数量正面临枯竭的威胁。必须采取有效的措施来管理 IP 地址的分配和使用。除了IPv6 之外,一种最为重要的解决机制就是网络地址转换(Network Address Translation,NAT)。NAT将私有地址转换为公共地址,使得内部网络的设备无需全球唯一地址即可访问互联网。公共地址仍需唯一,但私有地址可以在不同网络中重复使用。这是对应IPv4地址枯竭的核心技术之一。NAT与防火墙相结合生成的复合设备,已经演变成用于连接终端用户的最为常见的路由器类型,包括连接家庭网络和小型企业网络至互联网的。

7.2——防火墙

最为常用的两种防火墙是代理防火墙(proxy firewall)和包过滤防火墙(packet-filter firewall)。它们之间的主要区别是所操作的协议栈的层次及由此决定的IP地址和端口号的使用。包过滤防火墙是一个互联网路由器,能够丢弃符合(或者不符合)特定条件的数据包。
从 Internet 客户端的角度来看,代理防火墙则是一个多宿主的服务器主机。也就是说,它是TCP 和 UDP 传输关联的终点,通常不会在 IP 协议层中路由 IP 数据报。

  • 包过滤防火墙:

    包过滤防火墙作为互联网路由器,能够过滤(filter)一些网络流量。它们一般都可以配置为丢弃或转发数据包头中符合(或不符合)特定标准的数据包,这些标准称为过滤器(filter)。简单的过滤器包括网络层或传输层报头中各个部分的范围比较。最流行的过滤器包括 IP 地址或者选项、ICMP 报文的类型,以及根据数据包中端口号确定的各种 UDP或 TCP服务。最简单的包过滤防火墙是无状态的,而更复杂的防火墙是有状态的。无状态的包过滤防火墙单独处理每一个数据报,而有状态的防火墙能够通过关联已经或者即将到达的数据包来推断流或者数据报的信息,即那些属于同一个传输关联的数据包或构成同一个 IP 数据报的 IP 分片。IP 分片使得防火墙的工作变得更为复杂,无状态包过滤防火墙极易被其混淆。

    下图为一个典型的包过滤防火墙。在这里防火墙是一个有着三个网络接口的互联网路由器:一个“内”接口,一个“外”接口和第三个“非军事区”(DMZ)接口。DMZ 子网能够访问外联网或DMZ,其中部署的服务器可供互联网用户访问。网络管理员会安装过滤器或访问控制列表(Access Control Lists,ACL)(ACL列出了什么类型的数据包需要被丢弃或转发的基本政策)到防火墙中。通常情况下,这些过滤器将会全力拦截来自外网的恶意流量,但不会限制从内网到外网的流量。

    image-20250418195628674

  • 代理防火墙:

    代理防火墙并不是真正意义上的互联网路由器。相反,它们本质上是运行一个或多个应用层网关(Application-Layer Gateways,ALG)的主机,该主机拥有多个网络接口,能够在应用层中继两个连接/关联之间的特定类型的流量。它们通常不像路由器那样做IP转发。

    下图说明了一个代理防火墙。对于这种类型的防火墙,防火墙内的客户端通常会做特殊配置以便关联到代理防火墙,而不是连接到实际提供所需服务的真正的终端主机。通常这些防火墙作为多宿主主机,即便具备 IP 转发的能力也是被禁用的。与包过滤防火墙一样,一种常见的配置是为“外”接口分配一个全局路由的 IP 地址,为“内”接口分配一个私有的 IP 地址。因此,代理防火墙支持使用私有地址范围。

    image-20250418200137104

    虽然这种类型的防火墙是非常安全的,但它是以脆性和缺乏灵活性为代价的。特别是,因为这种类型的防火墙必须为每个传输层服务设置一个代理,任何要使用的新服务必须安装一个相应的代理,并通过该代理来操作发起连接。此外,必须配置每个客户端以便能够找到代理。至于部署方面,这些防火墙在所有被访问的网络服务均能提前确定的环境中能工作得很好,但是添加额外的服务可能需要网络运营者的重大干预。

    代理防火墙的两种最常见的形式是:

    • HTTP代理防火墙 :

      第一种类型也称为 Web 代理,只能用于HTTP 和 HTTPS 协议。这些代理对于内网用户来说就像是Web 服务器,对于被访问的外部网站来说就像是Web客户端。这种代理往往也提供Web缓存功能。这些缓存保存网页的副本,以便后续访问可以直接从缓存中获取,而不再需要访问原始的 Web 服务器。这样做的好处是可以减少显示网页的延迟,提高用户访问网站的体验。一些Web代理也经常被用作内容过滤器,能够基于“黑名单”来阻止用户访问某些Web网站。相反,在互联网上还可以找到一些所谓的隧道代理服务器。这些服务器本质上执行相反的功能,以避免用户被内容过滤器封阻。

    • SOCKS 防火墙:

      SOCKS 协议比 HTTP 代理访问使用更为广泛,可用于 Web 之外的其他服务。目前正在使用的 SOCKS 有两个版本:版本 4 和版本 5。第 4 版为代理传输提供了基本的支持,而第5 版增加了强大的认证、UDP 传输和 IPv6 寻址。为使用 SOCKS 代理,应用程序在开发时必须添加 SOCKS 代理支持功能(即它必须是能够被代理的),同时通过配置应用程序能够获知代理的位置及其版本。一旦配置完成,客户端使用SOCKS协议请求代理进行网络连接,也可以选择性地进行DNS查找。

7.3——网络地址转换(NAT)

NAT 本质上是一种允许在互联网的不同地方重复使用相同的IP 地址集的机制。建立NAT 的主要动机是正在急剧减少的有限 IP 地址空间。使用NAT 最常见的情况是,唯一与Internet 连接的站点仅被分配了很少的几个IP 地址(甚至只有一个IP 地址),但是内部却有多台主机需要同时上网。当所有进出的流量均通过一个单独的 NAT设备时,该设备将内部系统的地址空间和全球互联网地址空间分割开,因此所有的内部系统可以使用本地分配的私有IP地址访问互联网。

NAT 的引入用以解决IP 地址枯竭的问题。NAT是受欢迎的,因为它减少了对具备全局路由的互联网地址的需求,同时提供了一些防火墙功能,并且仅需要很少的配置。但具有讽刺意味的是,快速发展和广泛使用的 NAT却严重影响了 IPv6 的推进进程。在 IPv6 的诸多益处中,其中一项就是不再需要 NAT [RFC4864]。

NAT 尽管很流行,但是存在几个缺点:

  • 最明显的是,需要做特殊配置才能使处于NAT内部的主机能够提供可供互联网访问的服务,因为互联网上的用户无法直接访问具备私有地址的主机。
  • 此外,为了使 NAT 正常工作,每一个隶属于同一个连接或关联的双向数据包都必须通过相同的NAT。这是因为NAT必须重写每个数据包的寻址信息,以便私有地址空间的系统和Internet主机之间能够正常通信。为完成工作,NAT 需要跟踪每个关联(或每个连接)的连接状态,其操作贯穿多个协议层,并不像传统的路由器。修改IP 层地址也需要同时修改传输层的校验码。
  • NAT 会对一些应用协议造成困扰,尤其是那些在应用层的有效载荷内记录 IP 地址信息的协议。文件传输协议(File Transfer Protocol,FTP)[RFC0959]和SIP[RFC5411]就是这种类型的协议代表。它们需要一种特殊的应用层网关功能来重写应用程序的内容,以便能够毫无修改地采用 NAT 或者其他的 NAT 传输方法工作,这些传输方法允许应用程序自行确定如何在NAT上工作。

NAT 的工作原理就是重写通过路由器的数据包的识别信息。这种情况常发生在数据传输的两个方向上。在这种最基本的形式中,NAT 需要重写往一个方向传输的数据包的源 IP 地址,重写往另一个方向传输的数据包的目的 IP 地址。这允许传出的数据包的源 IP地址变为NAT 路由器中面向 Internet 的网络接口地址,而不是原始主机的接口地址。因此,在互联网上的主机看来,数据包是来自于具备全局路由 IP 的 NAT 路由器,而不是位于NAT 内部的私有地址的主机。

7.3.1 传统的NAT:基本NAT和NAPT

NAT类型的分类:所谓传统NAT(traditional NAT)包括:

  • 基本NAT(basic NAT):只执行IP地址的重写。本质上就是将私有地址改写为一个公共地址。它无助于减少需要使用的IP地址数量,全局可路由的地址数量必须大于或等于希望同时访问Internet的d内部主机数量。
  • 网络地址端口转换(Network Address Port Translation,NAPT)[RFC3022]:NAPT使用传输层标识符(即TCP和UDP端口,ICMP查询标识符)来确定一个特定的数据包到底和NAT内部的哪台私有主机关联(如下图7-4所示)。这使得大量的内部主机(即好几千台)能够同时访问互联网,而使用的公有地址数量却很少,通常只需要一个。

image-20250424203221793

在NAT“后面”或者“内部”使用的私有地址范围不受除了本地网络管理人员之外的任何人的限制。因此,有可能在私有范围内采用全局地址空间。原则上,这是可以接受的。然而,当这样的全局地址也被互联网上的另一个实体所使用时,在私有范围内的本地系统极有可能无法达到使用相同地址的公共系统,这是因为采用相同地址的本地系统会屏蔽掉使用相同地址的远端系统。为了避免这种不良情况的发生,保留了三个IPv4地址范围作为私有地址范围使用[RFC1918中]:

  • 10.0.0.0/8
  • 172.16.0.0/12
  • 192.168.0.0/16

NAT提供了一定程度上的类似于防火墙的安全性。默认情况下,从互联网上无法访问NAT私有端的所有系统。在大多数NAT部署中,内部系统使用私有地址。因此,必须借助NAT的参与(根据其使用策略和行为),才能保证私人地址领域和公共领域中的主机之间的正常通信。虽然在实践中可以使用各种策略,一个共同的策略是:几乎允许所有的传出及其返回流量(与传出流量相对应的)通过 NAT,但几乎阻断所有传入的新连接请求。此行为抑制了试图确定可利用的活动主机的 IP 地址“探测”攻击。此外,NAT(尤其是NAPT)对外“隐藏”内部地址的数量和配置。

7.3.1.1 NAT和TCP

互联网中最为主要的传输层协议是 TCP,使用一个IP 地址和端口号来标识一个连接的每一端。每个连接由两端组成,每个TCP连接由两个IP 地址和两个端口号唯一标识。当发起一个TCP连接时,“主动发起者”或客户端通常发送同步包(SYN)到“被动发起者”或服务器端。服务器端通过回复一个自己的SYN 数据包进行响应,同时还包括一个对客户端的 SYN数据包进行确认的 ACK 数据包。客户端回复一个 ACK 数据包给服务器端。这样,通过“三次握手”创建了连接。类似的结束(FIN)数据包被用于优雅地关闭连接。当然,连接也能通过重置(RST)数据包来强行关闭。与 TCP 相关的传统 NAT 行为要求定义在[RFC5382]中,主要涉及了 TCP的三次握手。

以下图为例

image-20250424204725785

考察一个由地址为 10.0.0.126 的无线客户端发起的 TCP 连接,其目标是Web服务器主机www.isoc.org(IPv4地址212.110.167.157)。使用以下符号来表示 IPv4 地址和端口号:(源 IP:源端口;目标 IP:目标端口),在私人段内发起连接的数据包可表示为(10.0.0.126:9200;212.110.167.157:80)。NAT/防火墙设备作为客户端的默认路由器,将会收到第一个数据包。NAT注意到传入的数据包是一个新的连接(因为TCP报头中的SYN标志位是打开的)。如果策略允许(通常会,因为这是一个向外发起的连接),数据包的源 IP 地址会被修改为 NAT 路由器的外部接口的 IP 地址。因此,当NAT 转发这个数据包的时候,其寻址是(63.204.134.177:9200;212.110.167.157:80)。除了转发数据包之外,NAT 还创建一个内部状态记住当前正在处理一个新连接(称为 NAT会话(NAT session))。这种状态至少包括一个由客户端的源端口号和IP 地址组成的条目(称为NAT 映射(NAT mapping))。当 Internet服务器回复时会用到这些信息。服务器会采用客户端初始选择使用的端口号来回复端点(63.204.134.177:9200),即 NAT 的外部地址。这种行为被称为端口保留(port preservation)。通过比对收到的数据包的目的端口号与NAT映射条目,NAT能够确定发起请求的客户端的内部IP地址。在我们的例子中,这个地址是10.0.0.126,所以NAT将回复的数据包从(212.110.167.157:80;63.204.134.177:9200)改为
(212.110.167.157:80;10.0.0.126:9200),并对其进行转发。然后客户端收到对其请求的响应,这样在多数情况下表示已经连接到服务器。

会话状态将会在交换 FIN 数据包之后被删除,但并不是所有的 TCP 连接都是正常关闭的。有时只是简单地将主机关闭,这样会导致应该被清除的NAT映射仍保留在内存中。因此当流量很少时(或者用一个 RST 段表示存在其他问题),NAT 必须清除这些被认为已经“死亡”的映射条目。

大多数的 NAT 包括一个 TCP 连接建立的简化版本,并可以区分连接成功还是失败了。特别地,NAT 在检测到一个传出的 SYN数据包后会激活连接计时器(connection timer),如果回复的 ACK 数据包在计时器到期之前还未到达,则该会话状态将被清除。如果 ACK 数据包到达了,计时器将被清除,并创建一个超时较长的会话计时器(session timer)(如用小时来代替分钟)。当发生这种情况时,NAT 可能会向内部的端点发送一个额外的数据包,用于确认该会话是否已经终止了(称为探测(probing))。如果收到 ACK,NAT 认识到该连接仍然是活跃的,则重置会话计时器,并不会删除会话。如果没有收到响应(在关闭计时器(closetimer)超时之后)或者收到一个 RST 数据包,表明该连接已经终止,状态将被清除。

[RFC5382]是 BEHAVE 工作组的一个成果,指出一个 TCP连接可以被配置为发送“存活”(keepalive)数据包,在该配置被启用时其默认的发送速率是每两个小时一个数据包。否则,一个TCP连接可以一直保持下去。然而,当一个连接被建立或清除时,其最大的空闲时间是 4 分钟。因此,[RFC5382]要求(REQ-5)NAT 在判定所创建的连接是否已经断开前至少需要等待 2 小时 4 分钟,而在判定部分打开或关闭的连接是否已经断开前至少需要等待 4 分钟。

一个TCP NAT面临的棘手问题是如何处理位于多个NAT内部的主机上运行的对等(peer-to-peer)应用[RFC5128]。一部分应用程序采用了“同时发起连接”(simultaneous open)的技术,让连接的每一端均作为客户端同时发送 SYN 数据包。TCP 能够响应 SYN + ACK 的数据包,完成连接的速度比三次握手还要快,但目前有许多NAT并不能正确地处理这种情况。为此,[RFC5382]要求(REQ-2)NAT处理所有有效的TCP包交换,尤其是这种连接同时打开的情况。某些对等应用程序(如网络游戏)便采用了这种行为。此外,[RFC5382]还规定 NAT 将会静默丢弃那些一无所知的传入的 SYN 数据包。这可能会发生在同时发起一个连接时,即当外部主机的SYN数据包先于内部主机的SYN数据包到达NAT主机时。虽然这种情况发生的可能性不大,但在出现时钟错误时确实会发生。如果传入的外部 SYN 数据包被丢弃,内部的 SYN 数据包还有时间来建立这个由外部的 SYN 数据包代表的 NAT 映射。如果在6s之内没有接收到内部的SYN 数据包,NAT可能会向外部主机发送一个错误信号。

7.3.1.2 NAT和UDP

针对单播 UDP 的 NAT 行为要求定义在[RFC4787]中。NAT 在处理一系列 UDP 数据报时所出现的问题,与处理 TCP 时出现的问题大多数一样。但是 UDP有些不同,不像 TCP,它没有连接建立和清除的过程。更具体地说,它没有标识位,如用 SYN、FIN 和 RST这些位来表示一个会话的创建或销毁。此外,一个关联中的参与者也未必完全清楚。UDP不像TCP那样采用一个4 元组来标识一个连接,相反,它是基于两个端点的地址/端口号的组合。为了处理这些问题,如果一个绑定在“近期”没有被使用,UDP NAT 会采用一个映射计时器(mapping timer)来清除NAT的状态。[RFC4787]要求计时器至少为2分钟,推荐5分钟。一个相关的问题是计时器何时刷新。当数据包从内部传输到外部时 NAT就刷新(NAT的对外刷新行为)或反之亦然(NAT的对内刷新行为)。[RFC4787]要求 NAT保证对外的刷新行为。对内的刷新行为是可选的。UDP和IP数据包可以被分片。分片允许一个IP 数据报跨越多个块(碎片),其中每个都是作为一个独立的数据报。但是,由于 UDP 是在 IP 层之上,为此除了第一个分片之外,其他的分片并没有包含端口号信息,而端口号信息是保证 NAPT 正确操作所必需的信息。这同样也适用于 TCP 和 ICMP。因此,在一般情况下,分片并不能被 NAT 或 NAPT 正确处理。

7.3.1.3 NAT 和其他的传输协议(DCCP,SCTP)

  • 数据报拥塞控制协定(Datagram Congestion Control Protocol,DCCP)[RFC4340]:提供拥塞控制的数据报服务。[RFC5597]给出了针对DCCP的NAT行为要求,[RFC5596]修改了DCCP用于支持类似于TCP的同时发起连接的过程。
  • 流控制传输协议(Stream Control Transmission Protocol,SCTP)[RFC4960]:提供了可靠的报文处理服务,可容纳拥有多个地址的主机。[HBA09]及[IDSNAT]给出了NAT与SCTP中应注意的事项。

7.3.1.4 NAT和ICMP

ICMP 是 Internet 控制报文协议,它提供了关于 IP 数据包的状态信息,也能够用于测量和收集网络状态信息。[RFC5508]中定义了ICMP的NAT行为要求。在ICMP中使用NAT时需要考虑两个问题。

ICMP有两类报文:

  • 信息类的:信息类的报文也存在和出错类报文同样的问题,但在这种情况下,大多数的报文类型是查询/响应或客户机/服务器性质的,还包括一个类似于TCP或UDP 端口号的查询ID(Query ID)字段。因此,处理这些类型信息的NAT 能够识别向外传输的信息请求,并设置计时器用于等待响应。
  • 出错类的:出错类报文通常包含一个引起错误条件的IP数据包(全部或部分)的副本。它们从错误被检测到的端点,通常是在网络中,发送到数据报的原始发送方。按说,这并没有任何困难,但是当一个ICMP错误报文通过NAT时,需要改写“错误数据报”的IP 地址,以便它们能被终端客户机识别(称为ICMP 的修复行动(ICMP fix-up))。

7.3.1.5 NAT 和隧道数据包

在某些情况下,隧道数据包也需要通过NAT发送。当发生这种情况时,NAT 不仅要修改 IP 包头,还需要修改封装在其中的其他数据包的包头和有效载荷。一个这样的例子是使用点对点隧道协议(PPTP)的通用路由封装(GRE)包头。当GRE包头通过NAT时,它的Call-ID 域会与NAT(或其他主机的隧道连接)冲突。如果NAT 没能妥善处理这一映射,便不能通信。正如我们可以想象的,更多的封装层次只会使NAT的工作进一步复杂化。

7.3.1.6 NAT和组播

NAT 也可以被配置成支持组播流量,虽然这比较少见。[RFC5135]给出了NAT在处理组播流量时的要求。实际上,为了支持组播流量,需要用IGMP 代理来增强 NAT(见[RFC4605])。此外,从位于 NAT 内部的主机发送到外部的数据包的目的 IP 地址和端口不会被修改。从内部传输到外部的流量,其源地址和端口号可根据单播 UDP 行为修改。

7.3.1.7 NAT和IPv6

由于在IPv6中没有必要节省地址空间,而其他的NAT特性(例如,防火墙功能,拓扑隐藏和隐私)也能通过本地网络保护(Local Network Protection,LNP)来提供,因此人们坚决抵制在 IPv6中使用NAT[RFC4864]。LNP 代表在 IPv6 中达到或者超过 NAT 性能的技术集合。

除了具备包过滤属性,NAT还支持多个地址范围共存,能够避免当站点切换ISP时需要改变其 IP 地址的问题。例如,[RFC4193]定义了唯一的本地IPv6单播地址(Unique Local IPv6 Unicast Addresses,ULA),能够为被称为NPTv6[RFC6296]的尚处于实验阶段的IPv6到 IPv6 前缀转换所采用。它采用了一种算法而不是一个表格,基于前缀将一个 IPv6地址转换为其他的(不同的)IPv6地址(例如,在不同的地址范围中),因此不需要像传统的NAT那样需要维护单个连接的状态。此外,该算法需要修改地址以保证通用传输协议(TCP,UDP)的“校验和”计算值保持不变。由于不需要修改网络层之上的数据包中的数据,也不需要访问传输层的端口号,因此该方法显著地降低了 NAT 的复杂性。然而,需要访问NAT外部地址的应用程序必须使用NAT穿越方法或依赖于ALG。此外,NPTv6本身并不提供防火墙的包过滤功能,因此必须考虑额外的部署。

7.3.2 地址端口转换行为

NAT 的操作方式差别很大。大部分的细节涉及具体的地址和端口映射。IETF工作组BEHAVE 的主要目标之一是要阐明共同行为,规定哪些是最合适的。为了更好地理解所涉及的问题,我们从一个通用的 NAT 映射例子开始(见下图 )。

image-20250427093249251

在上图中,我们使用符号 X:x 表示在私有地址范围(内部主机)中的主机使用 IP 地址X、端口号 x(对于 ICMP,采用查询 ID 代替端口号)。为了连接到远程地址/端口组合Y:y,NAT 需要使用一个外部地址(通常是公共的和全局路由的)X1’和端口号 x1’来创建一个映射。假设内部主机先连接到 Y1:y1,再连接到 Y2:y2,NAT 则需先创建映射 X1’:x1’,再创建映射 X2’:x2’。在大多数情况下,X1’等于 X2’,因为大多数网站只使用一个全局路由的 IP 地址。如果 x1’等于 x2’,映射则被认为是重复使用的。如果 x1’和 x2’均与 x 相等,NAT实现前面提到过的端口保留。在某些情况下,端口保留是不可能的,所以 NAT 必须处理图 7-4 所示的端口冲突。

下表和上图概括了由[RFC4787]定义的各种NAT端口和地址行为。下表使用类似的术语定义了过滤行为。在所有常见的传输层协议中,包括 TCP 和UDP,所需的NAT地址和端口处理行为是独立于端点的(在ICMP中推荐使用类似行为)。这项规定的目的是帮助应用程序确定一个确保流量能够正常工作的外部地址。

image-20250427094126978

如前所述,NAT 可能有几个可用的外部地址。这个地址集通常被称为 NAT 池(NAT pool)或者NAT地址池(NAT address pool)。多数中型到大型的NAT使用地址池。请注意,NAT 地址池和 DHCP 地址池不同,当然一台设备可能需要同时处理 NAT和 DHCP 地址池。在这种环境中的一个问题是,当位于 NAT 后的一个主机同时发起多个连接,此时是不是为每个连接分配相同的外部IP地址(称为地址配对(pairing))?如果没有限制哪个外部地址用于关联,一个 NAT 的 IP 地址池的行为(IP address pooling behavior)被认为是任意(arbitrary)的。如果它实现地址配对,它就被称为被配对(paired)。配对是所有传输层的推荐NAT行为。如果未使用配对,内部主机的通信对等端可能会错误地断定,它正与不同的主机进行通信。对于只有一个外部地址的 NAT,这显然不成问题。

一种脆弱的NAT类型不仅需要重载地址,也需要重载端口(称为端口重载(port overloading))。在这种情况下,多个内部主机的流量可能被修改为相同的外部IP地址和端口号(port number)。这是一种危险的情况,因为如果多台内部主机同时访问同一台外部主机上的服务,那么当流量从外部主机返回时便无法找到适当的目的地址。对于TCP而言,这是由多个外部连接共享连接标识符的4元组(源和目标地址及端口号)所导致的结果。现在这种行为是不允许的。

一些 NAT 实现了一个特殊的功能,称为端口奇偶性(port parity)。这种 NAT 尝试保持端口号(奇数或偶数)的奇偶性。因此,如果x1 是偶数,那么x1’也是偶数,反之亦然。虽然不如端口保留那么强大,但这样的行为有时对于使用特殊端口的特定应用协议还是非常有用的(例如,简称为RTP的实时协议(Real-Time Protocol),历来使用多个端口,当然也有方法来避免出现这种问题[RFC5761])。NAT 推荐保持端口的奇偶性,但并不是必需的。随着更复杂的 NAT 传输方法的普及,这种特性也变得越来越不重要。

7.3.3 过滤行为

当 NAT 为一个 TCP 连接、UDP 关联或各种形式的 ICMP 流量创建一个绑定,不仅要创建地址和端口映射,作为一个防火墙,还必须确定返回流量的过滤行为,这是非常常见的情况。NAT 所执行的过滤类型,尽管在逻辑上与地址和端口处理行为不同,但常常是相关的。尤其是使用相同的术语:独立于端点,依赖于地址,依赖于地址和端口。

一个NAT 的过滤行为通常与它是否已经建立了一个地址映射相关。显然,若NAT 中缺乏任何形式的地址映射,那么它无法转发从外到内的任何流量,这是由于它不知道需要使用的内部目标。对于外出流量最为常见的情况,是当创建一个绑定时,相关返回流量的过滤功能将被禁止。对独立于端点的 NAT行为,只要为内部主机创建了映射,无论来源如何,都将允许任何传入的流量。对依赖于地址的过滤行为,仅当X1:x1之前访问过Y1时,才允许Y1:y1 传输流量到 X1:x1。对于那些依赖于地址和端口的 NAT 过滤行为,仅当 X1:x1 之前访问过 Y1:y1 时,才允许 Y1:y1 传输流量到 X1:x1。最后两个之间的区别是,后面那个只是将端口号 y1 考虑进去了。

7.3.4 位于 NAT 之后的服务器

采用NAT 的主要问题之一,就是从外网无法直接访问位于NAT之后的主机提供的服务。以下图为例。

image-20250424204725785

如果地址为10.0.0.3 的主机向互联网提供服务,如果没有NAT 的参与便无法被访问到,至少存在如下两个原因:

  • NAT作为互联网路由器,它必须同意转发目的地为10.0.0.3的传入流量。

  • 更为重要的是,从互联网无法路由到IP地址10.0.0.3,互联网中的主机也无法识别该地址。相反,NAT的外部地址被用于查找服务器,NAT必须妥善重写和转发到达服务器的适当流量,以便它可以操作。这个过程通常称为端口转发(port forwarding)或端口映射(port mapping)。

    通过端口转发,进入NAT的流量被转发到一个位于NAT后面的特定配置的目的地址。通过采用 NAT 端口转发,就可以让服务器给互联网提供服务,即使它们被分配了私有的、不可路由的地址。端口转发,通常需要采用转发到的服务器的地址和端口号来静态配置NAT。

    端口转发就像一个始终存在的静态 NAT 映射。如果服务器的 IP 地址被更改,NAT 必须更新寻址信息。端口转发也有局限性,只有一个端口号集合用于绑定每个(IP地址,传输协议)组合。因此,如果 NAT只有一个外部 IP 地址,它最多将相同传输协议的一个端口转发到一个内部机器(例如,它不能支持通过TCP 80端口访问内部的两台独立的Web服务器)。

7.3.5 发夹和NAT 环回

当客户希望访问位于同一个NAT私有地址空间内的服务器时,会导致一个有趣的问题。能够支持这种场景的NAT需要实现发夹(hairpinning)或者NAT环回(NAT loopback)。参考下图。

image-20250427100725884

假设主机 X1 试图建立一个到主机 X2的连接。如果 X1 知道私有地址信息,X2:x2,这没有任何问题,因为可以直接进行连接。然而,在某些情况下 X1 只知道公用地址信息,X2’:x2’。在这种情况下,X1借助NAT采用目的地址X2’:x2’尝试连接 X2。当 NAT 意识到在 X2’:x2’和X2:x2之间存在映射,并将数据包转发到位于NAT 私有地址空间内的 X2:x2 时,会触发发夹过程。此时会出现一个问题,目的是 X2:x2 的数据包头部中的源地址应该是 X1:x1 还是 X1’:x1’?

如果 NAT 给 X2 的发夹数据包的源地址信息是 X1’:x1’,那么这种 NAT 被称为有“外部源 IP地址和端口”的发夹行为。这种行为是 TCP NAT所必需的[RFC5382]。之所以需要这种行为,是为了均采用全局路由地址的应用能够识别对方。在我们的例子中,X2可能期望一个来自于X1’(例如,因为第三方系统的协调)的连接。

7.3.6 NAT 编辑器

总之,大多数IP流量均使用UDP和TCP传输协议在互联网上进行传输。这些传输协议,自己就可以很好地被NAT支持,而无须增加额外的复杂性,这是因为它们的格式是很好理解的。当应用层协议与它们一起携带传输层或更低层的信息,如 IP 地址,NAT 的问题就会变得复杂得多。最常见的例子是FTP[RFC0959]。在正常操作中,它交换传输及网络层的端点信息(IP 地址和端口号),所以当要传输大量数据时可以增加额外的连接。这需要NAT 不仅改写数据报的 IP 和 TCP 部分中的 IP 地址和端口号,而且也需要修改有些应用的有效载荷本身。具有这种能力的NAT有时也被称为NAT编辑器(NAT editor)。如果NAT改变了包的应用载荷大小,接着需要更多的工作要做。例如,TCP为数据传输中的每个字节分配了一个序列号,所以如果一个数据包的大小改变了,序列号也需要相应地修改。PPTP[RFC2637]在进行透明操作时便需要NAT编辑器。

7.4——NAT穿越

鉴于将ALG 和NAT编辑器放置于NAT设备中的复杂性,一种可替代的方法是应用程序自己尝试执行NAT穿越(NAT traversal)。此时应用程序需要确定其流量通过NAT时使用的外部 IP地址和端口号,并对其协议操作做相应的修改。如果一个应用程序分布在整个网络中(例如,有多个客户端和服务器,其中一些并不在 NAT 后),服务器可为位于NAT 后的客户端之间传递(拷贝)数据,或者使这样的客户端发现对方的 NAT 绑定,并促成它们之间的直接通信。使用一台服务器在客户端之间进行数据拷贝是不得已的选择,因为这其中会涉及负载和潜在的滥用。因此,大多数时候是尝试提供一些方法,以便允许客户机之间直接通信。

直接通信的方法在对等文件共享、游戏和通信应用中已经非常广泛。然而,这种技术往往局限于某一特定的应用程序,这意味着每一个需要 NAT 穿越的新分布式应用程序,均倾向于实现自己的方法。这可能会导致冗余和互操作性问题,最终增加了用户的挫败感和成本。为了应付这种情况,已经建立了一个处理 NAT 穿越的标准方法,它取决于几个我们在下面讨论的不同从属协议。现在,我们先从其中一个为分布式应用所采用、健壮但尚未成为标准的方法开始。紧接着,我们来标准化 NAT 穿越的框架。

7.4.1 针孔和打孔

如前所述,一个 NAT 通常包括流量重写和过滤功能。当一个 NAT 映射创建时,针对特定应用程序的流量通常允许在NAT 的两个方向传输。这种映射是临时的,通常只适用于在执行时间内的单一应用程序。这类映射被称为针孔(pinhole),因为它们被设计为只允许通过一部分的临时信息流量(例如,一对 IP 地址和端口号组合)。随着程序之间的通信,针孔通常动态地创建和删除。

通过采用针孔试图使位于NAT之后的两个或两个以上的系统直接通信的方法称为打孔(hole punching)。[RFC5128]的3.3 节描述了针对UDP的打孔,3.4 节描述针对TCP 的打孔。为了打一个孔,一个客户机需通过一个向外的连接来访问一台已知的服务器,这样便在本地的 NAT中创建了一个映射。当另一个客户机访问同一台服务器时,由于服务器和每个客户机均有连接,因此知道它们的外部寻址信息。它然后在客户机之间交换它们的外部寻址信息。一旦知道了这个信息,一个客户机便可以尝试直接连接到其他的客户机。流行的对等应用 Skype便使用了这种方法(和其他一些方法)。

参照下图

image-20250427103334267

假设客户机 A 访问服务器 S1,然后客户机 B 也访问服务器 S1。S1 会知道A和B的外部寻址信息:分别为IPv4地址192.0.2.201 和203.0.113.100。将B的信息发送给A(反之亦然),A可以尝试利用 B 的外部地址直接联系 B(反之亦然)。这是否有效取决于已部署的 NAT类型。对于连接(A,S1),其NAT状态在 N1 中,对于连接(B,S1),其NAT状态同时在 N2 和 N3 中。如果所有NAT 独立于端点,这些信息便足够使直接通信成为可能。
由于任何其他类型的 NAT将不会接受除了 S1之外的流量,从而阻止直接通信。换句话说,如果两台主机均位于具备依赖于地址或者同时依赖于地址和端口映射行为的 NAT 之后,那么这种方法是行不通的。

7.4.2 单边的自地址确定

应用程序使用一系列方法来定位其流量在通过NAT时所采用的地址。这便称为确定(学习和维护)地址信息。地址确定的方法分为:

  • 直接:直接方法涉及应用程序和 NAT 本身之间通过一个或者多个特殊协议(目前还不是IETF的标准)来进行直接会话。
  • 间接:间接方法涉及通过与 NAT 交换流量来推测其行为。

IETF花费了很大的精力来发展被特定应用程序所广泛采用的间接方法,其中为最知名的便是 VoIP 应用。目前部分NAT 也能够支持一些直接方法。这些方法也为 NAT 的基本配置做准备,因此我们将在 NAT 的安装和配置中对其进行讨论。

在没有NAT协助的情况下一个应用程序尝试确定地址,所执行的地址确定被称为是单边类型的。这样做的应用程序被称为是执行单边的自地址确定(UNilateral Self-Address Fixing,UNSAF)[RFC3424]。顾名思义,这种方法从长远来看被认为是不可取的,但暂时却是必要的。UNSAF会涉及一套启发式,它们并不能保证在所有情况下都能工作,特别是因为NAT 的行为受供应商和特定环境的影响变化很大。之前提到的 BEHAVE文档,其目标就是让 NAT 的行为更为一致。如果被广泛采用,UNSAF 方法工作起来将更为可靠。

在大多数感兴趣的情况下,UNSAF采用类似打孔的客户机/服务器操作方式,但增加了普适性。上图说明了一些在这种情况下可能出现的危害。其中一个问题就是每一台 NAT缺乏一个单一的“外部”地址范围。在这个例子中,在客户端 B 和服务器 S1之间有两层NAT。这种情况可能会导致复杂性。例如,如果 B 上的应用希望通过一台服务器的 UNSAF获得其“外”地址,根据它是和服务器 S1 通信还是和服务器 S2 通信,将会收到不同的回复。最后,因为 UNSAF使用不同于 NAT 的服务器,始终存在这种可能性,即 NAT 的行为报告会随时间而改变,或者与 UNSAF方法报告不一致。

7.4.3 NAT的会话穿越工具

一个UNSAF 和NAT穿越的主要功能,就是NAT会话穿越工具(SessionTraversal Utilities for NAT,STUN)[RFC5389]。STUN 源自于 UDP 简单隧道穿越 NAT(Simple Tunneling of UDP through NAT),现在被称为“经典的STUN”。经典STUN已经在VoIP/SIP应用中使用了一段时间,但已被修改为一个可以为其他需要 NAT 穿越的协议使用的工具。需要完整 NAT 穿越解决方案的应用,建议先从我们将在 7.4.5 节讨论(例如,ICE 和 SIP 出站)的其他机制开始。这些框架可以以一种或多种特定方式来使用STUN,被称为STUN 用法(usage)。用法可能会扩展STUN的基本操作、报文类型,或在[RFC5389]定义的错误代码集。

STUN 是一个相对简单的客户机/服务器协议,它能够在多种环境中确定在 NAT 中使用的外部 IP地址和端口号。它也可以通过保持激活的信息来维持当前的 NAT 绑定。它需要在NAT 一侧存在一台有效的“其他”合作服务器,以及几台被配置了全局IP 地址的可在互联网上被访问到的公共 STUN 服务器。STUN 服务器的主要工作是回显发送给它的 STUN 请求,以确定客户端的寻址信息。与一般 UNSAF方法相比,该方法并非万无一失。但是STUN的好处是它并不需要修改网络路由器、应用协议或者服务器。它仅需要客户端实现 STUN 请求协议,以及至少一台在适当位置可用的 STUN 服务器。STUN 被设想为一种“临时”的解决方案,直到制定和实施更复杂的直接协议,或由于 IPv6 的广泛采用而使得 NAT 成为过时的)。

STUN 操作使用 UDP、TCP 或具备传输层安全性(Transport Layer Security,TLS)的TCP。STUN 用法规范定义特定用法所支持的传输协议。它为 UDP 和 TCP 使用 3478 端口,为TCP/TLS 使用 3479 端口。STUN基础协议有两种类型的事务:请求/响应事务(request/response transactions)和标志事务(indication transactions)。标志不需要响应,并可以通过客户机或服务器生成。各种 STUN参数,包括方法和属性数量,均由IANA[ISP]维护。属性有自己的类型,并可以改变长度。在一个IP 数据包中,基本的 STUN头通常紧挨着UDP传输头,

STUN报文如下图所示

image-20250427104729369

  • STUN报文总是以2个0比特位开始,并且封装在UDP中,当然TCP也是允许的。
  • 报文类型字段同时给出了方法(例如,绑定)和类型(请求,响应,错误,成功)。
  • 报文长度:段提供了一个最大为 2^16-1 字节的完整的 STUN 报文长度(报文长度字段不包括 20字节的报头长度),由于报文总是用多个4字节来填充的,所以长度字段的低 2 位总是为0
  • 值为0x2112A442的魔术cookie
  • 事务 ID 是一个长为96位的数字,用于匹配请求和响应,或者在标志情况中用于调试。
  • 每个 STUN 报文能够包含 0个或者多个属性,这取决于 STUN 的特定用法

基本的 STUN 头的长度是 20 字节。通过UDP/IP发出的 STUN报文所形成 IP数据包,若预先知道路径MTU 的大小,为避免分片,其大小应小于MTU。如果不知道 MTU,整个数据报的长度(包括 IP 和 UDP 头和任何选项)应小于576个字节(IPv4)或1280字节(IPv6)。STUN没有规定如何处理回复的报文超过相反方向路径 MTU 的情况,所以服务器应当安排使用大小适当的报文。

通过 UDP/IP 传递的 STUN 报文是不可靠的,因此 STUN 应用程序都需要自己来实现可靠性。这是通过重发认为丢失的报文来实现的。重传间隔是通过估计向对方发送和接受一个报文的时间来计算的,称为往返时间(round-trip time,RTT)。在我们讨论TCP 时,RTT的计算及重传计时器的设置是一个需要重点考虑的地方。STUN使用了类似的做法,但在标准的 TCP 上稍做了修改。更多细节请参考[RFC5389]。通过 TCP/IP 或带有 TLS/IP 的TCP 来传输的 STUN 报文的可靠性问题由 TCP 来处理。基于 TCP 的连接可以支持多个待定的STUN事务。

STUN 的属性被编码在一个 TLV 布局中,这也为许多其他互联网协议所采用。TLV 的类型和长度字段均是16比特,值部分是长度可变的(最多到64KB,如果支持的话),紧随其后的是多个4字节的填充(填充的比特可能为任意值)。在同一个STUN报文中,属性类型可能会出现多次,尽管只有第一个对接受者来说才是必需的。属性值低于0x8000的是必须包含(comprehension-required)的属性,而其他的则称为可选包含(comprehension-optional)的属性。假如一个代理收到一个拥有必须包含属性的报文但却并不知道该如何处理,就生成一个错误。到目前为止,多数定义的属性是必须包含的[ISP]。

[RFC5389]定义了一个称之为绑定(binding)的STUN方法,能够在请求/响应或者标志事务中用于地址确定和保持 NAT 绑定。它同时定义了 11 个属性,如下表所示。

image-20250427105739581

参考下图

image-20250427093249251

地址信息为X:x的客户机总是有兴趣确定X1’:x1’,即反向传输地址或者映射地址,位于Y1:y1STUN服务器将反向传输地址包含在一个 STUN报文的 MAPPED-ADDRESS 属性中,并将其回复给客户机。MAPPED-ADDRESS 属性包含一个 8 位的地址族(Address Family)字段,一个 16 位的端口号(Port Number)字段,以及一个 32 位或 128 位的地址(Address)字段,这取决于地址族字段(IPv4 为 0x01,IPv6 为 0x02)指定是 IPv4 还是IPv6。之所以包含这个属性是为了与经典的 STUN 保持向后兼容。

更重要的属性是 XOR-MAPPED-ADDRESS 属性,其中包含与MAPPED-ADDRESS 完全相同的属性值,但需要与魔术 cookie 值(对于 IPv4)或事务 ID 与魔术的cookie串联值(对于IPv6)异或。以这种方式使用异或值的原因是为了检测并绕过通用 ALG,防止它们查看和改写通过的任何 IP 地址。这种 ALG 是很脆弱的,因为它们可能改写像STUN这样的协议所必需的信息。经验表明,在数据包负载中异或 IP 地址足以绕过ALG。

一个 STUN 客户机,包括多数的 VoIP 设备和软件电话应用如 pjsua[PJSUA],初始时均需要配置一个或者多个STUN服务器的IP 地址或者名称。之所以希望使用STUN服务器是因为当该应用程序最终与对方对话时它能看到相同的IP地址,尽管要确定可能有点困难。通常使用布局在互联网中的STUN服务器(例如,stun.ekiga.net,stun.xten.com,numb.viagenie.ca)便足够了。一些服务器能够通过 DNS服务(SRV)记录来发现。

STUN可用于执行地址确定之外的其他一些称为机制(mechanisms)的功能,包括DNS发现、重定向到备用服务器的方法和报文完整性交换。机制是在一个特定的 STUN 用法的上下文中选择的,所以一般被认为是可选的 STUN 功能。一个更重要的机制是提供身份和报文完整性验证。它有两种形式:

  • 短期信任机制(short-term credential mechanism):短期信任持续一个会话;特定时间由 STUN 用法来定义。短期信任通常用于特定的信息交换。短期信任机制使用 USERNAME 和 MESSAGE-INTEGRITY 这两个属性。两者在任何请求中都是必需的。USERNAME属性暗示需要哪种凭证,允许信息的发送方使用合适的共享密码来形成一个报文的完整性校验(基于报文内容计算一个 MAC 值)。使用短期信任时,假定某种形式的凭证信息(例如,用户名和密码)在前期已经被交换过。用于形成 STUN 信息完整性校验的凭证被编码在 MESSAGE-INTEGRITY 属性中。能够形成一个有效的 MESSAGE-INTEGRIT 属性值,意味着发送方当前持有的凭证是正确和最新的。
  • 长期信任机制(long-term credential mechanism):长期信任支持多个会话;它们对应一个登录 ID 或账户。长期信任在分配某些特定资源时才使用(例如和TURN一起),在能够被截获的地方,从来不用明文来发送密码。长期信任机制通过一种称为摘要挑战(digest challenge)的方法来保证凭证是最新的。使用这个机制,客户端在初始化请求时不需要提供任何认证信息。服务器会先拒绝请求,但在响应中会包含一个 REALM 属性。这可以被客户端用来确定需要提供何种凭证才能通过验证,当然客户端可能有各种服务的凭据(例如,多个 VoIP 账户)。和REALM 一起,服务器会提供一个永不重用的 NONCE 值,客户端能够用它来形成后续的请求。这种机制还采用了MESSAGE-INTEGRITY 属性,但其完整性功能是通过包含 NONCE 值来计算的。因此,偷听了之前长期信任交换的窃贼很难回复一个有效的请求(因为 NONCE 值是不同的)。长期信任机制无法用来保护 STUN标志,因为这些事务不是以请求/响应对来操作的。

7.4.4 利用 NAT 中继的穿越

利用NAT中继的穿越(Traversal Using Relays around NAT,TURN)[RFC5766]为两个或多个系统提供了一种通信方式,即使它们均位于并未协作的 NAT 后。作为支持在这种情况下通信的最后手段,它需要一个中继服务器在无法通信的系统之间传递数据。使用STUN和一些 TURN 特定报文的扩展,即使大多数其他方法都失败了它也能照样支持通信,只要每个客户端均能连接到不在NAT 后的公共服务器。如果所有的 NAT均与BEHAVE标准兼容,TURN 就没有必要存在了。直接通信的方法(即不使用 TURN)总是优于采用 TURN 服务器的方法。
根据下图

image-20250427111832129

通常位于 NAT 后的 TURN 客户机会访问位于公共互联网上的 TURN 服务器,并暗示了它希望连接的其他系统(称为对等(peer))。通过使用一种特殊的DNS NAPTR记录([RFC5928]),或通过手动配置,便可以找到用于通信的服务器的地址和相应的协议。客户端从服务器端获得的地址和端口信息,称为中继传输地址(relayedtransport address),就是TURN服务器用于和其他对等客户机通信的地址和端口号。客户端也获得了它自己的服务器反向传输地址。对等客户机也得到了代表它们外部地址的服务器反向传输地址。这些地址是客户端和服务器用来连接客户机及其对等所必需的。交换寻址信息的方法并没有在 TURN 中定义。相反,为了能够更加有效地使用 TURN 服务器,这些信息必须使用其他一些机制来完成交换(如 ICE)。

客户端使用TURN命令来创建和维护服务器上的分配(allocation)。一个分配类似于一个多路NAT绑定,包括(唯一)中继传输地址,每个对等客户机需要使用它到达本机。通过 UDP/IPv4 使用传统的 TURN 报文来发送服务器/对等数据。通过增强也能支持 TCP[RFC6062]和 IPv6(IPv4 和 IPv6之间的中继)[RFC6156]。封装的客户/服务器数据内包括发送信息或者接受相关数据的相应的对等客户机的信息。客户/服务器连接已被指定为使用UDP/IPv4、TCP/IPv4 和采用 TLS 的 TCP/IPv4。建立一个分配要求验证客户端的身份,通常使用 STUN 长期信任机制。

TURN 支持两种客户端和对等之间拷贝数据的方法。

  • 第一种使用STUN 方法来编码数据,称为发送(Send)和数据(Data),定义在[RFC5766]中,这是 STUN 指示器(indicator),因此无须认证。

  • 其他的方法采用特定于TURN的概念,称为隧道(channel)。隧道是客户端和对等之间的通信路径,相对于发送和数据方法负载较轻。通过隧道传递的报文使用一个较小的、4 个字节的报头,与 TURN 使用的较大的 STUN 格式报文是不兼容的。一个分配最多可以拥有 16K 个隧道。发展隧道方法,有助于减小一些数据包比较小的应用的延迟和开销,如 VoIP 等。

在操作中,客户端使用一个TURN定义的STUN分配(Allocate)方法来发出一个获取分配的请求。如果成功,服务器响应一个成功指示器和已经分配的中继传输地址。如果客户未能提供足够的验证信息,服务器可能会拒绝请求。现在,客户端必须发送更新的报文以保持分配活跃。如果客户机10分钟内不发送信息,那么分配就到期,除非客户机在分配请求中包含了一个用于指定不同生命周期值的STUN LIFETIME属性。通过请求一个生命周期为0的分配,就能将其删除。分配到期时,与其相关的所有隧道便也到期了。

分配通常使用“5元组”表示。在客户端,5元组包括:客户端的主机地址和端口号、服务器传输地址和端口号以及用于与服务器通信的传输协议。除了客户端的主机传输地址和端口被替换为服务器的反向地址和端口之外,服务器端使用了相同的五元组。一个分配可能有零个或多个相关联的权限(permission),以限制允许通过TURN服务器的连接模式。每个权限包括一个IP 地址的限制,只有当源地址匹配的数据包到达 TURN 服务器,其数据有效载荷才会被转发到相应的客户端。如果不能在5分钟内刷新,权限将被删除。

TURN通过6种方法、9个属性以及6个错误响应代码增强STUN。这些大致可以分为支持建立和维护分配、认证以及操作隧道。6种方法和它们的方法号如下:

  • 分配(Allocate)(3)
  • 刷新(Refresh)(4)
  • 发送(Send)(6)
  • 数据(Data)(7)
  • 创建权限(CreatePermission)(8)
  • 隧道绑定(ChannelBind)(9)

前两种方法用于建立并保持分配存活。Send和Data使用STUN报文封装从客户端发送到服务器的数据,反之亦然。GreatePermission用于创建或刷新一个权限,ChannelBind通过一个 16 位的隧道号与一个特定的对等客户端相关联。错误报文表明与TURN 功能相关的问题,如认证失败或资源耗尽(例如,隧道数)。下表给出了由TURN 定义的9个STUN属性名称、值以及目的。

image-20250427113840940

TURN请求采用了 STUN报文的形式,其中报文类型是一个分配请求。

正如前面提到的,TURN 存在的缺点是流量必须通过 TURN服务器进行中继,这可能会导致低效的路由(即TURN服务器可能会离客户端和最优的对等客户端距离较远)。此外,其他某些从对等到客户端的流量内容并不会通过 TURN 服务器。这包括 ICMP 值、TTL(跳数限制)字段值和IP DS字段(DS field)值。此外,请求TURN的客户端必须实现STUN长期信任机制,并有由TURN服务器操作员分配的登录凭证或账户。这有助于避免不加控制地使用开放TURN服务器,但也增加了配置的复杂度。

7.4.5 交互建立链接

一种称为交互式连接建立(Interactive Connectivity Establishment,ICE)[RFC5245]的通用功能,用于帮助位于 NAT 后的 UDP 应用程序主机建立连接。ICE 是一套启发式,利用它应用程序能够以一个相对可预见的方式来执行 UNSAF。在它的操作中,ICE 使用了其他协议,如TURN 和STUN。有一种方法可以扩展 ICE 使其支持基于 TCP 的应用[IDTI]。

ICE使用并扩展了“请求/应答”协议,如单播 SIP 连接建立时的会话描述协议(SDP)[RFC3264]。这些协议会提供一项拥有一组服务参数的服务,还包括一组选定的选项。找到ICE客户并纳入使用SDP/SIP建立通信的VoIP应用已经变得越来越普遍。然而在这种情况下,ICE被用于建立媒体流(如使用RTP[RFC3550]或SRTP[RFC3711]通话中的音频或视频部分)的 NAT 穿越,而另一种称为 SIP 出站(SIP outbound)的机制[RFC5626]用于处理SIP 信令,如谁是被叫方。尽管在实际中,ICE 主要用于基于 SIP/SDP的应用,它也可以作为一个通用的 NAT 穿越机制用于其他应用程序。这样的一个例子就是将 ICE 定义为可扩展的报文和现场协议(Extensible Messaging and Presence Protocol,XMPP)[RFC6120]核心的一个扩展,并与 Jingle 一起使用[XEP-0176]。

通常,ICE 用于创建两个 SDP 实体(称为代理(agent))的通信,首先需要确定一组每个代理都能够用来与其他代理进行通信的候选传输地址(candidate transport address)。参照下图

image-20250427111832129

这些地址可能是主机传输地址、服务器反向地址或中继地址。ICE 可同时使用STUN 和 TURN来确定候选的传输地址。接着,ICE 根据优先分配算法对这些地址进行排序。相比于那些需要中继的地址,该算法为能够提供直接连接的地址分配更大的优先级。然后,ICE为对等代理提供优先的地址集合,其中对等代理也会有类似的行为。最终,两个代理商量好一套最好的可用地址,并将选择的结果告知对方。使用一系列编码为STUN 报文的检查
(check)可用于确定哪些候选的传输层地址是可用的。ICE 通过几项优化可以减少同意选定候选地址的延迟,但这超出了本文的讨论范围。

ICE开始试图发现所有可用的候选地址。这些地址可能是本地分配的传输层地址(如果是多宿主代理便有多个主机)、服务器反向地址,或由TURN 确定的中继地址。在为每个地址分配一个优先级后,每个代理使用SDP将优先级列表发送给对等方。对等代理执行相同的操作,这导致每个代理会有两个优先名单。然后每个代理通过连接2个列表形成一个完全相同的优先候选对(candidate pair)集合。采用特定的顺序在候选对中执行一系列的检查可以确定最终采用哪些地址。一般情况下,优先排序更加倾向于具有较少NAT 或者中继的候选对。一个由ICE指派的控制代理(controlling agent)将确定最终选择的候选对。控制代理根据其优先顺序指定(nominate)使用哪个有效的候选对。控制代理可能会尝试所有对,并随后做出选择(称为常规选择(regular nomination)),或者可能使用第一个可行的对(称为积极选择(aggressive nomination))。通过一个用于指定特定对的STUN报文中的标志来表示常规选择,而通过在每个请求中设置选择标志来表示积极选择。

利用被检查的地址信息在两个代理中交换 STUN绑定请求信息,就是发送检查。检查是由计时器触发,或者受来自于对等代理连接的调度(称为触发检查(triggered check))。通过包含地址信息的 STUN 绑定回复表示响应。在某些情况下这可能会揭示一个新的用于代理的服务器反向地址(例如,当STUN或者TURN服务器最初确定候选地址后,代理之间又使用了一个新的不同于以往的NAT)。如果发生这样的情况,代理获得了一个称为对等反向候选(peer-reflexive candidate)的新地址,该地址将被ICE添加到候选地址中。ICE检查是通过使用基于STUN短期信任机制的完整性检查及STUN的FINGERPRINT属性来完成的。当采用TURN时,ICE客户机用TURN权限来限制针对感兴趣的远端候选地址的TURN绑定。

ICE 采用了不同的实现概念。Lite 实现是专为没有采用 NAT 的系统部署所设计的。它们永远不会充当控制代理,除非与另一个Lite实现进行交互。它们也不会执行前面提到的完全(full)实现所做的检查。发出的STUN报文会表明ICE 实现的类型。所有ICE实现必须遵守STUN[RFC5389],但Lite实现将永远只能充当STUN服务器。ICE通过下 表中所述的属性扩展 STUN。

image-20250427120000278

image-20250427120032148

检查是一个包含PRIORITY属性的STUN绑定请求。当发送方是正在控制或者被控制的代理时,STUN请求中会分别包含 ICE-CONTROLLING 和 ICE-CONTROLLED 属性。一个控制代理可能还包括一个 USE-CANDIDATE 属性。如果存在,这种属性指示控制代理在后续使用中想要选择的代理。

7.5——配置包过滤防火墙和NATA

NAT 通常只需很少的配置(除非端口转发正在使用),但是防火墙通常需要进行配置,有时它们需要大量的配置。大多数家庭网络中,同一台设备需要同时提供NAT、IP路由和防火墙等功能,并可能需要一些配置。虽然每个配置在逻辑上是独立的,但是配置文件、命令行界面、网页控件或其他网络管理工具有时会合并。

7.5.1 防火墙规则

包过滤防火墙,必须给予一套说明匹配条件的指令来选择丢弃或者转发流量。现在配置一个路由器,网络管理员通常配置一个或多个 ACL。每个 ACL包含一个规则列表,其中每个规则通常包含模式匹配条件(pattern-matching criteria)及其对应的动作(action)。匹配条件通常允许规则表达网络层或传输层中的包字段值(例如,源和目的地IP地址、端口号、ICMP类型字段等)以及方向(direction)的说明。方向模式采用基于方向的方式来匹配流量,允许不同的规则集分别应用于传入与传出的流量。许多防火墙还允许在处理顺序中的某一点应用防火墙规则。这方面的例子包括能够在IP路由决策过程之前或之后指定一个ACL。在某些情况下(尤其是当使用多个接口时),这种灵活性就变得很重要。

当一个包到达时,在适当的 ACL 中按照顺序匹配其中的匹配条件。对于大多数的防火墙而言,按照第一个匹配的规则采取动作。典型动作包括阻止或加速符合某项规则的流量,还可以调整计数器或写一个日志条目。一些防火墙可能也包括附加功能,如将特定的数据包发往应用程序或其他主机。每个防火墙厂商通常有自己的方法来指定规则,其中思科系统的ACL 格式已成为许多企业级路由器厂商所广泛支持的一种格式。家庭用户的ACL配置通常使用一个简单的 Web 界面。

一个非常流行的用于构建防火墙的系统是包含在现代版本 Linux中的 iptables,它是使用一个称为NetFilter[NFWEB]的网络过滤功能来构建的。这是早先称为ipchains功能的演变,iptables能够提供无状态和有状态包过滤以及NAT和NAPT的支持。我们应研究它是如何工作的,以更好地理解防火墙以及现代 NAT 提供的各种功能。

iptables包含过滤表格(table)和过滤链(chain)的概念。一个表格包括许多预定义的链,也可能包含0个或者多个用户自定义的链。三个预先定义的表格为:filter,nat和mangle。默认的filter表格用来处理基本的包过滤,包括了预先定义的INPUT、FORWARD和OUTPUT三条链。这些动作分别对应于目的地是防火墙路由器本身运行程序的流量、路由时通过防火墙的流量以及从该防火墙主机发出的流量。nat表格包含了PREROUTING、OUTPUT和POSTROUTING三条链。mangle表格有五条链,主要用于任意修改数据包。

每条过滤链是一个规则列表,每条规则包含匹配条件及其对应的动作。这个动作(也称为目标(target))可能是执行一条用户自定义的链或者执行如下预定义的动作:ACCEPT,DROP,QUEUE和RETURN,当一个数据包匹配上述之一的规则时,便立即采取响应的动作。ACCEPT(DROP)是指数据包将被转发(丢弃)。QUEUE是指数据包将被提交给一个用户程序处理,RETURN是指处理将在之前触发的一条链中继续,形成了一种包过滤链子调用。

7.5.2 NAT规则

在多数简单的路由器中,NAT能够配置为和防火墙一起工作。在基本的 Windows系统中,NAT被称为互联网连接共享(Internet Connection Sharing,ICS),在Linux中被称为IP伪装(IP masquerading)。以Windows XP为例,ICS有一些独有的特征。它为运行ICS的主机分配了192.168.0.1的“内部”IPv4地址,同时启动了一个DHCP服务器和DNS服务器。其他的主机地址从192.168.0/24子网段中分配,并将ICS主机作为DNS服务器。因此,在已经有其他的主机或者路由器提供了上述服务或者存在地址冲突的网络中,ICS不应该被启用。通过修改注册配置能够修改默认的地址范围。

在 Windows XP 中为一个互联网连接启动 ICS 可以通过网络设置向导来完成,或者在一个已经运行了的互联网连接中改变“高级”属性。至此,用户可能决定允许别的用户来控制或者关闭共享网络连接。这个功能也被称为互联网网关设备发现和控制(Internet Gateway Device Discovery and Control,IGDDC),它采用了通用的即插即用的框架,允许在一个客户机中控制本地互联网网关。所支持的功能包括连接、断开,同时读取各种状态信息。与ICS一起工作的Windows防火墙功能支持创建服务定义(service definition)。服务定义等同于之前定义的端口转发。为了使之有效,需要选中互联网连接中的“高级”属性标签,再添加一个新的服务(或者编辑一个现有的服务)。然后,用户在外部接口和内部服务器中便能够填入合适的 TCP 和 UDP 端口号。这样也为进来的连接提供了一种配置NAPT的方法。

7.5.3 与NAT和防火墙的直接交互:UPnP、NAT-PMP和PCP

在多数情况下,一个客户系统希望或者需要和防火墙直接交互。例如,一个防火墙需要为不同的服务配置或者再配置,以保证针对特定端口的网络流量不会被丢弃(创建一个“小孔”)。在一个代理防火墙正在被使用的情况下,每个客户机必须被告知代理的身份。否则的话,就无法越过防火墙进行通信。目前已经开发了许多支持客户机和防火墙之间进行通信的协议。其中两个最为流行的是:

  • 通用即插即用(Universal Plug and Play,UPnP):UPnP 这个标准是由一个称为 UPnP 论坛的工业组开发的。UPnP 在 Windows 系统中是原生支持的,也能够被添加到 Mac OS和Linux系统。UPnP也被数字生活网络联盟(DLNA)[DLNA]用于家庭网络中支持消费电子设备发现协议。通过采用UPnP,被控制的设备通过第一个DHCP来配置IP 地址,如果DHCP不可用的话,就采用动态链接-本地地址配置。接着,简单服务发现协议(Simple Service Discovery Protocol,SSDP)[XIDS]向控制点(例如,客户机)宣布设备的存在,同时允许控制点来查询设备的其他信息。SSDP使用了基于UDP的两个 HTTP变种来代替更为标准的 TCP,它们被称为 HTTPU 和 HTTPMU[XIDMU],其中后者使用组播寻址(IPv4地址239.255.255.250,端口1900)。如果使用基于IPv6的SSDP,那么将采用如下的地址:ff01::c(本地节点),ff02::c(本地连接),ff05::c(本地站点),ff08::c(本地组织),ff0e::c(全局)。后续的控制和事件通知(eventing)是由通用事件通知架构(General Event Notification Architecture,GENA)控制,它采用了简单对象访问协议(Simple Object Access Protocol,SOAP),SOAP支持客户/服务器远程过程调用(Remote Procedure Call,RPC)机制,使用编码在可扩展标记语言(eXtensible Markup Language,XML)中的报文(XML通常用于语Web 网页中)。UPnP 被消费电子设备所广泛采用,包含音频和视频回放和存储设备。NAT和防火墙设备是采用互联网网关设备(Internet Gateway Device,IGD)协议控制的[IGD].
    IGD支持一些别的功能,包括学习NAT映射和配置端口转发的能力。UPnPIGD的第二个版本[IGD2]增加了对IPv6的支持。

  • NAT 端口映射协议(NAT Port Mapping Protocol,NAT-PMP):NAT-PMP 目前是 IETF 中一个到期的草稿文件。NAT-PMP 为绝大多数的 Mac OS 系统所支持。NAT-PMP针对与NAT设备进行程序通信。NAT-PMP是苹果公司用于零配置网络的服务器搜索协议 Bonjour规范的一部分。NAT-PMP并没有采用发现过程,这是由于被管理的设备通常就是可通过 DHCP获取的默认网关。NAT-PMP 使用 UDP 端口 5351。NAT-PMP 支持一个用于学习NAT外部地址和配置端口映射的请求/响应协议。它也支持一个基本的事件机制,当NAT外部地址发生改变时能够通知监听者。这是在外部地址发生改变时通过采用一个UDP组播报文发送到地址224.0.0.1(即所有主机的地址)来完成的。NAT-PMP使用UDP端口号5350 用于客户机/服务器的交互,5351 端口用于组播事件通知。根据端口控制协议(Port Control Protocol,PCP)[IDPCP]的建议,NAT-PMP的概念可被扩展用于支持SPNAT。

7.6——IPv4/IPv6共存和过渡中 NAT

随着最后一个顶层单播IPv4地址在2011年早期被分配出去,向IPv6的过渡便开始加速了。曾经认为通过为主机配备双栈功能(例如,实现完整的IPv4和IPv6协议栈)[RFC4213],网络服务就会过渡到只有IPv6的操作。目前认为IPv4和IPv6将会共存更长一段时间,甚至可能是无限期的,这是由于各种经济原因网络基础设施可能会使用IPv4或者IPv6或者两者同时使用。假设这是真的,那就需要支持IPv4和IPv6系统之间的通信,无论它们是否拥有双协议栈。目前用于支持IPv4和IPv6组合的两种主要方法是隧道和转换。隧道方法包括Teredo、双协议栈精简版(DS-Lite)和IPv6快速部署(6rd)。虽然DS-Lite 采用 SPNAT作为其架构的一部分,但在[RFC6144]描述的框架中给出了一种更单一的转换方法,它使用了我们在第2章中见到过的嵌入了IPv4的IPv6地址。我们将在本节更为详尽地讨论 DS-Lite和转换架构的细节。

7.6.1 双协议栈精简版

DS-Lite(Dual Stack Lite,双协议栈精简版)[RFC6333]是一种希望在内部运行 IPv6 的服务提供者更容易过渡到 IPv6(同时支持传统的 IPv4 用户)的方法。从本质上讲,它可以让供应商把重点放在部署一个可操作的IPv6核心网上,还通过使用少数的IPv4 地址为客署户提供了IPv4 和 IPv6 连接。该方法结合了在 IPv6 中的 IPv4(IPv4-in-IPv6)的“软电线”(softwire)隧道与 SPNAT[RFC5571]。下图显示了这种部署的设想。

image-20250427122703023

在上图中,每个客户网络运行 IPv4 和 IPv6 的任意组合。假定仅使用 IPv6 来管理服务提供者的网络。客户对IPv6互联网的访问是通过采用传统的IPv6路由来完成的。对于IPv4 的访问,每个客户使用一个特殊的“前”网关(在图中标记为“B4”)。一个 B4设备提供了基本的 IPv4 服务(如 DHCP 服务,DNS 代理等),但也以多点到点的隧道方式封装了客户的 IPv4 流量,并在“后”设备(图中标记为“AFTR”)处终止。这个 AFTR设备为目标是IPv4互联网的流量执行了解封操作,并为相反方向的流量执行封装操作。AFTR还执行了NAT,并作为一种形式的SPNAT。更具体地说,AFTR可以利用客户隧道终端的标志信息来消除从IPv4互联网返回到 AFTR的流量的二义性。这将允许多个客户使用相同的 IPv4 地址空间。通过利用 DHCPv6 中的一个 AFTR-Name 选项[RFC6334],一个 B4设备能够学习到它所对应的AFTR设备的名称。

回忆一下第 6章中对IPv6快速部署(6rd)的讨论是非常有益的。鉴于DS-Lite 通过一个服务提供者的IPv6网络为客户提供了到IPv4的访问,6rd的目标是通过一个服务提供者的 IPv4网络为客户提供到IPv6 的访问。本质上,它们使用类似的框架组件,但却采取了相反的做法。然而,6rd 中从 IPv6 地址映射到相应的 IPv4 隧道端点(反之亦然)的计算,是通过一个无状态的地址映射算法完成的。框架中也使用了无状态地址转换,用于 IPv4 和 IPv6之间的全协议转换,这是我们接下来需要讨论的。

7.6.2 使用NAT和ALG的IPv4/IPv6转换

采用隧道技术解决IPv4 和IPv6共存问题的最大缺点是,采用一种地址类型的主机上的网络服务无法被采用了另一种地址类型的主机直接访问。由此,一个只有IPv6的主机就只能够与其他支持 IPv6 的系统进行通信。这种状况是不能接受的。IPv4 和 IPv6 转换的框架在[RFC6144]中有描述。这个基本的转换架构同时采用了有状态的和无状态的方法来完成 IPv4 和 IPv6 地址之间的转换、DNS 的转换,以及在任何必要情况下(包括 ICMP 和 FTP)添加的行为或者 ALG 的定义。

7.6.2.1 已转换的IPv4地址和可转换的IPv4地址

在第 2 章,我们已经讨论了内嵌有IPv4的IPv6地址结构。这样的地址是IPv6地址,但是将其作为一个函数的输入,则能够输出一个对应的IPv4地址。这个函数也能轻易地被反转。内嵌IPv4 的IPv6 地址存在两种重要的类型,称为已转换的IPv4 地址和可转换的IPv4地址。每个提到的地址类型是其他类型的一个子集。也就是说,如果我们将每个地址类型看作一个集合,那么会有(可转换的IPv4)C(已转换的IPv4)C(内嵌的IPv4)C(IPv6)。可转换的IPv4地址是能够通过有状态的方式来确定一个IPv4地址的IPv6地址。

IPv4 和 IPv6 地址之间的算法转换涉及使用第 2 章中讨论过的前缀。这个前缀可能是一个知名前缀(WKP)64:ff9b::/96 或者另外一个为服务提供者所有并和转换器一起使用的特定于网络的前缀。WKP只用于表示常规的全局可路由的IPv4 地址,不能表示私有地址[RFC1918]。此外,WKP也不能用于创建可转换的IPv4地址。这样的地址应该在服务提供者网络内部被定义,因此不适合在一个全局范围中使用。

WKP 是很有趣的,因为相对于 Internet 校验和,它是校验和中立(checksum-neutral)的。回想一下Internet校验和的计算方法。假如我们将前缀64:ff9b::/96看作是十六进制值 0064,ff9b,0000,0000,0000,0000,0000,0000 组成的,这些值的和是 ffff,它的补码正好是 0。因此,当一个 IPv4 地址包含 WKP 前缀时,包中作为转换结果(例如,在IPv4 头部中的 TCP 或者 UDP 校验和)的相关 Internet 校验和是不会受影响的。自然地,恰当选择的特定于网络的前缀也能是校验和中立的。

在接下来的两个小节中,我们将使用符号To4(A6,P)来表示从前缀为P的IPv6地址A中得到的IPv4地址。P可以是WKP或者是某个特定于网络的前缀。我们将使用符号To6(A4,P)来表示从前缀为P的 IPv4地址A 中得到的 IPv6 地址。注意,除了一些特殊的情况之外,A6=To6(To4(A6,P),P)和 A4=To4(To6(A4,P),P)。

7.6.2.2 无状态转换

无状态的IP/ICMP 转换(Stateless IP/ICMP Translation,SIT)是指不采用状态表格进行IPv4 和 IPv6 数据包转换的方法[RFC6145]。转换中无须查找表格,只需要使用一个可转换的 IPv4 地址及一个预定义的用于转换 IP 头部的计划。大部分情况下,IPv4 选项是不需要转换的(被忽略),IPv6 扩展头部也不需要转换(分片头部例外)。唯一的例外是未到期的 IPv4源路由选项。如果存在这种选项,数据包将被丢弃,并产生相应的ICMP 差错报文(目的不可达,源路由失败)。下表描述了当转换一个IPv4 报文到IPv6 时,IPv6头部字段是如何赋值的。

image-20250427124014387

在转换的过程中,IPv4 头部被抽离,取而代之的是 IPv6头部。假如到达的IPv4 数据报相对于下一个链路的MTU来说太大了,并且其头部中的DF位也未设置,那么将会产生多个 IPv6 分片数据包,其中每个将包含一个分片头部。当到达的 IPv4 数据报是一个分片时,也会发生这种情况。[RFC6145]建议当到达的IPv4数据报头部的DF位值为0时,不管转换器是否需要执行分片,也不管达到的数据报是否是一个分片,都需要在结果IPv6数据报中包含一个分片头部。这将允许 IPv6 接收者知道 IPv4 的发送者并没有采用 PMTUD。当包含了一个分片头部时,需要根据下表所列的方法来设置字段值。

image-20250427124119897

在相反的方向(IPv6 到 IPv4 转换)上会涉及创建一个 IPv4 数据报,并根据到达的 IPv6头部字段值来设置该头部字段值。显然,范围更广的IPv6 地址空间不可能允许一个只有IPv4 的主机访问 IPv6 互联网上的每一台主机。当一个未分片的IPv6 数据报到达时,下表给出的方法能给传出的IPv4 数据报头部的字段赋值。

image-20250427124215888

image-20250427124231376

假如到达的一个IPv6数据报包含一个分片头部,将采用从上表修改而来的赋值方法来为传出的 IPv4 数据报字段赋值。下表给出了这种情况。

image-20250427124339252

在分片IPv6数据报的情况下,转换器将生成分片的IPv4报文。注意在IPv6中标识(Identification)字段更大,假如来自于同一台主机的多个不同的 IPv6 数据报被分片了,并且它们的标识字段共享了一个低 16 位值,这些分片将可能无法重组。但是,这种情况的危险性低于传统的IPv4的标识字段中出现的环绕情况。况且,更高层次上的完整性检查将大大打消这种顾虑。

7.6.2.3 有状态的转换

在有状态的转换中,NAT64[RFC6146]被用于支持只有IPv6的客户机与其他IPv4服务器进行通信。当许多重要的服务继续只用 IPv4来提供时,这将显得非常重要。针对头部的转换方法与无状态转换方法几乎一样。作为一个NAT,NAT64 符合BEHAVE规格,支持独立于端点的映射,以及独立于端点和依赖于地址的过滤。因此,它是和我们前面讨论过的NAT 穿越技术(如ICE,STUN,TURN)兼容的。缺乏这些附加协议,NAT64仅支持由 IPv6主机发起的与IPv4主机通信的动态转换。

NAT64在跨越多个地址类型时像传统的NAT(NAPT)那样工作,除了从IPv4到IPv6这个方向的转换比相反方向的转换更加简单。一个NAT64 设备被赋予一个IPv6前缀,能用于形成一个有效的IPv6地址,该地址是通过第2章和[RFC6052]描述的机制从IPv4上直接转换过来的。由于IPv4地址空间的不足,在IPv6 到IPv4这个方向的转换利用了一个动态管理的IPv4地址池。这需要NAT64支持NAPT的功能,据此多个不同的IPv6地址可能会映需射到一个相lНIPv4地址上。NAT64 目前定义了由 IPv6 节点初始化的 TCP,UDP和ICMP报文的转换方法(在ICMP查询和应答的情况下,ICMP标识符字段被用来代替传输层的端口号)。

于端点和依赖于地址的过滤。因此,它是和我们前面讨论过的NAT 穿越技术(如ICE,STUN,TURN)兼容的。缺乏这些附加协议,NAT64仅支持由 IPv6主机发起的与IPv4主机通信的动态转换。

NAT64在跨越多个地址类型时像传统的NAT(NAPT)那样工作,除了从IPv4到IPv6这个方向的转换比相反方向的转换更加简单。一个NAT64 设备被赋予一个IPv6前缀,能用于形成一个有效的IPv6地址,该地址是通过第2章和[RFC6052]描述的机制从IPv4上直接转换过来的。由于IPv4地址空间的不足,在IPv6 到IPv4这个方向的转换利用了一个动态管理的IPv4地址池。这需要NAT64支持NAPT的功能,据此多个不同的IPv6地址可能会映需射到一个相lНIPv4地址上。NAT64 目前定义了由 IPv6 节点初始化的 TCP,UDP和ICMP报文的转换方法(在ICMP查询和应答的情况下,ICMP标识符字段被用来代替传输层的端口号)。

NAT64 处理分片不同于其有状态部分。对于到达的传输层校验和不为 0 的 TCP 或者UDP 分片,NAT64 可能会将分片排队,然后一起或者单独地转换它们。NAT64必须处理分片,即便是那些乱序到达的。一个 NAT64可能被配置一个时限,限制分片被缓存的时间(至少为 2s)。否则,NAT 可能受到 DoS 攻击,耗尽保存分片的包缓冲空间。

相关文章:

  • vue3+three 搭建平面上滚动旋转的几何体
  • 第一章 应急响应-webshell查杀
  • 无线定位之 二 SX1302 网关源码 thread_down 线程详解
  • RAGFlow 初步尝试 (01)
  • Leetcode (力扣)做题记录 hot100(34,215,912,121)
  • MongoDB 操作可能抛出哪些异常? 如何优雅的处理?
  • 全球变暖-bfs
  • matlab计算天线的近场和远场
  • MongoDB使用x.509证书认证
  • Matlab基于PSO-MVMD粒子群算法优化多元变分模态分解
  • 逆向破解:x64dbg
  • Python 处理图像并生成 JSONL 元数据文件 - 灵活text版本
  • 机器学习——集成学习基础
  • AI边缘网关_5G/4G边缘计算网关厂家_计讯物联
  • Clion远程开发git触发“No such device or address”的解决方案
  • 数据库笔记(1)
  • Oracle adg环境下调整redo日志组以及standby日志组大小
  • 音视频学习:使用NDK编译FFmpeg动态库
  • Matlab 基于GUI的汽车巡航模糊pid控制
  • 榜单按行显示
  • 礼来公布头对头研究详细结果:替尔泊肽在所有减重目标中均优于司美格鲁肽
  • 汉斯·季默:不会指挥的声音工程师终成音乐“大神”
  • 人民日报读者点题·共同关注:今天我们为什么还需要图书馆?
  • 中方是否认同俄方关于新纳粹主义观点?外交部:联大曾多次通过相关决议
  • 中国国家电影局与俄罗斯文化部签署电影合作文件
  • 司法部:加快研究制定行政执法监督条例,建立完善涉企行政执法监督长效机制