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

我已经对没有基本服务器的p2p通信做了一些研究,并且通过了STUN。 从我所读到的,STUN是NAT“打孔”的一种方式,它不需要将对等端口转发连接到。 这是正确的,打孔究竟是什么意思? 如果它不需要端口转发,它似乎非常脆弱,因为它越过防火墙,我不完全理解STUN的作用。 STUN可以用于Java中的p2p程序或其他语言,例如聊天客户端,它通过TCP / UDP端口向没有基本服务器的对等端发送消息,或者不要求用户端口转发?

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

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

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

STUN遍历

为了使两个客户端A和B都在Internet上的防火墙之后进行直接通信,他们必须知道路由器映射。 一般的解决方案是使用STUN服务器来确定它们的端口映射。 机器A将端口X的数据包发送到STUN。 路由器将端口转换为Y,并且STUN服务器看到这个并响应回A告诉他外部端口是什么。 B做同样的事情。 然后,A和B交换他们翻译的端口(通过使用其他一些中央服务器……为简化示例,Skype可能有一个中央登录服务器,其中A和B告诉Skype服务器他们的端口翻译,Skype分别告诉A和B关于端口映射)。 然后,B使用端口Y而不是X向A的公共IP发送数据包。机器A“打孔”其防火墙,允许它从外部端口Y接收数据包。

安全?

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

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

对称NAT和TURN遍历

STUN并不总是有效:一些路由器“表现得很糟糕”。 机器A可能会从端口X发送两个数据包,一个发送到stackoverflow.com,一个发送到facebook.com。 路由器将stackoverflow.com数据包从端口Y和facebook.com数据包FROM端口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向我发送一个数据包,一旦我告诉它映射。 路由器可能已经放弃了映射(路由器必须定期清除旧映射以便为新映射腾出空间,并且最小化安全性尝试)。 我找不到我的参考,我认为它取决于TCP和UDP数据包,但我熟悉的应用程序每隔约60秒或更短时间发送一个保持活动数据包,以确保路由器不会丢弃映射。 一旦路由器丢弃映射并且机器试图发送数据包,数据包将被丢弃(导致数小时的混乱……)。

用品

  • RFC 5389 STUN
  • RFC 5766 TURN
  • 跨网络地址转换器的点对点通信。 B. Ford,et al。

最后一篇文章是对genreal中路由器和NAT遍历的许多想法的一个很好的介绍。 我刚才读到它时实现了一些TURN服务器/客户端程序,作者真的知道他们在谈论什么!