STUN打洞学习笔记

STUN打洞学习笔记

学习起因

由于处理GB28181问题时,设计到NAT网络的问题,领导就把6月份的能力提升任务设定为SIP的UDP打洞。
不过我们使用的国标服务器就是公网服务器,每台服务器均有自己的公网IP地址,好像没有打洞的问题,但是工作这么多年,确实有必要针对于NAT网络相关的知识点做一个总结。

什么叫打洞?

摘录自(随便点的链接):http://www.cppblog.com/lapcca/archive/2010/01/28/106663.html

确切地说是穿透NAT,一般使用UDP协议,TCP协议也可以穿透,只是好像没有UDP成功率高。
如果是一般情况,使用STUN协议.
除了要通信的两个端点之外,还有一个有公网IP的一个服务器 STUN server。
一个端点穿过防火墙,发个消息给STUN server,STUN server收到这个包之后 就可以知道该端点通过防火墙映射后的公网地址。
同样道理,STUN sever可以得到另外一个端点的通过它的防火墙映射后的公网地址。
STUN server把得到的这两个地址发给两个端点。
端点得到对方端点的公网地址后,就可以给对方端点发消息。相互就可以通信。
通俗的说,一个端点发一个UDP消息出去之后,就把自己的墙打了一个洞;另外一个端点也把它的墙打了一个洞。然后双方都可以向对方的洞发数据,进行通信 。

UDP打洞和我理解的差不多,作者说的也够直白的了,
笔者也边学边写,这篇帖子的说法是否准确,我也无法辨知。
不过我们就从这篇看起来不太专业的帖子慢慢探讨这个话题。

作者提出一个STUN的概念,STUN是什么概念?

STUN是什么?

摘录自(百度百科):https://baike.baidu.com/item/stun/3131387?fr=aladdin

STUN(Session Traversal Utilities for NAT,NAT会话穿越应用程序)是一种网络协议,它允许位于NAT(或多重NAT)后的客户端找出自己的公网地址,查出自己位于哪种类型的NAT之后以及NAT为某一个本地端口所绑定的Internet端端口。这些信息被用来在两个同时处于NAT路由器之后的主机之间创建UDP通信。该协议由RFC 5389定义。

STUN提供一种服务,可以查询自己的公网地址。
这句话引出了一个比较敏感的概念NAT
相关标准: RFC 5389 Session Traversal Utilities for NAT (STUN)

NAT是什么?

摘录自(百度百科):https://baike.baidu.com/item/nat/320024?fr=aladdin

NAT(Network Address Translation),是指网络地址转换,1994年提出的。
当在专用网内部的一些主机本来已经分配到了本地IP地址(即仅在本专用网内使用的专用地址),但又想和因特网上的主机通信(并不需要加密)时,可使用NAT方法。
这种方法需要在专用网(私网IP)连接到因特网(公网IP)的路由器上安装NAT软件。装有NAT软件的路由器叫做NAT路由器,它至少有一个有效的外部全球IP地址(公网IP地址)。这样,所有使用本地地址(私网IP地址)的主机在和外界通信时,都要在NAT路由器上将其本地地址转换成全球IP地址,才能和因特网连接。
另外,这种通过使用少量的全球IP地址(公网IP地址)代表较多的私有IP地址的方式,将有助于减缓可用的IP地址空间的枯竭。在RFC 2663中有对NAT的说明。

NAT就是内网映射到公网上,就是进行地址转换

相关标准: RFC 2663 IP Network Address Translator (NAT) Terminology and Considerations

NAT类型

摘录自(这篇帖子不错):https://blog.csdn.net/wgl307293845/article/details/120450626

NAT分类
一般NAT可以分为四种类型

1.Full Cone NAT(完全圆锥型NAT)
内网主机建立一个UDP socket(LocalIP:LocalPort) 第一次使用这个socket给外部主机发送数据时NAT会给其分配一个公网(PublicIP:PublicPort),以后用这个socket向外面任何主机发送数据都将使用这对(PublicIP:PublicPort)。此外,任何外部主机只要知道这个(PublicIP:PublicPort)就可以发送数据给(PublicIP:PublicPort),内网的主机就能收到这个数据包

2.Restricted Cone NAT(地址限制圆锥型NAT)
内网主机建立一个UDP socket(LocalIP:LocalPort) 第一次使用这个socket给外部主机发送数据时NAT会给其分配一个公网(PublicIP:PublicPort),以后用这个socket向外面任何主机发送数据都将使用这对(PublicIP:PublicPort)。此外,如果任何外部主机想要发送数据给这个内网主机,只要知道这个(PublicIP:PublicPort)并且内网主机之前用这个socket曾向这个外部主机IP发送过数据。只要满足这两个条件,这个外部主机就可以用自己的(IP,任何端口)发送数据给(PublicIP:PublicPort),内网的主机就能收到这个数据包

3.Port Restricted Cone NAT(端口限制圆锥型NAT)
内网主机建立一个UDP socket(LocalIP:LocalPort) 第一次使用这个socket给外部主机发送数据时NAT会给其分配一个公网(PublicIP:PublicPort),以后用这个socket向外面任何主机发送数据都将使用这对(PublicIP:PublicPort)。此外,如果任何外部主机想要发送数据给这个内网主机,只要知道这个(PublicIP:PublicPort)并且内网主机之前用这个socket曾向这个外部主机(IP,Port)发送过数据。只要满足这两个条件,这个外部主机就可以用自己的(IP,Port)发送数据给(PublicIP:PublicPort),内网的主机就能收到这个数据包

4.Symmetric NAT(对称型NAT)
内网主机建立一个UDP socket(LocalIP,LocalPort),当用这个socket第一次发数据给外部主机1时,NAT为其映射一个(PublicIP-1,Port-1),以后内网主机发送给外部主机1的所有数据都是用这个(PublicIP-1,Port-1),如果内网主机同时用这个socket给外部主机2发送数据,第一次发送时,NAT会为其分配一个(PublicIP-2,Port-2), 以后内网主机发送给外部主机2的所有数据都是用这个(PublicIP-2,Port-2).如果NAT有多于一个公网IP,则PublicIP-1和PublicIP-2可能不同,如果NAT只有一个公网IP,则Port-1和Port-2肯定不同,也就是说一定不能是PublicIP-1等于 PublicIP-2且Port-1等于Port-2。此外,如果任何外部主机想要发送数据给这个内网主机,那么它首先应该收到内网主机发给他的数据,然后才能往回发送,否则即使他知道内网主机的一个(PublicIP,Port)也不能发送数据给内网主机,这种NAT无法实现UDP-P2P通信。

从上面也描述也可以看出,安全性系数, 对称型 > 端口受限锥型 > 受限锥型 > 全锥型

说的也是这个理儿,但是不配图有点过分,我也尝试解释一下:

完全圆锥型NAT(Full Cone NAT)

内网主机同一个内网IP和端口映射出来的公网IP和端口,任何公网主机向映射的公网IP和端口发送数据包,数据包就可以到达内网主机。
在这里插入图片描述

地址限制圆锥型NAT(Restricted Cone NAT)

内网主机同一个内网IP和端口映射出来的公网IP和端口,只要内网主机发过数据包给公网主机,这个公网主机就可以向映射的公网IP和端口发送数据包,数据包就可以到达内网主机。

在这里插入图片描述

端口限制圆锥型NAT(Port Restricted Cone NAT)

内网主机同一个内网IP和端口映射出来的公网IP和端口,只要内网主机发过数据包到给公网主机的特定端口,这个公网主机就可以通过特定端口向映射的公网IP和端口发送数据包,数据包就可以到达内网主机。

在这里插入图片描述

对称型NAT(Symmetric NAT)

内网主机给不同的公网主机和端口发送数据包,映射出来的公网IP和端口不一样,同时只有内网主机发过数据包到给公网主机的特定端口,这个公网主机才可以通过特定端口特定端口所映射的公网IP和端口发送数据包,数据包才可以到达内网主机。

在这里插入图片描述

STUN的功能

摘录自:https://blog.csdn.net/wyl1987527/article/details/80188001

STUN主要有3个功能
(1)获取经过NAT转换后的地址和端口
服务器记录接收到的UDP包的发起地址和端口。
(2)检测是否位于NAT后面
Server 在收到client 发送的UDP包以后,Server 将接收该包的地址和端口利用UDP再传回给client,client把Server发送过来的地址和端口信息与本机的ip地址和端口进行比较,如果不同,说明在NAT后面;如果相同就说明client位于NAT前面,client也是公网。
(3)检测NAT的类型
这个主要发送响应的时候使用不同IP地址和端口或者改变端口等等。这个检测是对NAT一般情况下有效,但是对防火墙就无能为力了,因为防火墙可能不会打开UDP端口。

STUN的NAT类型判断流程

摘录自:https://segmentfault.com/a/1190000008056434

STUN是RFC3489规定的一种NAT穿透方式,它采用辅助的方法探测NAT的IP和端口。STUN的探测过程需要有一个公网IP的STUN server,在NAT后面的UAC必须和此server配合,互相之间发送若干个UDP数据包。UDP包中包含有UAC需要了解的信息,比如NAT外网IP,PORT等等。UAC通过是否得到这个UDP包和包中的数据判断自己的NAT类型。
NAT的探测过程
假设有如下UAC(B),NAT(A),SERVER(C),UAC的IP为IPB,NAT的IP为IPA ,SERVER的IP为IPC1 、IPC2。
STEP1
B向C的IPC1的port1端口发送一个UDP包。C收到这个包后,会把它收到包的源IP和port写到UDP包中,然后把此包通过IPC1和port1发还给B。这个IP和port也就是NAT的外网IP和port,也就是说你在STEP1中就得到了NAT的外网IP。
如果向一个STUN服务器发送数据包后,没有收到STUN的任何回应包,那只有两种可能:1、STUN服务器不存在,或者弄错了port;2、NAT设备拒绝一切UDP包从外部向内部通过(不支持cone NAT)。
当B收到此UDP后,把此UDP中的IP和自己的IP做比较,如果是一样的,就说明自己是在公网,下步NAT将去探测防火墙类型。如果不一样,说明有NAT的存在,系统进行STEP2的操作。
STEP2
B向C的IPC1发送一个UDP包,请求C通过另外一个IPC2和PORT(不同与SETP1的IPC1)向B返回一个UDP数据包(server两个IP是为了检测cone NAT的类型)。
如果B收到了这个数据包,说明NAT来者不拒,不对数据包进行任何过滤,这也就是STUN标准中的full cone NAT。遗憾的是,full cone nat太少了,这也意味着能收到这个数据包的可能性不大。如果没收到,那么系统进行STEP3的操作。
STEP3
B向C的IPC2的port2发送一个数据包,C收到数据包后,把它收到包的源IP和port写到UDP包中,然后通过自己的IPC2和port2把此包发还给B。
和step1一样,B肯定能收到这个回应UDP包。此包中的port是我们最关心的数据。如果这个port和step1中的port一样,那么可以肯定这个NAT是个CONE NAT,否则是对称NAT。道理很简单:根据对称NAT的规则,当目的地址的IP和port有任何一个改变,那么NAT都会重新分配一个port使用,而在step3中,和step1对应,我们改变了IP和port。因此,如果是对称NAT,那这两个port肯定是不同的。
如果到此步的时候PORT是不同的,那么你的STUN已经死了。如果相同,那么只剩下了restrict cone 和port restrict cone,系统用step4探测是是哪一种。
STEP4
B向C的IPC2的一个端口PD发送一个数据请求包,要求C用IPC2和不同于PD的port返回一个数据包给B。
如果B收到了,那也就意味着只要IP相同,即使port不同,NAT也允许UDP包通过,显然这是restrict cone NAT。如果没收到,没别的好说,port restrict NAT。

相关标准: RFC 3489 STUN - Simple Traversal of User Datagram Protocol (UDP) Through Network Address Translators (NATs)

摘录自:https://blog.csdn.net/wyl1987527/article/details/80188001

在这里插入图片描述
摘录的图片不清楚,我也是放大好几倍,想通过图片搞清楚有点难。
先抓包看看再说

STUN服务程序(coturn)

流程挺复杂的,那么有没有现成stun服务供我们用呢?
可定有啊,coturn

摘录自:https://github.com/coturn/coturn

This project evolved from rfc5766-turn-server project (https://code.google.com/p/rfc5766-turn-server/). There are many new advanced TURN specs which are going far beyond the original RFC 5766 document. This project takes the code of rfc5766-turn-server as the starter, and adds new advanced features to it.

相关标准: RFC 5766 Traversal Using Relays around NAT (TURN): Relay Extensions to Session Traversal Utilities for NAT (STUN)

自己部署了coturn,但是好像不能用,不用能用原因应该是我的服务器只有一个公网IP,不能够完整的走完测试流程。

详情可见:https://blog.csdn.net/yjkhtddx/article/details/110117862
也是一把辛酸泪啊,不提了。

公共STUN服务

摘录自:http://www.freeswitch.org.cn/2012/01/11/gong-yong-stun-fu-wu-qi-lie-biao.html

Public STUN servers

provserver.televolution.net
sip1.lakedestiny.cordiaip.com
stun1.voiceeclipse.net
stun01.sipphone.com
stun.callwithus.com
stun.counterpath.net
stun.ekiga.net (alias for stun01.sipphone.com)
stun.ideasip.com (no XOR_MAPPED_ADDRESS support)
stun.internetcalls.com
stun.ipns.com
stun.noc.ams-ix.net
stun.phonepower.com
stun.phoneserve.com
stun.rnktel.com
stun.softjoys.com (no DNS SRV record) (no XOR_MAPPED_ADDRESS support)
stunserver.org see their usage policy
stun.sipgate.net
stun.sipgate.net:10000
stun.voip.aebc.com
stun.voipbuster.com (no DNS SRV record) (no XOR_MAPPED_ADDRESS support)
stun.voxalot.com
stun.voxgratia.org (no DNS SRV record) (no XOR_MAPPED_ADDRESS support)
stun.xten.com
numb.viagenie.ca (http://numb.viagenie.ca) (XOR_MAPPED_ADDRESS only with rfc3489bis magic number in transaction ID)
stun.ipshka.com inside UA-IX zone russsian explanation at http://www.ipshka.com/main/help/hlp_stun.php

贼多,先用别人的。

STUN客户端

找了一个,主要是星星多,看着也简单,(确实也挺简单)
https://github.com/ccding/go-stun
在这里插入图片描述

可以看到,我自己的电脑都是对称NAT,自己这边就没法打洞,还学个蛋蛋。
淡定,在现有条件下抓个包分析一下

抓包分析

wireshark分析抓包

wirshark配置

由于stun有重发机制,得给ID调出来,方便分析
在这里插入图片描述

抓包结果

在这里插入图片描述
抓包结果下载 http://120.53.223.230:8084/temp/stun.pcap
笔者自己私房钱偷偷整的服务器,手下留情,请勿攻击。

TEST I

第一步:
在这里插入图片描述

TEST II

在这里插入图片描述

分析

看抓包也是一头雾水,上面摘录的文章不好使,看着费劲,换一个帖子;

摘录自:https://www.csdn.net/tags/MtjacgysNzM3OTYtYmxvZwO0O0OO0O0O.html

<----------------------------------------------------------------------------------
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。
<----------------------------------------------------------------------------------

分析结果


192.168.1.42:52971 → 217.10.68.152:10000 发送Binding请求
217.10.68.152:10000 → 192.168.1.42:52971 接受Binding响应
告知客户端:服务接收的Binding请求来自:117.158.134.217:49434
告知客户端:服务器的另外一个服务地址为:217.116.122.136:10001
客户端发现自己的192.168.1.42和117.158.134.217的IP不一致,
说明自己在NAT后面。


192.168.1.42:52971 → 217.10.68.152:10000 发送Binding请求,
携带参数change-ip,change_port
意思是让服务器使用217.116.122.136:10001给恢复响应消息。
但是客户端在规定的时间内,没有收到响应。
说明,客户端所在的NAT,确定不是 完全圆锥型NAT(Full Cone NAT)。


192.168.1.42:52971 → 217.116.122.136:10001 发送Binding请求,
217.116.122.136:10001 → 192.168.1.42:52971 接受Binding响应
告知客户端:服务接收的Binding请求来自:117.158.134.217:47149
告知客户端:服务器的另外一个服务地址为:217.10.68.152:10000
嗝屁,同一个端口出去的数据,因为发给不同服务器,端口不一样了。
对称型NAT(Symmetric NAT)无疑。


我这边反正是打不了洞让别人用了,
但愿对方是个 完全圆锥型NAT(Full Cone NAT)或者 地址限制圆锥型NAT(Restricted Cone NAT)
还有一丝希望通过P2P通讯。

官方说明

难搞明白的东西,有初步了解后,还是需要看看官方说明

摘录自:RFC 3489 STUN - Simple Traversal of User Datagram Protocol (UDP) Through Network Address Translators (NATs)


                        +--------+
                        |  Test  |
                        |   I    |
                        +--------+
                             |
                             |
                             V
                            /\              /\
                         N /  \ Y          /  \ Y             +--------+
          UDP     <-------/Resp\--------->/ IP \------------->|  Test  |
          Blocked         \ ?  /          \Same/              |   II   |
                           \  /            \? /               +--------+
                            \/              \/                    |
                                             | N                  |
                                             |                    V
                                             V                    /\
                                         +--------+  Sym.      N /  \
                                         |  Test  |  UDP    <---/Resp\
                                         |   II   |  Firewall   \ ?  /
                                         +--------+              \  /
                                             |                    \/
                                             V                     |Y
                  /\                         /\                    |
   Symmetric  N  /  \       +--------+   N  /  \                   V
      NAT  <--- / IP \<-----|  Test  |<--- /Resp\               Open
                \Same/      |   I    |     \ ?  /               Internet
                 \? /       +--------+      \  /
                  \/                         \/
                  |                           |Y
                  |                           |
                  |                           V
                  |                           Full
                  |                           Cone
                  V              /\
              +--------+        /  \ Y
              |  Test  |------>/Resp\---->Restricted
              |   III  |       \ ?  /
              +--------+        \  /
                                 \/
                                  |N
                                  |       Port
                                  +------>Restricted

                 Figure 2: Flow for type discovery process
10.1  Discovery Process

   In this scenario, a user is running a multimedia application which
   needs to determine which of the following scenarios applies to it:

   o  On the open Internet

   o  Firewall that blocks UDP

   o  Firewall that allows UDP out, and responses have to come back to
      the source of the request (like a symmetric NAT, but no
      translation.  We call this a symmetric UDP Firewall)

   o  Full-cone NAT

   o  Symmetric NAT

   o  Restricted cone or restricted port cone NAT

   Which of the six scenarios applies can be determined through the flow
   chart described in Figure 2.  The chart refers only to the sequence
   of Binding Requests; Shared Secret Requests will, of course, be
   needed to authenticate each Binding Request used in the sequence.
   
   The flow makes use of three tests.  In test I, the client sends a
   STUN Binding Request to a server, without any flags set in the
   CHANGE-REQUEST attribute, and without the RESPONSE-ADDRESS attribute.
   This causes the server to send the response back to the address and
   port that the request came from.  In test II, the client sends a
   Binding Request with both the "change IP" and "change port" flags
   from the CHANGE-REQUEST attribute set.  In test III, the client sends
   a Binding Request with only the "change port" flag set.

   The client begins by initiating test I.  If this test yields no
   response, the client knows right away that it is not capable of UDP
   connectivity.  If the test produces a response, the client examines
   the MAPPED-ADDRESS attribute.  If this address and port are the same
   as the local IP address and port of the socket used to send the
   request, the client knows that it is not natted.  It executes test
   II.

   If a response is received, the client knows that it has open access
   to the Internet (or, at least, its behind a firewall that behaves
   like a full-cone NAT, but without the translation).  If no response
   is received, the client knows its behind a symmetric UDP firewall.

   In the event that the IP address and port of the socket did not match
   the MAPPED-ADDRESS attribute in the response to test I, the client
   knows that it is behind a NAT.  It performs test II.  If a response
   is received, the client knows that it is behind a full-cone NAT.  If
   no response is received, it performs test I again, but this time,
   does so to the address and port from the CHANGED-ADDRESS attribute
   from the response to test I.  If the IP address and port returned in
   the MAPPED-ADDRESS attribute are not the same as the ones from the
   first test I, the client knows its behind a symmetric NAT.  If the
   address and port are the same, the client is either behind a
   restricted or port restricted NAT.  To make a determination about
   which one it is behind, the client initiates test III.  If a response
   is received, its behind a restricted NAT, and if no response is
   received, its behind a port restricted NAT.

   This procedure yields substantial information about the operating
   condition of the client application.  In the event of multiple NATs
   between the client and the Internet, the type that is discovered will
   be the type of the most restrictive NAT between the client and the
   Internet.  The types of NAT, in order of restrictiveness, from most
   to least, are symmetric, port restricted cone, restricted cone, and
   full cone.

   Typically, a client will re-do this discovery process periodically to
   detect changes, or look for inconsistent results.  It is important to
   note that when the discovery process is redone, it should not
   generally be done from the same local address and port used in the
   previous discovery process.  If the same local address and port are
   reused, bindings from the previous test may still be in existence,
   and these will invalidate the results of the test.  Using a different
   local address and port for subsequent tests resolves this problem.
   An alternative is to wait sufficiently long to be confident that the
   old bindings have expired (half an hour should more than suffice).

谁爱看谁看,我英语水平有限,我反正没有看。

P2P在什么情况下能通

摘录自(上面摘录过):https://blog.csdn.net/wgl307293845/article/details/120450626

在这里插入图片描述
为什么对称型NAT和端口受限型NAT之间无法实现无法实现P2P通讯

自己

悟不明白说明您没有闹懂,重新看或者再找别的帖子学习好了。

TCP怎么打洞?

和主题无关,搁置

  • 3
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值