在NAT后面的两台计算机之间建立联系

时间:2014-10-08 22:42:10

标签: python nat

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

1 个答案:

答案 0 :(得分:18)

你想做什么可能的,几乎是常规的(至少对于UDP)。它被称为NAT洞打孔。它不能与世界上的每个NAT一起工作,但它适用于许多设备,包括大多数当前家用路由器的设置。

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

然而,这里有一些技巧。

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

至少,你有一个私人地址和你的公共地址,你真的想要给其他人所有,而不只是一个。 (如果你只给我你的公共地址,结果我们在同一个NAT上,我们可能无法互相交谈。)如果你有多个网卡,或者你和#39;在具有多层NAT等的企业局域网上。但是如果你给我一大堆地址,我怎么知道使用哪一个?很简单,我可以尝试从每个本地地址连接到每个地址,第一个有效的是我一直使用的地址。我们显然需要某种协议,所以你可以告诉我其中一个有效,但它可能很简单。

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

当打孔不起作用,并且您需要通过服务器回退代理时,您不希望该代码看起来完全不同;你最终必须写两次,并且调试时遇到很大问题。幸运的是,有一个标准的解决方案,称为TURN,这使得它看起来像他们实际上直接说话,即使他们通过中继说话。同样有免费的实现,但当然没有打开TURN服务器供您使用(因为这将花费大量带宽)。

同时,一旦你知道你的公共地址,你必须告诉我它是什么,反之亦然。显然我们需要一些侧面通道来讨论,比如一个特殊的"介绍人"或" lobby"服务器。通常,您将产生对等连接作为某些服务器中介连接的分支。例如,我们可能在一起的IRC频道,或XMPP / Jabber聊天网络,并决定我们想要点对点通信(避免窃听,或共享巨大的电子表格文件,或玩没有巨大的游戏)滞后)。

有一个名为ICE的标准将这一切联系在一起;只要我们有共享的侧通道和STUN(以及可能的TURN)服务器列表,ICE就可以让我们在可能的情况下协商点对点连接(如果没有则回退到TURN)。

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

当然,你不必使用任何这些标准,但你一定要阅读他们做的事情,以及他们为什么这样做。 (另外,请记住,人们现在专门制作路由器以使ICE更好地工作,并且对于您发明的任何不同的东西都不会成为现实。)


我之前与上述维基百科的文章相关联,因为他们开始时非常简单地概述了这些技术的工作原理及其背后的基本原理。有详细的参考规范,开始的示例代码,使用的库等等,有更好的来源,但维基百科通常会链接到您需要的其他所有内容。