在NAT后面的两台计算机之间建立连接 [英] Make a connexion between two computers behind NAT

查看:189
本文介绍了在NAT后面的两台计算机之间建立连接的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I'm trying to etablish a connexion between two computers behind NAT. I can't open any port. I would like to use a broker who will be on the internet and who will be able to comunicate with the 2 others. After, i would like to etablish a tunnel between those 2. I'm using Python and i'm trying to code this broker. How can i begin this ?

推荐答案

您想做的 是可能的,并且几乎是常规的(至少对于UDP).这就是所谓的NAT打孔.它不能与世界上所有的NAT一起使用,但可以与许多NAT一起使用,包括最新家用路由器的大多数设置.

What you want to do is possible, and almost routine (at least for UDP). It's called NAT hole punching. It won't work with every NAT in the world, but it works with many, including most setups of most current home routers.

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

The basic idea is that, with most routers, if you send an outgoing packet, it will forward any incoming packets from the same endpoint back to you. Otherwise, NAT wouldn't work at all, right? So, if both you and I try to talk to each other's public addresses at the same time, one of us will have "punched a hole" in his NAT in time to receive the message. The other one will probably miss the initial message, because he punched his hole too late, but he'll receive the next reply the other guy sent, and after that, everything is working.

但是,这里有一些技巧.

There are a few tricks here, however.

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

First, you need to know your public address. All you can see directly is your private address inside the NAT, so you need a server outside the NAT that can tell you where you're coming from. There's a standard for this, called STUN. Not only are there multiple free implementations you can build and run yourself, there are multiple open STUN servers on the internet; google for an updated list.

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

At minimum, you have one private address and your public address, and you really want to give the other guy all of them, not just one. (If you only give me your public address, and it turns out that we're on the same NAT, we may not be able to talk to each other.) It gets even more complicated if you have multiple NICs, or you're on a corporate LAN with multiple layers of NAT, etc. But if you give me a whole slew of addresses, how do I know which one to use? Simple, I can just try to connect to each of them from each of my local addresses, and the first one that works is the one I keep using. We obviously need some kind of protocol for this so you can tell me when one of them has worked, but it can be dead simple.

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

Also, note that when I say "address" here, that doesn't just mean IP address, but IP address plus port. After all, NATs can and do translate ports along with addresses, and the "hole" that you punch in a NAT is often port-specific. So, you need to do the negotiation using the same source and destination ports you're going to use for the real communication. (Actually, there are some tricky bits here, which are explained by the linked documents, but let's skim over them for now.)

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

When hole punching doesn't work, and you need to fall back to proxying through a server, you don't want that code to look completely different; you'd end up having to write everything twice, and having huge problems with debugging. Fortunately, there's a standard solution for this, called TURN, which makes it look to the peers like they're actually talking directly even where they're talking through a relay. Again there are free implementations, but of course there aren't open TURN servers for you to use (because that would cost a lot of bandwidth).

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

Meanwhile, once you know your public address, you have to tell me what it is, and vice versa. Obviously we need some side channel to talk on, like a special "introducer" or "lobby" server. Typically, you're spawning a peer-to-peer connection as an offshoot of some server-mediated connection. For example, we might be in an IRC channel together, or an XMPP/Jabber chat network, and decide we want a peer-to-peer communication (to avoid eavesdropping, or to share giant spreadsheet files, or to play a game without huge lag).

有一个称为 ICE 的标准,它将所有这些联系在一起;只要我们有一个共享的边信道和一个STUN(可能还有TURN)服务器列表,ICE便可以让我们协商对等连接(如果可能的话,则回退到TURN).

There's a standard called ICE that ties this all together; as long as we have a shared side channel and a list of STUN (and possibly TURN) servers, ICE lets us negotiate a peer-to-peer connection if possible (falling back to TURN if not).

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

ICE support is part of SIP and a number of other protocols, so if you're using a library for one of those protocols, you probably just need to find out how to give it a list of STUN and TURN servers and that's it. If not, there are probably libraries for doing ICE. If not, there are definitely libraries for doing STUN and TURN (and if there weren't, they're both pretty simple protocols), so you can do the negotiation yourself on top of them.

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

Of course you don't have to use any of these standards, but you should definitely read what they do and why they do things that way. (Also, keep in mind that people are now making routers specifically to make ICE work better, and that won't be true for anything different that you invent.)

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

I've linked to Wikipedia articles above because they start off with a pretty simple overview of how the technologies work and the rationale behind them. There are better sources for the detailed reference specifications, sample code to get started, libraries to use, etc., but generally Wikipedia has links to everything else you need.

这篇关于在NAT后面的两台计算机之间建立连接的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆