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

Mat*_*age 2 python nat

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

aba*_*ert 18

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

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

但是,这里有一些技巧.

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

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

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

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

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

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

ICE支持是SIP和许多其他协议的一部分,所以如果你使用其中一个协议的库,你可能只需要找到如何给它一个STUN和TURN服务器的列表,就是这样.如果没有,可能有用于做ICE的库.如果没有,肯定有用于执行STUN和TURN的库(如果没有,它们都是非常简单的协议),所以你可以在它们之上自己进行协商.

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


我已经链接到上面的维基百科文章,因为他们开始时非常简单地概述了技术如何运作以及它们背后的基本原理.有详细的参考规范,开始的示例代码,使用的库等等,有更好的来源,但维基百科通常会链接到您需要的其他所有内容.