什么是STUN,它需要一个端口转发服务器吗



我对没有基本服务器的p2p通信进行了一些研究,并介绍了STUN。从我读到的内容来看,STUN是一种NAT"打孔"的方式,它不需要将对等端转发到端口即可连接。这正确吗?打孔到底意味着什么?如果不需要端口转发,这一切似乎都很容易通过防火墙,我也不完全理解STUN的作用。STUN是否可以用于Java或其他语言的p2p程序中,例如聊天客户端,该客户端通过TCP/UDP端口向对等方发送消息,而无需基本服务器或无需用户端口转发?

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

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

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

STUN遍历

为了让两个客户端(A和B都在互联网防火墙后面)直接通信,他们必须知道路由器映射。一般的解决方案是使用STUN服务器来确定它们的端口映射。机器A从端口X向STUN发送一个数据包。路由器将端口转换为Y,STUN服务器看到了这一点,并回复A,告诉他外部端口是什么。B也这么做。然后,A和B交换他们的翻译端口(通过使用其他中央服务器……为了简化示例,Skype可能有一个中央登录服务器,其中A和B告诉Skype服务器他们的端口翻译,Skype告诉A和B端口映射)。然后,B使用端口Y而不是X向a的公共IP发送数据包;穿孔的";它的防火墙,允许它从外部端口Y接收数据包。

安全吗

你提到了安全:打孔会让网络面临安全违规吗?潜在地我还没有研究过这个主题,但考虑一下全锥NAT。一旦映射完成,任何外部机器都可以向机器a的路由器发送数据包,而a会得到这些数据包,即使a从未向恶意机器Z发送过数据包。当然,机器Z必须以某种方式发现映射。在维基百科的一些文章中,图表只显示了全锥NAT存在此漏洞,但不要相信我的话。从使用打孔的应用程序数量(Skype、xbox-live…)来看,除了路由器防火墙措施外,网络似乎还依赖应用程序和系统级防火墙保护。

下面福特的文章简要提到了安全性:;与它的名字可能暗示的相反,打孔并不会损害私有网络的安全"网络似乎更依赖于系统级防火墙,而不是路由器防火墙。

对称NAT和TURN遍历

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

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

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

洞穴

虽然我不可能列出所有NAT穿越的注意事项,但有一个重要的概念是保持活跃:一旦路由器进行了端口映射,它会持续多久?假设我连接到STUN服务器,然后等10分钟,等我告诉B映射后,B再给我发一个数据包。路由器可能已经放弃了映射(路由器必须定期清除旧映射,为新映射腾出空间,并尽可能减少安全尝试)。我找不到我的参考,我认为它根据TCP和UDP数据包的不同而有所不同,但我熟悉的应用程序每隔约60秒或更短时间发送一个保持活动的数据包,以确保路由器不会丢失映射。一旦路由器丢弃映射和试图发送数据包的机器,数据包就会被丢弃(导致我数小时的困惑…)。

文章

  • RFC 8489 STUN
  • RFC 5766转
  • 通过网络地址转换器进行对等通信。B.Ford等人

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

最新更新