UDP打洞技术

8
我有关于UDP打洞的一些问题。根据维基百科 http://en.wikipedia.org/wiki/UDP_hole_punching 1)要在两个参与方之间(客户端在NAT后面,服务器不在NAT中)建立UDP会话,客户端是否只需向服务器发送一个数据包,然后允许防火墙进行双向(发送和接收)通信?这意味着客户端也可以从服务器接收数据。
2)UDP打洞:两个客户端首先连接到服务器,然后服务器将一个客户端的端口/IP传递给其他客户端,因此客户端可以在这些端口上相互发送数据包。这样是正确的吗?
3)如果#2是真的,为什么防火墙会允许从不同于该端口建立连接时使用的IP地址接收数据?听起来像一个巨大的安全漏洞,应该被轻易过滤掉吧?我知道源IP欺骗可以欺骗它,但是这种情况呢?
谢谢,Johan
2个回答

5

1) 大多数合理的防火墙都可以,除非你将其配置为极端偏执模式。

2) 不完全是这样。 这篇文章 对此进行了更详细的解释,但基本思路是其中一台客户端首先向另一个公共IP发送数据包。然后该数据包被丢弃,但另一个客户端知道它已被发送,因为第一个客户端通过服务器告诉了它。然后另一个客户端向第一个客户端回复相同端口的数据包,因为第一个数据包来自该端口,所以第一个客户端的NAT会记住该端口有一个数据包,因此将传入的数据包视为对第一个数据包的回复。问题在于要确定NAT将选择哪个公共端口发送第一个数据包,但大多数NAT都以可预测的方式完成,因此几乎总是可以正常工作,有时只需尝试几次即可。


据我所了解,当用户发送数据时,实际上使用了两个不同的端口;首先是他绑定的端口(客户端的“私有”端口),其次是他正在发送的端口(客户端的“公共”端口)。因此,我需要告诉每个客户端其他客户端的公共端口是什么,如果他们尝试使用自己的私有端口进行通信,那是行不通的。(例如,我将所有端口绑定到12340,其他客户端不能只向其他客户端的IP + 12340发送数据) - KaiserJohaan
@Kaiser,通常情况下这样是行不通的。你需要找出哪个公共端口映射到了你的私有端口。据我所知,这是通过从私有端口向服务器发送一些内容来完成的,然后服务器告诉双方该端口。但如果两个客户端恰好都在同一个NAT后面,可以尝试使用私有IP地址与私有端口进行通信,这将在局域网中起作用。 - Sergei Tachenov

2

1) 是的。但是,如果您连接的是非NAT服务器,则无需进行孔洞穿越。您的客户端应用程序只需正常运行。

2) 是的。

3) 一些NAT确实会将公共端口限制为一个发送者-接收者对。如果您需要在这种情况下进行孔洞穿越,那么您唯一的机会就是猜测NAT将为直接连接选择哪个公共端口。

然而,NAT不是安全功能。因此,接受任何公共端口的数据包并不构成安全漏洞,因为与客户端直接连接到互联网的简单情况没有区别。


因此,私有端口(应用程序中的bind()端口)与公共端口(实际发送的端口)不同。当客户端连接到服务器时,服务器会看到公共端口还是私有端口?我需要中继公共端口而不是私有端口,以允许其他客户端进行通信吗? - KaiserJohaan
@KaiserJohaan 是的,私有端口对公共通信无关紧要。 - phihag

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接