2014-10-08 110 views
-1

我试图在NAT之后的两台计算机之间建立连接。我无法打开任何端口。我想使用一名将在互联网上的经纪人,他将能够与另外两人交流。之后,我想在这两个之间建立一个隧道。我使用Python,并且我正在尝试为这个代理编写代码。 我该如何开始呢?在NAT之后的两台计算机之间建立连接

+0

有一百种方法可以做到这一点。 NAT后面的计算机将不得不启动与常见的互联网代理的连接。实验的一个简单选项是zeromq,它有几个可用于路由消息的工具。你甚至可以设置一个在两台服务器之间转发请求的asyncio服务器。 – tdelaney 2014-10-08 22:50:53

+0

嗯,但是可以将服务器连接到代理,然后将客户连接到此代理,并在这两者之间建立隧道?没有再次使用经纪人 – 2014-10-08 22:55:45

+0

不,所有流量都必须经过经纪人。我假设这些机器位于不同的NAT之后,并且您不希望在NAT之后进行端口转发。如果是这样,这些机器是彼此不可见的,并且需要某种通用代理/经纪人进行通信。 – tdelaney 2014-10-08 23:09:24

回答

12

你想做什么可能的,几乎是例行的(至少对于UDP)。这就是所谓的NAT打孔。它不适用于全球所有的NAT,但它可以与许多设备一起使用,包括大多数当前家庭路由器的大多数设置。

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

但是,这里有一些技巧。

首先,您需要知道您的公开地址。你可以直接看到是你在NAT内的私人地址,所以你需要一个NAT以外的服务器来告诉你你来自哪里。有一个标准,称为STUN。不仅有多个可以自己构建和运行的免费实现,互联网上有多个开放的STUN服务器;谷歌更新列表。

至少,你有一个私人地址和你的公共地址,你真的想给其他人所有他们,而不只是一个。 (如果你只给我你的公共地址,而且事实证明我们在同一个NAT上,我们可能无法相互交谈。)如果你有多个NIC,它会变得更加复杂,或者你是在具有多层NAT的企业局域网上等。但是如果你给我一大堆地址,我怎么知道使用哪一个?简单来说,我可以尝试从每个本地地址连接到每个地址,而第一个工作的地方就是我一直使用的地址。我们显然需要某种协议,所以你可以告诉我他们中的一个是否已经工作,但它可能很简单。

另外,请注意,当我在这里说“地址”时,这并不仅仅意味着IP地址,而是IP地址加上端口。毕竟,NAT可以并且可以将端口与地址一起转换,并且您在NAT中打出的“孔”通常是端口特定的。因此,您需要使用您将用于真正通信的相同源端口和目标端口进行协商。 (实际上,这里有一些棘手的问题,这是由链接文档解释的,但现在让我们一起浏览它们。)

当穿孔不起作用,并且您需要通过服务器回退代理,你不希望代码看起来完全不同;你最终不得不把所有东西都写两遍,并且在调试时遇到很大问题。幸运的是,这里有一个标准的解决方案,叫做TURN,它使得它看起来像是他们实际上直接对话,即使他们正在通过中继谈话。再次有免费的实现,但当然没有开放的TURN服务器供您使用(因为这会花费很多带宽)。

同时,一旦你知道你的公开地址,你必须告诉我它是什么,反之亦然。显然,我们需要一些辅助通道来讨论,如特殊的“介绍者”或“大厅”服务器。通常,您将产生一个点对点连接作为一些服务器中介连接的旁枝。例如,我们可能一起在IRC频道或XMPP/Jabber聊天网络中,决定我们想要点对点通信(以避免窃听,或共享巨大的电子表格文件,或者玩一个没有巨大数量的游戏落后)。

有一个叫做ICE的标准把这一切联系在一起;只要我们有一个共享侧通道和一个STUN(可能是TURN)服务器的列表,ICE让我们在可能的情况下协商一个对等连接(如果没有的话,则回落到TURN)。

ICE支持是SIP和其他一些协议的一部分,所以如果您使用其中一种协议的库,您可能只需要了解如何为它提供一个STUN和TURN服务器列表以及而已。如果没有,那么可能有用于ICE的库。如果没有,那么肯定有STUN和TURN库(如果没有,它们都是非常简单的协议),所以你可以自己做谈判。

当然,您不必使用这些标准中的任何一个,但您一定要阅读他们的工作内容,以及他们为什么要这样做。 (另外,请记住,人们现在正在路由器专门做ICE更好地工作,以及有什么不同,你创造这不会是真的。)


我已链接到维基百科的文章,因为以上他们首先对这些技术的工作原理和背后的基本原理进行了非常简单的概述。有详细的参考规范,开始的示例代码,要使用的库等的更好的来源,但一般来说维基百科链接到您需要的一切。

+1

非常感谢您的回答。我有最后一个问题。我看到如何拥有所有客户的公共IP。但如何拥有港口? – 2014-10-09 09:00:54

+1

@MathieuLepage:好问题。由于NAT可以重新映射端口,因此您必须通过STUN获取公共端口,并通过您使用的任何辅助渠道或介绍人宣布该地址,就像地址一样。有些协议(包括SIP)尝试使用相邻端口范围的技巧,但许多NAT会打破这些技巧,所以如果可以避免的话,那么做。无论如何,如果你正在使用ICE,它会与其余的谈判一起处理。 – abarnert 2014-10-09 18:46:04

+0

但冰可以使用没有眩晕和转弯? – 2014-10-09 20:48:26

相关问题