在现实Internet网络环境中,大多数计算机主机都位于防火墙或NAT之后,只有少部分主机能够直接接入Internet。很多时候,我们希望网络中的两台主机能够直接进行通信(即所谓的P2P通信),而不需要其它公共服务器的中转。由于主机可能位于防火墙或NAT之后,在进行P2P通信之前,我们需要进行检测以确认它们之间能否进行P2P通信以及如何通信。这种技术通常被称为NAT穿透(NAT Traversal)。最常见的NAT穿透是基于UDP的技术(如下面的RFC3489/STUN),也有基于TCP的穿透技术。NAT穿透技术最重要的是识别目标主机的NAT类型,这也是本文所要介绍的内容。

在RFC3489/STUN[1]中,基于UDP的NAT穿透技术把主机划分为如下七种NAT类型:UDP Blocked、Open Internet、Symmetric Firewall、Full Cone NAT、Restricted Cone NAT、Port Restricted Cone NAT、Symmetric NAT。具体解释如下:

(1)Open Internet:主机具有公网IP,允许主动发起和被动响应两种方式的UDP通信。

(2)UDP Blocked:位于防火墙之后,并且防火墙阻止了UDP通信。

(3)Symmetric Firewall:主机具有公网IP,但位于防火墙之后,且防火墙阻止了外部主机的主动UDP通信。

(4)Full Cone NAT:当内网主机创建一个UDP socket并通过它第一次向外发送UDP数据包时,NAT会为之分配一个固定的公网{IP:端口}。此后,通过这个socket发送的任何UDP数据包都是通过这个公网{IP:端口}发送出去的;同时,任何外部主机都可以使用这个公网{IP:端口}向该socket发送UDP数据包。即是说,NAT维护了一个映射表,内网主机的内网{IP:端口}与公网{IP:端口}是一一对应的关系。一旦这个映射关系建立起来(内部主机向某一外部主机发送一次数据即可),任何外部主机就可以直接向NAT内的这台主机发起UDP通信了,此时NAT透明化了。

(5)Restricted Cone NAT:当内网主机创建一个UDP socket并通过它第一次向外发送UDP数据包时,NAT会为之分配一个公网{IP:端口}。此后,通过这个socket向外发送的任何UDP数据包都是通过这个公网{IP:端口}发送出去的;而任何收到过从这个socket发送来的数据的外部主机(由IP标识),都可以通过这个公网{IP:端口}向该socket发送UDP数据包。即是说,NAT维护了一个内网{IP:端口}到公网{IP:端口}的映射,还维护了一个{外部主机IP, 公网{IP:端口}}到内网{IP:端口}的映射。因此,要想外部主机能够主动向该内部主机发起通信,必须先由该内部主机向这个外部发起一次通信。

(6)Port Restricted Cone NAT:当内网主机创建一个UDP socket并通过它第一次向外发送UDP数据包时,NAT会为之分配一个公网{IP:端口}。此后,通过这个socket向外部发送的任何UDP数据包都是通过这个公网{IP:端口}发送出去的;一旦外部主机在{IP:端口}上收到过从这个socket发送来的数据后,都可以通过这个外部主机{IP:端口}向该socket发送UDP数据包。即是说,NAT维护了一个从内网{IP:端口}到公网{IP:端口}的映射,还维护了一个从{外部主机{IP:端口}, 公网{IP:端口}}到内网{IP:端口}的映射。

(7)Symmetrict NAT:当内网主机创建一个UDP socket并通过它第一次向外部主机1发送UDP数据包时,NAT为其分配一个公网{IP1:端口1},以后内网主机发送给外部主机1的所有UDP数据包都是通过公网{IP1:端口1}发送的;当内网主机通过这个socket向外部主机2发送UDP数据包时,NAT为其分配一个公网{IP2:端口2},以后内网主机发送给外部主机2的所有UDP数据包都是通过公网{IP2:端口2}发送的。公网{IP1:端口1}和公网{IP2:端口2}一定不会完全相同(即要么IP不同,要么端口不同,或者都不同)。这种情况下,外部主机只能在接收到内网主机发来的数据时,才能向内网主机回送数据。

RFC3489/STUN协议过程

STUN协议定义了三类测试过程来检测NAT类型,如下所述:

Test1:STUN Client通过端口{IP-c1:Port-c1}向STUN Server{IP-s1:Port-s1}发送一个Binding Request(没有设置任何属性)。STUN Server收到该请求后,通过端口{IP-s1:Port-s1}把它所看到的STUN Client的IP和端口{IP-m1,Port-m1}作为Binding Response的内容回送给STUN Client。

Test1#2:STUN Client通过端口{IP-c1:Port-c1}向STUN Server{IP-s2:Port-s2}发送一个Binding Request(没有设置任何属性)。STUN Server收到该请求后,通过端口{IP-s2:Port-s2}把它所看到的STUN Client的IP和端口{IP-m1#2,Port-m1#2}作为Binding Response的内容回送给STUN Client。

Test2:STUN Client通过端口{IP-c1:Port-c1}向STUN Server{IP-s1:Port-s1}发送一个Binding Request(设置了Change IP和Change Port属性)。STUN Server收到该请求后,通过端口{IP-s2:Port-s2}把它所看到的STUN Client的IP和端口{IP-m2,Port-m2}作为Binding Response的内容回送给STUN Client。

Test3:STUN Client通过端口{IP-c1:Port-c1}向STUN Server{IP-s1:Port-s1}发送一个Binding Request(设置了Change Port属性)。STUN Server收到该请求后,通过端口{IP-s1:Port-s2}把它所看到的STUN Client的IP和端口{IP-m3,Port-m3}作为Binding Response的内容回送给STUN Client。

NAT类型检测过程如下(在RFC3489中或者在Wiki上都可以找到流程图):

1. 进行Test1。如果STUN Client不能够收到STUN Server的应答(重复多次确认),那么说明该STUN Client是UDP Blocked类型(也有可能是STUN Server不可到达,这里不考虑这种情形);否则,STUN Client把返回的{IP-m1,Port-m1}和本地的{IP-c1:Port-c1}进行比较(只需要比较IP即可),如果相同,说明本机直接连接于公网,否则本机位于NAT之后,但还需要进一步判断具体类型。

1.1. 如果本机直接连接于公网,进行Test2。如果STUN Client不能够收到STUN Server的应答(重复多次确认),那么说明该STUN Client是Symmetric Firewall类型;否则,该STUN Client是Open Internet类型。

1.2. 如果本机位于NAT之后,进行Test2。如果STUN Client能够收到STUN Server的应答,那么说明该STUN Client是Full Cone NAT;否则,需要进一步进行测试。

1.2.1. 进行Test1#2。STUN Client比较IP-m1和IP-m1#2是否相同,如果不相同,那么说明该STUN Client是Symmetric NAT类型;否则,需要进一步进行测试。

1.2.1.1 进行Test3。如果STUN Client能够收到STUN Server的应答,那么说明该STUN Client是Restricted Cone NAT类型;否则,该STUN Client是Port Restricted Cone NAT类型。

一些说明:

1. 只需要进行Test2,即可判断出是否为Open Internet或Full Cone Nat类型。

STUN实现

1.STUN Client and Server

library()

这个库实现了RFC3489中的STUN协议。其中,Client程序输出结果意义如下:

(1)"Open"表示这里的Open Internet

(2)"Independent Mapping, Independent Filter"表示这里的Full Cone NAT

(3)"Independedt Mapping, Address Dependendent Filter"表示这里的Restricted

Core NAT

(4)"Indepndent Mapping, Port Dependent Filter"表示这里的Port Restricted Core

NAT

(5)"Dependent Mapping"表示这里的Symmetric NAT

(6)"Firewall"表示这里的Symmetric Firewall

(7)"Blocked or could not reach STUN server"表示这里的UDP Blocked

2. reTurn ()

实现了RFC5389中的STUN协议和TURN协议。

网上一些可用STUN Server(注意:STUN协议指定默认端口为3478)

stun01.sipphone.com

stun.iptel.org

stun.softjoys.com

stun.xten.com(这个STUN Server的实现好像有问题,测试结果与前面三个不相同)

注解

[1] RFC3489中的STUN协议(Simple Traversal of UDP Through

NATs)是一个完整的NAT穿透方案,但其修订版本(RFC5389)把STUN协议(Session Traversal Utilities

for

NAT)定位于为穿透NAT提供工具,并不提供一个完整的解决方案。此外,RFC3489只提供了UDP的NAT穿透,而RFC5389还支持TCP的穿

透)。

Reference

1.

2.

阅读(2418) | 评论(0) | 转发(0) |

Linux怎么检测nat类型,STUN(RFC3489)的NAT类型检测方法相关推荐

  1. 【笔记】P2P - 1 路由NAT(原理、四种类型、问题),P2P(概念、兼容NAT方案:ACL、upnp中间件、“打洞”、Relay)

    参考 路由器四种NAT - https://blog.csdn.net/wgl307293845/article/details/120450626 P2P介绍(一)NAT详解 ⭐️ - http:/ ...

  2. Linux下的设备管理、磁盘分区及分区类型的修改

    Linux下的设备管理.磁盘分区及分区类型的修改 https://blog.csdn.net/yyyxxxs/article/details/80174164 一.设备管理 1.查看命令 fdisk ...

  3. Win7下的Linux通过Nat的VMnet8下的NAT方式进行上网

    [实践Ok]Win7下的Vmware下的Linux通过Nat的Vmware8(VMnet8)下NAT方式进行配置后SecureCRT能连接上并可以上网的配置方法 发表于2013-08-16 10:06 ...

  4. Types of NAT and How to determine the NAT Type(NAT的类型和如何确定NAT类型)

      我将做几篇关于NAT(网络地址转换)的文章,讨论它们的分类以及如何在Linux机器上创建一个NAT.这篇文章将介绍NAT的类型.   一般来说,NAT是用来允许私人IP与互联网对话的.它也有一定的 ...

  5. 错误类型、混淆矩阵及目标检测常用评价指标

    目标检测常用评价指标 本文主要参考陈恺大佬在B站商汤账号的介绍mmdetection的视频. 检测结果的正确/错误类型 真阳性(Ture Positive):算法检测到了某类物体(Positive), ...

  6. php变量有三种不同的作用域,PHP中变量类型与转换,变量的检测以及变量的作用域学习--2018年4月13日12时03分...

    今天主要讲述了变量类型与转换,变量的检测,变量的作用域. 一.变量的类型与转换 在PHP中有八种变量类型,分别是: 标量中的整形(int),浮点型(float),字符串(string),布尔型(boo ...

  7. linux的shell类型_Linux中有哪些不同类型的Shell?

    linux的shell类型 Shells are an important part of any Linux user session. We are provided several differ ...

  8. linux列出一个目录及其子目录下面的某种类型的文件

    linux列出一个目录及其子目录下面的某种类型的文件 作者:smarteng ⁄ 时间:2009年07月09日 ⁄ 分类: Linux命令 ⁄ 评论:0 怎么样把,一个目录及其所有的子目录下面的某种类 ...

  9. Linux窗口和Win命令窗口查看mysql bit类型的值

    Linux窗口和Win命令窗口查看mysql bit类型的值 在很多情况下(例如数据量大.磁盘空间有限活节约空间),我们需要压缩存储空间,mysql的数据也一样,当我们存储的数据为1和0时,就可以采用 ...

最新文章

  1. python画图程序飞机_Python海龟画图工具绘制叮当猫程序
  2. [KIWI syslog]Install document
  3. 开发日记 20200129 新年这几天的总结
  4. Nuget常用命令(转)
  5. HDFS的API操作-获取FileSystem方式
  6. python安装caffe_Caffe安装笔记二:Caffe安装过程
  7. 根据经纬度求最近点的三种解法java实现
  8. 兼容彩虹支付系统商户登录模板(彩虹系统版本)
  9. 九九乘法表Python+Java
  10. 2017.3.12 lzy 测试
  11. 一个单片机搞定USB电阻式触摸屏,完美解决飞点问题。
  12. 12.01 晚 心情 阴雨 既然能力支撑不起自己的野心就先沉下心来努力学习好让有一天重新出现在江湖大放光芒...
  13. 检查虚拟机是否使用virtio
  14. java新手笔记7 找最小、最大、排序
  15. php聊天系统文档,聊天后台管理系统接口文档
  16. Python打包应用程序
  17. 从源码角度分析android事件分发处理机制
  18. XWindow与GtkWindow的转换
  19. 计算机性能怎么测试软件,如何测试电脑性能|检测电脑性能的方法
  20. eclipse工具按键翻译

热门文章

  1. Linux下Java程序不识别宋体
  2. Hyperledger技术简介
  3. extjs 修改官方主题
  4. 用户案例:网络设备厂商选择Vdoo平台强化其旗舰路由器的安全性
  5. python飞机场安检功能
  6. github pull request那些事
  7. 【CCTC 2017】云计算核心技术与实践专场:剖析云计算关键技术,探寻金融、气象行业转型升级之路...
  8. 基于距离浓度的人工免疫算法(DCAIA)求函数最值(python实现)
  9. 怎样在Word 2010文档中选择纵向或横向
  10. 机器学习(六)结果分析(过拟合、欠拟合)