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

2024-03-08

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


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

NAT 穿越解决了路由器将数据包的传出端口号转换为其他内容的问题(例如,您从端口 X 发送请求,路由器将数据包转换为就像从端口 Y 离开一样)。如果路由器是端口转发,则路由器实际上不执行任何转换(端口 X->X)。然而,大多数家庭/公司/等路由器都没有端口转发,因此 NAT 穿越开始发挥作用。看NAT穿越 http://en.wikipedia.org/wiki/NAT_traversal以及不同类型的NATs http://en.wikipedia.org/wiki/Network_address_translation#Methods_of_Port_translation.

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

Secure?

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

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

对称 NAT 和 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 的初衷。看TURN http://en.wikipedia.org/wiki/Traversal_Using_Relays_around_NAT.

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

任何具有网络库支持的语言(Java、C 等),您可以从任意端口发送数据包,都可以使用 STUN 来遍历 NAT(只要它不是对称 NAT 等)。一般来说,一always需要一个中央服务器(在本例中是两个:STUN 和一个login服务器)。这login服务器的使用方式如 Skype 示例中所述;一旦两个客户端知道他们的端口映射,他们必须以某种方式相互通信beforep2p 通信已经开始(参见先有鸡还是先有蛋 http://en.wikipedia.org/wiki/Chicken_or_the_egg)。但是一旦 A 和 B 知道彼此的公网 IP 和 NAT 映射,他们就可以直接通信。

Caveat

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

Articles

  • RFC 8489 眩晕 https://www.rfc-editor.org/rfc/rfc8489
  • RFC 5766 回合 https://www.rfc-editor.org/rfc/rfc5766
  • 跨网络地址转换器的点对点通信。 B.福特等人。 http://www.brynosaurus.com/pub/net/p2pnat/

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

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

什么是 STUN?它是否需要端口转发服务器? 的相关文章

  • Hibernate 4 字节码增强不适用于脏检查优化

    我正在使用 Hibernate 4 3 6 并且我使用了最新的Maven 字节码增强 http vladmihalcea com hibernate 4 bytecode enhancement 使所有实体提高自我肮脏意识 我添加了mave
  • ListView:防止视图回收

    我有一个使用回收视图的 ListView 我试图阻止视图被回收 所以我使用 setHasTransientState android support v4 view ViewCompatJB setHasTransientState Vie
  • APNS(Apple 推送通知服务器)的反馈服务

    我们正在使用Java作为推送通知提供商APNS I我能够将消息发送到APNS但我不知道如何获得该消息的反馈 请帮忙 反馈服务具有类似于用于发送推送通知的接口的二进制接口 您可以通过以下方式访问生产反馈服务feedback push appl
  • 如果主引用指向 null,WeakReference 或 SoftReference 有何不同

    我正在读关于WeakReference https docs oracle com javase 10 docs api java lang ref WeakReference html and SoftReference https do
  • 如何停止使用扫描仪从标准输入读取多行?

    我正在做一个 JAVA 作业 应该处理多行输入 指令显示 输入是从标准输入读取的 给出了示例输入的示例 one 1 two 2 three 3 我不明白上面的示例输入 从标准输入读取 是什么意思 这是我编写的一个测试程序 它可以消除我的困惑
  • Ant 中回显目标描述

  • Apache Commons VFS - 无法解析文件

    VFS 方法无法处理此 URI jboss server temp dir local outgoing配置在jboss beans xml这是决心 C Download jboss eap 5 1 1 server default tmp
  • Java - toString 到 Color

    我一整天都在努力解决这个问题 基本上我做了一个 for 循环 将条目添加到数组列表中 其中一项是 颜色 变量 我已经用过random nextInt为颜色构造函数的红色 绿色和蓝色部分创建新值 我还设置了一个toString方法 这样我就可
  • Java时间转正常格式

    我有 Java 时间1380822000000 我想转换为我可以阅读的内容 import java util Date object Ws1 val a new Date 1380822000000 toString 导致异常 warnin
  • 如何从 Java 中“double”类型的值中删除小数值

    我正在调用一个名为 calculateStampDuty 的方法 它将返回 财产需缴纳的印花税金额 百分比计算有效 很好 并返回正确的值 15000 0 但是 我想显示该值 前端用户只是 15000 所以只想删除小数点和任何前面的值 此后
  • 欧拉项目 45

    我还不是一名熟练的程序员 但我认为这是一个有趣的问题 我想我应该尝试一下 三角形 五边形 六边形 数字由以下生成 公式 三角形 T n n n 1 2 1 3 6 10 15 五边形 P n n 3n 1 2 1 5 12 22 35 六角
  • java 中的 Try-with-resources 和 return 语句

    我想知道是否放一个return里面的声明尝试资源block 防止资源自动关闭 try Connection conn return conn createStatement execute 如果我写这样的东西将会联系被关闭 Oracle 文
  • java数学中的组合“N选择R”?

    java库中是否有内置方法可以为任何N R计算 N选择R 公式 实际上很容易计算N choose K甚至不需要计算阶乘 我们知道 公式为 N choose K is N N K K 因此 公式为 N choose K 1 is N N N
  • Java8 项目上的 SonarQube 给出 jacoco-Exception

    我刚刚下载了最新版本 SonarQube 4 3 然后尝试使用以下命令构建 java 8 项目 mvn clean install mvn sonar sonar 这给了我下面的例外 谷歌搜索 我的印象是这是一个早期的问题 应该已经解决 h
  • SDK尚未初始化,请务必先调用FacebookSdk.sdkInitialize()

    我在实现 Facebook SDK 时遇到此错误 并且我tried https stackoverflow com questions 15490399 error inflating class com facebook widget l
  • 将 PropertyPlaceholderConfigurer 中的所有属性注入到 bean 中

    我有一个PropertyPlaceholderConfigurer加载多个属性文件 我想通过配置 XML 将合并的属性映射注入到 Spring Bean 中 我可以这样做以及如何做 您只需创建一个属性 bean 并将其用于您的Propert
  • 如何在 Java 中创建一个带有连字符的值的静态枚举?

    如何创建如下所示的静态枚举 static enum Test employee id employeeCode 截至目前 我遇到了错误 这对于 Java 来说是不可能的 因为每个项目都必须是有效的标识符 并且有效的 Java 标识符可能不包
  • 动态创建 JSON 对象

    我正在尝试使用以下格式创建 JSON 对象 tableID 1 price 53 payment cash quantity 3 products ID 1 quantity 1 ID 3 quantity 2 我知道如何使用 JSONOb
  • 检查 Java 字符串实例是否可能包含垃圾邮件数据的最简单方法

    我有一个迭代 String 实例的过程 每次迭代对 String 实例执行很少的操作 最后 String 实例被持久化 现在 我想为每次迭代添加一个检查 String 实例是否可能是垃圾邮件的检查 我只需验证 String 实例不是 成人材
  • 如何让JComboBox中的内容居中显示?

    目前我有这个JComboBox 我怎样才能将其中的内容居中 String strs new String 15158133110 15158133124 15158133458 JComboBox com new JComboBox str

随机推荐

  • 使用 nginx 的子目录中的 CakePHP(重写规则?)

    不久前我设法让它工作 但是当我回到我开始的 cakephp 项目时 似乎我最近对 nginx 所做的任何更改 或者可能是最近的更新 都打破了我的重写规则 目前我有 worker processes 1 events worker conne
  • Angular cli 项目中的绝对路径

    如何在 Angular cli 生成的项目中使用绝对路径 所以我有这条路 src gt app gt shared我想写import from shared ffdsdf my module ts 代替 shared ffdsdf my m
  • 将 dynamodb 表复制到 hive 的 pyspark 代码问题:不允许操作

    我正在尝试使用 pyspark 代码从 aws emr 上的 Dynamodb 创建外部配置单元表 当我在 hive 提示符下执行查询时 该查询工作正常 但当我将其作为 pyspark 作业执行时 该查询会失败 代码如下 from pysp
  • 本地开发主机的通配符

    我最近在多个项目之间切换 所有这些都在相同的IP上本地运行 但具有不同的域 实际上它总是 local like foo local bar local等等 我可以继续将它们添加到我的 etc hosts文件 但这不是很干净的方式 这就是为什
  • 我无法在 Android AVD Manager 中创建模拟器

    我正在尝试创建一个 Android 模拟器 当我打开 AVD 管理器并尝试创建一个模拟器时 它一直显示 未选择目标 即使我选择了目标 http bit ly 15vr9fk http bit ly 15vr9fk 面临同样的问题 我检查了A
  • 未收到 Microsoft Graph 更改通知

    我想订阅用户删除 以便每当在 Azure AD 中删除用户时 我们的应用程序都可以做出相应的反应 这是我的订阅请求 const now new Date const threeDaysLater new Date now getTime 3
  • unix fork exec 序列真的像听起来那么昂贵吗?

    我正在读关于fork and exec对于考试 我的书说 每当需要在 UNIX 系统中运行一个新的 不同的 进程时 您都会分叉当前进程 然后是execve 然而 它也说 每当fork被调用时 父进程的整个内存映像被复制到新进程 那么我的问题
  • 是否可以通过在基类中添加新的虚函数来破坏代码?

    是否可以通过简单地向基类添加新的虚函数来改变程序的观察到的行为 我的意思是不必对代码进行其他更改 以下程序打印OK 取消注释虚函数B它将开始打印CRASH include
  • 如何使用 JavaScript 创建电子邮件按钮

    我找不到真正符合我的问题的帖子 所以我们开始 我想在我的网站上实现 通过邮件共享 按钮 因此当您单击该按钮时 假设 Outlook 或 Thunderbird 打开 并为您提供在新邮件中共享网站链接的选项 我不太确定 但我认为我无法仅使用
  • 将带孔的多边形转换为多个简单的无孔多边形

    我正在处理IfcFace http www buildingsmart tech org ifc IFC4 Add2 html schema ifctopologyresource lexical ifcface htm 我得到了一个带孔的
  • Xamarin - 异步数据绑定

    我有以下代码 包含大量图像的页面 通过数据绑定动态加载 base OnAppearing if loaded loaded true BindingContext new GalleryViewModel pCode gCode gUrl
  • __func__ 和 __PRETTY_FUNCTION__ 并不总是扩展

    我有一个日志库 它使用宏来跟踪消息 该宏使用预定义的宏 例如 func and PRETTY FUNCTION 指示消息被记录在哪个函数 方法中 我的日志库的宏定义在我的日志库的主头中 位于任何函数之外 由于某种原因 预处理的代码包含 fu
  • Dynamics CRM 2011 中如何拥有多个 javascript 库

    是的 我正在创建一个方法 将帐户添加到 Dynamics CRM 并使用 Ajax POST 到内置 Web 服务 代码如下 var context GetGlobalContext var serverUrl context getSer
  • 将值类型转换为泛型

    我有一个泛型类 我需要将其限制为仅值类型 int float 等 我有一个基于类型测试调用 Parse 方法的方法 例如 class MyClass
  • 如何连接 MySQL 中的结果集?

    我想用逗号作为分隔符字符串来连接 MySQL 中集合中返回的结果 例如 返回的集合包含 COLUMN X john jerry maria joseph gugla 我希望收到的结果为 COLUMN X concat john jerry
  • 静态构造函数和异常

    如果静态构造函数抛出异常且未处理 会发生什么情况 它会一直保留到应用程序域处于活动状态吗 静态构造函数中未处理的异常将被包装在TypeInitializationException 如果您使用的是 NET 2 或更高版本 则未处理的异常将终
  • 错误:ENOENT:没有这样的文件或目录,scandir './commands/'

    当我想使用不和谐时 我收到此错误输出 Error ENOENT no such file or directory scandir commands 90m at Object readdirSync fs js 1021 3 39m at
  • 如果存在重复的模块名称,Python 指定从哪个模块导入?

    相关 从相对路径导入模块 https stackoverflow com questions 279237 import a module from a relative path dirA A py B py dirB B py A py
  • .NET MVC 5 中的 Angular 6 应用程序,角度路由不起作用

    我已将 Angular 6 应用程序嵌入到现有的 NET MVC 5 应用程序中 我在 MVC 应用程序 RouteConfig cs 中添加了一条指向 Home Index 的后备路由 因此 未知 路由将传递到 Angular 应用程序的
  • 什么是 STUN?它是否需要端口转发服务器?

    我对没有基础服务器的 p2p 通信进行了一些研究 并通过了 STUN 据我所知 STUN 是 NAT 打孔 的一种方式 不需要对等方进行端口转发即可连接 这是正确的吗 打孔到底是什么意思 这一切看起来都很脆弱 因为如果不需要端口转发 它就会