我正在尝试在NAT后面的两台计算机之间建立连接。我无法打开任何端口。我想使用一个经纪人,他将在互联网上并且能够与其他两个人进行通信。之后,我想在两者之间建立一条隧道。我正在使用Python,并且正在尝试对该代理进行编码。我该如何开始呢?

最佳答案

您想要做的是可能的,并且几乎是例行的(至少对于UDP)。这就是所谓的NAT打洞。它不能与世界上所有的NAT一起使用,但可以与许多NAT一起使用,包括当前大多数家用路由器的大多数设置。

基本思想是,对于大多数路由器,如果您发送传出数据包,它将把来自同一端点的所有传入数据包转发回给您。否则,NAT根本无法工作,对吗?因此,如果您和我都尝试同时与对方的公共(public)地址交谈,我们中的一个人将及时在他的NAT中“打个洞”以接收消息。另一个人可能会错过最初的消息,因为他打洞太晚了,但是他将收到另一个人发送的下一个答复,此后一切正常。

但是,这里有一些技巧。

首先,您需要知道您的公共(public)地址。您可以直接看到的只是NAT内部的专用地址,因此您需要NAT外部的服务器来告诉您您的来源。有一个标准,称为STUN。您不仅可以构建和运行多个免费的实现,而且互联网上还有多个开放的STUN服务器。谷歌的更新列表。

至少,您有一个私有(private)地址和一个公共(public)地址,并且您真的想将所有这些都给另一个人,而不仅仅是一个。 (如果您只给我您的公共(public)地址,而事实证明我们在同一个NAT上,我们可能无法互相通信。)如果您有多个NIC,或者您有多个NIC,则情况将变得更加复杂。在具有多层NAT等功能的公司LAN上。但是,如果给我一大堆地址,我怎么知道要使用哪个地址?很简单,我可以尝试从每个本地地址连接到每个地址,第一个有效的地址就是我一直使用的地址。显然,我们为此需要某种协议(protocol),以便您可以告诉我其中一个协议(protocol)何时起作用,但是这很简单。

另外,请注意,当我在此处说“地址”时,这不仅表示IP地址,还表示IP地址加端口。毕竟,NAT可以并且确实可以转换端口以及地址,而您在NAT中打洞的“漏洞”通常是特定于端口的。因此,您需要使用将用于实际通信的相同源端口和目标端口进行协商。 (实际上,这里有一些棘手的地方,由链接的文档进行了解释,但让我们现在略过它们。)

当打洞不起作用时,您需要通过服务器进行代理,则您不希望该代码看起来完全不同。您最终将不得不编写两次所有内容,并且在调试方面遇到了巨大的问题。幸运的是,有一个标准的解决方案称为TURN,它使对等端看起来就像他们实际上在直接讲话一样,即使他们正在通过中继进行交谈。再次有免费的实现,但是当然没有开放的TURN服务器供您使用(因为这会占用大量带宽)。

同时,一旦您知道自己的公开地址,就必须告诉我它是什么,反之亦然。显然,我们需要一些辅助 channel 来进行交谈,例如特殊的“介绍者”或“大厅”服务器。通常,您会生成对等连接作为某些服务器中介连接的分支。例如,我们可能一起在IRC channel 中,或者在XMPP/Jabber聊天网络中,并决定我们要进行对等通信(以避免窃听,共享巨大的电子表格文件或玩游戏而没有大量内容)落后)。

有一个叫做ICE的标准将所有这些联系在一起。只要我们有一个共享的边信道和一个STUN(可能还有TURN)服务器列表,ICE就可以让我们在可能的情况下协商对等连接(如果不可以,则返回TURN)。

ICE支持是SIP和许多其他协议(protocol)的一部分,因此,如果您为这些协议(protocol)之一使用库,则可能只需要找出如何为其提供STUN和TURN服务器列表即可。如果没有,那么可能有用于执行ICE的库。如果没有,则肯定有用于执行STUN和TURN的库(如果没有,它们都是非常简单的协议(protocol)),因此您可以自己在它们之上进行协商。

当然,您不必使用这些标准中的任何一个,但是您绝对应该阅读它们的作用以及为什么这样做的原因。 (还要记住,人们现在正在专门制造路由器以使ICE更好地工作,而对于您所发明的任何其他东西都不是正确的。)

我之所以链接到上面的Wikipedia文章,是因为它们从一个非常简单的概述开始,概述了技术的工作原理和背后的原理。对于详细的引用规范,入门示例代码,要使用的库等都有更好的来源,但是通常Wikipedia包含指向您需要的所有其他内容的链接。

关于python - 在NAT后面的两台计算机之间建立连接,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/26267599/

10-15 08:55