什么是 STUN,它是否需要端口转发服务器?
我对没有基本服务器的p2p通信进行了一些研究,并获得了STUN。根据我所读到的内容,STUN是NAT“打孔”的一种方式,不需要对等体被端口转发即可连接。这是正确的吗,打孔到底是什么意思?如果不需要端口转发,那么它似乎都非常容易受到攻击,因为它会通过防火墙,我不完全了解STUN的作用。STUN是否可以在Java或其他语言的p2p程序中使用,例如聊天客户端,该客户端通过TCP / UDP端口将消息发送到对等体,而无需基本服务器或不需要用户端口转发?
我对没有基本服务器的p2p通信进行了一些研究,并获得了STUN。根据我所读到的内容,STUN是NAT“打孔”的一种方式,不需要对等体被端口转发即可连接。这是正确的吗,打孔到底是什么意思?如果不需要端口转发,那么它似乎都非常容易受到攻击,因为它会通过防火墙,我不完全了解STUN的作用。STUN是否可以在Java或其他语言的p2p程序中使用,例如聊天客户端,该客户端通过TCP / UDP端口将消息发送到对等体,而无需基本服务器或不需要用户端口转发?
考虑两台想要相互通信的机器的任务。如果两台计算机直接连接到公共 Internet(而不是路由器后面),则两台计算机只需将数据包来回发送到彼此的公共 IP。通常,计算机位于一个或多个路由器后面。为了简化问题,我们假设只有一个级别的路由器。
NAT遍历解决了路由器将数据包的传出端口号转换为其他内容的问题(例如,您从端口X发送请求,路由器转换数据包以充当从端口Y离开的情况)。如果路由器是端口转发的,则路由器实际上不会执行任何转换(端口 X->X)。然而,大多数家庭/企业/等路由器不是端口转发的,因此NAT遍历开始发挥作用。请参阅 NAT 遍历和不同类型的 NAT。
考虑路由器的防火墙,它执行上述文章中的任何非端口转发转换(例如全锥)。如果路由器接收到端口X的一些数据包,但路由器没有从端口Y发送任何数据包,它会丢弃数据包(毕竟,数据包指的是谁?路由器不知道!只有当某些专用计算机发送数据包并且路由器进行转换以将端口 X 从该专用计算机映射到外部端口 Y 时,才会将外部数据包转发到端口 Y。
为了使两个客户端(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发送过数据包。一些维基百科文章,图表只显示了具有此漏洞的全锥形NAT,但不要相信我的话。从使用打孔(Skype,xbox live等)的应用程序数量来看,除了路由器防火墙措施外,网络似乎还依赖于应用程序和系统级防火墙保护。
福特下面的文章简要提到了安全性:“与它的名字可能暗示的相反,打孔不会损害专用网络的安全性。网络似乎更依赖系统级防火墙而不是路由器防火墙。
STUN并不总是有效:一些路由器“表现不佳”。计算机 A 可能从端口 X 发送两个数据包,一个发送到 stackoverflow.com,另一个发送到 facebook.com。路由器将 stackoverflow.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,C等),您可以从任意端口发送数据包,可以使用STUN遍历NAT(只要它不是对称NAT等)。通常,人们总是需要一个中央服务器(在这种情况下,两个:STUN和登录服务器)。登录服务器的使用如 Skype 示例中所述。一旦两个客户端知道他们的端口映射,他们必须在p2p通信开始之前以某种方式相互通信(参见鸡还是先有蛋)。但是,一旦A和B知道彼此的公共IP和NAT映射,他们就可以直接通信。
虽然我不可能列出所有的NAT遍历警告,但一个重要的概念是保持活动状态:一旦路由器进行了端口映射,它将持续多长时间?假设我连接到STUN服务器,然后等待10分钟,以便在我告诉映射后B向我发送数据包。路由器可能会放弃映射(路由器必须定期清除旧映射,以便为新映射腾出空间,并尽量减少安全尝试)。我找不到我的引用,我认为它因TCP与UDP数据包而异,但我熟悉的应用程序每约60秒或更短时间发送一个保持活动状态的数据包,以确保路由器不会丢弃映射。一旦路由器删除映射并且计算机尝试发送数据包,数据包将被丢弃(导致我数小时的混乱...)。
最后一篇文章很好地介绍了路由器和NAT遍历在流派中的许多想法。不久前,当我实现一些TURN服务器/客户端程序时,我读了它,作者真的知道他们在说什么!