当我从对称 nat 下的网络发送 tcp 或 udp 数据包时,我希望端口与我的计算机选择的端口不同,所以它是。但是当我发送一个低 ttl 的 udp 数据包,但它仍然设法离开 ISP 网络时,我收到一个错误 icmp 数据包,其中包含我最初作为有效负载发送的 udp 数据包,但端口由我生成系统 。
在这一点上,我怀疑 NAT 是否也没有掌握 ICMP 数据包的内容。因为我知道有必要更改真正重要的层的标头而不是有效负载。因此,在 ICMP 数据包的情况下,只有源 IP 地址,而不像我认为的那样,还有回显“子数据包”的 ip 和端口。
那是 NAT 的网络地址端口转换 (NAPT)版本。基本 NAT 对传输协议没有任何作用。NAPT 必须为每个传输协议有不同的表,这就是为什么它只支持 TCP、UDP 和 ICMP,因为 TCP 端口不是 UDP 端口,而 ICMP 不使用端口,它使用查询 ID。
那是正确的。
对于必须返回发送应用程序的 ICMP 错误消息,是的,NAPT 必须修复 ICMP 错误消息的内容,以便目标应用程序得到错误。ICMP 错误消息将原始数据包的第一部分作为其有效负载,以便可以将其返回给正确的应用程序。如果 NAPT 修改了传出数据包,它必须将返回的 ICMP 错误消息有效负载修改为原始地址,包括端口号。
此行为在RFC 2663,IP 网络地址转换器 (NAT) 术语和注意事项中进行了解释:
如您所见,NAT,尤其是 NAPT,非常占用资源,这就是为什么一些供应商(例如 Cisco)只允许在具有 NAT 硬件辅助的设备上进行 NAT。
由于您指的是 UDP 数据包,因此不会在 ICMP 消息中欺骗 TCP 端口。然而,出于多种原因,它很可能会重写 ICMP 消息以反映原始 UDP 流量(围绕您的主机/应用程序需要知道如何处理并可能在收到此类 ICMP 消息后做出响应)。
这可能因 NAT 实现而异,但让我们看一下您的示例(相信您在问题中陈述的所有内容都是准确的)。
停下来想一想。生成 ICMP 超时消息的路由器将没有“我最初发送的 udp 数据包”,因为它通过了您的 NAT 网关并被转换。换句话说,生成 ICMP 消息的路由器怎么会知道要放入 ICMP 消息中的原始信息是什么?
原始 UDP 数据包可能在 ICMP 消息的有效负载中的唯一方法是您的 NAT 网关重写它。