java 什么是 STUN,它是否需要端口转发服务器?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/13501288/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-31 12:59:46  来源:igfitidea点击:

What is STUN and does it need a port-forwarded server?

javatcpudpportforwardingstun

提问by daviga404

I've done some research on p2p communication without a base server, and came over STUN. From what I've read, STUN is a way of NAT "Hole Punching" that would not require a peer to be port-forwarded to be connected to. Is this correct, and what exactly does hole punching mean? It all seems very vulnerable as it is going past the firewall if it does not require port-forwarding, and I do not entirely understand what STUN does. Could STUN be used in a p2p program in Java or another language such as a chat client that sends messages over TCP/UDP ports to the peer WITHOUT a base server or WITHOUT requiring the user to port forward?

我在没有基本服务器的情况下对 p2p 通信进行了一些研究,并且研究了 STUN。从我读过的内容来看,STUN 是一种 NAT“打孔”方式,不需要对等端进行端口转发即可连接。这是正确的,打孔究竟是什么意思?如果不需要端口转发,这一切似乎都非常脆弱,因为它会通过防火墙,而且我不完全理解 STUN 的作用。STUN 是否可以用在 Java 或其他语言的 p2p 程序中,例如聊天客户端,它通过 TCP/UDP 端口向对等方发送消息,而无需基本服务器或无需用户转发端口?

回答by Chris

Consider the task of two machines wanting to communicate with each other. If the two machines are connected directly to the public Internet (not behind a router), then the two machines simply send packets back and forth to each other's public IP. Typically, machines are behind one or more routers. To simplify the problem, we assume only one level of routers.

考虑两台机器想要相互通信的任务。如果两台机器直接连接到公共互联网(而不是在路由器后面),那么两台机器只需将数据包来回发送到彼此的公共 IP。通常,机器位于一个或多个路由器之后。为了简化问题,我们假设只有一层路由器。

NAT traversal solves the problem of routers translating the outgoing port number of packets into something else (e.g. you send a request from port X, the router translates the packet to act as if it left from port Y instead). If the routers are port-forwarding, then the router doesn't actually do any translation (port X->X). Most home/corporate/etc routers are not port-forwarding, however, and thus NAT traversal comes into play. See NAT traversaland different types of NATs.

NAT 遍历解决了路由器将数据包的传出端口号转换为其他内容的问题(例如,您从端口 X 发送请求,路由器将数据包转换为好像它是从端口 Y 离开的)。如果路由器是端口转发,则路由器实际上不会进行任何转换(端口 X->X)。然而,大多数家庭/公司/等路由器都不是端口转发,因此 NAT 穿越开始发挥作用。请参阅NAT 穿越和不同类型的NAT

Consider a router's firewall that does any of the non port-forwarding translations in the above article (e.g.full cone). If a router receives some packet to port X, but the router has not sent any packets from port Y, it drops the packet (after all, to whom was the packet meant? the router has no idea!). Only when some private machine sends a packet and the router makes a translation to map port X from that private machine to external port Y will external packets TO port Y be forwarded to the private machine.

考虑一个路由器的防火墙,它执行上述文章中的任何非端口转发转换(例如全锥)。如果路由器收到一些到端口 X 的数据包,但路由器没有从端口 Y 发送任何数据包,它就会丢弃数据包(毕竟,数据包是给谁的?路由器不知道!)。只有当某个私有机器发送数据包并且路由器进行转换以将端口 X 从该私有机器映射到外部端口 Y 时,外部数据包才会转发到端口 Y 到私有机器。

STUN traversal

STUN穿越

In order for two clients, A and B both behind firewalls across the Internet, to communicate directly, they must somehow know the router mapping. The general solution is to use a STUN server to determine their port mapping. Machine A sends a packet form port X to STUN. The router translated the port to Y, and the STUN server sees this and responds back to A telling him what the external port was. B does the same. Then, A and B exchange their translated ports (by using some other central server...for a simplified example, Skype might have a central login server where A and B tell the Skype server their port translations, and Skype tells A and B respectively about the port mappings). Then, B sends a packet to A's public IP using port Y, not X. Machine A "punched" its firewall, allowing it to receive packets from external port Y.

为了让两个客户端 A 和 B 都在 Internet 上的防火墙后面直接通信,它们必须以某种方式知道路由器映射。一般的解决方案是使用 STUN 服务器来确定它们的端口映射。机器 A 向 STUN 发送一个来自端口 X 的数据包。路由器将端口转换为 Y,STUN 服务器看到这一点并回复 A 告诉他外部端口是什么。B 也一样。然后,A 和 B 交换他们翻译的端口(通过使用其他一些中央服务器......举个简单的例子,Skype 可能有一个中央登录服务器,其中 A 和 B 告诉 Skype 服务器他们的端口转换,Skype 分别告诉 A 和 B关于端口映射)。然后,B 使用端口 Y 而不是 X 向 A 的公共 IP 发送一个数据包。机器 A“刺穿”了它的防火墙,允许它从外部端口 Y 接收数据包。

Secure?

安全的?

You mention security: does hole punching open up a network to security violations? Potentially...I haven't studied the subject, but consider a full cone NAT. Once the mapping is made, ANY external machine can send packets to machine A's router and A will get the packets, even if A has never sent a packet to some malicious machine Z. Machine Z, of course, would have to somehow discover the mapping. Some the Wikipedia article, the diagram only shows full cone NATs having this vulnerability, but don't take my word for it. Judging by the amount of applications that use hole punching (Skype, xbox live, ...), it would appear networks rely on application and system-level firewall protections in addition to router firewall measures.

您提到了安全性:打孔是否会导致网络安全违规?可能......我没有研究过这个主题,但考虑一个完整的锥形 NAT。映射完成后,任何外部机器都可以向机器 A 的路由器发送数据包,A 将收到数据包,即使 A 从未向某些恶意机器 Z 发送数据包。当然,机器 Z 必须以某种方式发现映射. 一些维基百科文章,该图仅显示了具有此漏洞的完整锥形 NAT,但不要相信我的话。从使用打孔的应用程序(Skype、xbox live 等)的数量来看,除了路由器防火墙措施外,网络似乎还依赖于应用程序和系统级防火墙保护。

The Ford article below briefly mentions security: "Contrary to what its name may suggest, hole punching does not compromise the security of a private network." It would seem that networks rely on system-level firewalls more than router firewalls.

下面的福特文章简要提到了安全性:“与其名称所暗示的相反,打孔不会损害专用网络的安全性。” 与路由器防火墙相比,网络似乎更依赖于系统级防火墙。

Symmetric NATs and TURN traversal

对称 NAT 和 TURN 遍历

STUN doesn't always work: some routers "behave badly." Machine A might send two packets from port X, one to stackoverflow.com and one to facebook.com. The router maps the stackoverflow.com packet FROM port Y and the facebook.com packet FROM port Z (even though machine A send both packets FROM internal port X). This is a symmetric NAT. These NATs are problematic, since the above STUN/Skype connection won't work. Replace stackoverflow.com with STUN and facebook.com with machine B (the person you're trying to Skype with). Unfortunately, STUN can find out the NAT mapping for packets A sends to STUN, but packets sent to B use an entirely different mapping. In general, it is impossible (without you being able to track outbound router packets) to determine port mappings for symmetric NATs. Thus, a central routing server is needed for clients to communicate, but this defeats the whole point of p2p. See TURN.

STUN 并不总是有效:一些路由器“表现不佳”。机器 A 可能从端口 X 发送两个数据包,一个到 stackoverflow.com,一个到 facebook.com。路由器映射来自端口 Y 的 stackoverflow.com 数据包和来自端口 Z 的 facebook.com 数据包(即使机器 A 从内部端口 X 发送两个数据包)。这是一个对称的 NAT。这些 NAT 是有问题的,因为上面的 STUN/Skype 连接不起作用。将 stackoverflow.com 替换为 STUN,将 facebook.com 替换为机器 B(您尝试与之 Skype 的人)。不幸的是,STUN 可以找出 A 发送到 STUN 的数据包的 NAT 映射,但发送到 B 的数据包使用完全不同的映射。通常,(如果您无法跟踪出站路由器数据包)确定对称 NAT 的端口映射是不可能的。因此,客户端需要一个中央路由服务器来进行通信,但这会破坏 p2p 的全部意义。看

Can we use this in a Java chat program?

我们可以在 Java 聊天程序中使用它吗?

Any language with network library support (Java, C, etc) where you can send packets from arbitrary ports can use STUN to traversal a NAT (as long as its not a symmetric NAT, etc). In general, one alwaysneeds a central server (in this case two: STUN and a loginserver). The loginserver is used as described in the Skype example; once two clients know their port mappings, they must communicate this to each other somehow beforethe p2p communicate has begun (see chicken or the egg). But once A and B know each other's public IPs and NAT mappings, they can communicate directly.

任何具有网络库支持的语言(Java、C 等),您可以从任意端口发送数据包,都可以使用 STUN 来遍历 NAT(只要它不是对称 NAT 等)。一般来说,一个总是需要一个中央服务器(在这种情况下两个:STUN 和一个登录服务器)。的登录如Skype的实施例中描述用于服务器; 一旦两个客户端知道他们的端口映射,他们必须在 p2p 通信开始之前以某种方式相互通信(参见先有鸡还是先有蛋)。但是一旦 A 和 B 知道彼此的公共 IP 和 NAT 映射,他们就可以直接通信。

Caveat

警告

Though I can't possibly list all NAT traversal caveats, one important concept is keep alive: once the router has made a port mapping, how long will it last? Say I connect to a STUN server, then wait 10 minutes for B to send me a packet once I tell it the mapping. The router will likely have dropped the mapping (routers have to regularly clear out old mappings for make room for new ones, and for a minimal attempt at security). I can't find my reference, and I think it varies depending on TCP vs UDP packets, but applications I am familiar with send a keep-alive packet every ~60 seconds or less to ensure the router doesn't drop the mapping. Once the router drops the mapping and machines trying to send packets, the packets will be dropped (leading to hours of confusion for me...).

虽然我不可能列出所有的 NAT 穿越警告,但一个重要的概念是保持活动:一旦路由器进行了端口映射,它会持续多久?假设我连接到 STUN 服务器,然后等待 10 分钟让 B 在我告诉它映射后向我发送一个数据包。路由器可能会丢弃映射(路由器必须定期清除旧映射,以便为新映射腾出空间,并尽量减少安全性尝试)。我找不到我的参考资料,我认为它因 TCP 与 UDP 数据包而异,但我熟悉的应用程序每约 60 秒或更短时间发送一个保持活动数据包,以确保路由器不会丢弃映射。一旦路由器丢弃映射并且机器尝试发送数据包,数据包将被丢弃(导致我数小时的困惑......)。

Articles

文章

The last article is a great introduction to many of the ideas for routers and NAT traversal in genreal. I read it a while ago when I implemented some TURN server/client procedures, and the authors really know what they're talking about!

最后一篇文章很好地介绍了路由器和 NAT 穿越的许多想法。不久前我在实现一些 TURN 服务器/客户端程序时阅读了它,作者真的知道他们在说什么!