2016-05-26 74 views
3

如果有问题的NAT设备重写出站ICMP数据包,ICMP NAT穿越应该如何工作?ICMP打孔缺陷?

========================================================================================= 
| CLIENT | <---> | NAT-C | <---> { internet } <---> | NAT-S | <---> | SERVER | 
========================================================================================= 
        19.19.19.19 (external addresses) 72.72.72.72 
192.168.0.2  192.168.0.1 (internal addresses) 172.16.0.1  172.16.0.2 

力学

pwnat描述ICMP holepunching的快速概览:

SERVER发送ICMP回应请求包(ping),以一些其它宿主(例如3.3.3.3)至在NAT-S打开一个洞。当CLIENT想要连接时,它发送一个ICMP Time Exceeded数据包到NAT-S,这应该被路由到SERVER。为了使所述路由工作,CLIENT通过在其中嵌入相同的数据包(ICMP回声到3.3.3.3)来构造ICMP超时数据包,它期望SERVER首先发送。

问题

如果CLIENT需求,从而嵌入在其ICMP超时回复留下NAT-S相同(ICMP回应请求)数据包,它必须知道包的查询ID。 但是它如何知道这个查询ID?

RFC 3022 Section 2.2,当NAT-S遇到出站ICMP回应请求,重写数据包的查询ID字段以独特的外部查询ID,以便它可以路由未来ICMP回声相同的查询ID,以SERVER回复。

鉴于上述问题,似乎背后pwnat和ICMP holepunching背后的前提是无效的,它从来没有工作。我在这里错过了什么吗?

在此先感谢:)

回答

3

您对查询ID是正确的。

pwnat现在很少有作品。我几年前碰巧知道这个icmp冲孔的东西,并对这个想法感兴趣。我已经阅读了pwnat的源代码并在Go中自己重新实现了它。只有进行简单地址转换的基本NAT设备(rfc 1631描述)可以与它一起工作,具有健壮NAPT实现的任何NAPT设备都不会这样做。

除了标识符问题,(顺便说一句,pwnat的source code使用0作为原始请求的标识符)pwnat没有给出原始ip头的正确校验和,这可能导致NAT-S丢弃TTL超出的消息(如果数据包可以到达那里)。
更严重的,根据rfc 5508

当NAT设备接收来自私人领域的ICMP错误分组

,NAT设备使用嵌入的ICMP错误消息(内的分组即来自客户端的IP分组到服务器)查找嵌入式数据包所属的NAT会话。如果NAT设备没有嵌入式数据包的活动映射,NAT应该悄悄丢弃ICMP错误数据包。

这意味着来自客户端的ICMP Time Exceeded报文不会通过NAT-C。 This paper确实提到了这种情况并推荐了其他解决方案。