NAT类型与穿透 及 STUN TURN 协议
STUN : Simple Traversal of User Datagram Protocol [UDP] Through Network Address Translators [NATs]
STUN protocol (Simple Traversal of UDP through NATs) is described in the IETF RFC 3489,
available at http://www.ietf.org/rfc/rfc3489.txt
http://www.ietf.org/rfc/rfc5389.txt
http://nodex.iteye.com/blog/1488719
NAT类型与穿透 及 STUN TURN 协议
NAT话题,主要涉及:
– NAT 与 防火墙
– NAT 基本类型 与 原理
– NAT 穿透方式及原理
– 基于NAT穿透的网络应用
– NAT穿透相关的工具和开源项目
焦点集中在NAT类型以及对应的穿透方式,下面分别收录几篇文章做进一步了解。
1 网络 与 NAT 和 防火墙
公网/内网IP分配及NAT地址转换协议
http://yanshiwen2007.blog.163.com/blog/static/38688705200711483248456/
防火墙和NAT
http://wenku.baidu.com/view/1c5ccba10029bd64783e2c94.html
NAT的四种类型及类型检测
http://www.cnblogs.com/my_life/articles/1908552.html
多媒体通讯中防火墙和NAT问题的解决
http://it.rising.com.cn/newSite/Channels/Safety/SafeDefend/Defender/200212/26-095709141.htm
Linux下的NAT及防火墙的混合应用
http://www.bitscn.com/os/linux/200604/7934.html
2 NAT 穿透
NAT穿透
http://zh.wikipedia.org/wiki/NAT%E7%A9%BF%E8%B6%8A
NAT的完全分析及其UDP穿透的完全解决方案
http://zongtongyi.blogbus.com/logs/2857757.html
NAT穿透
http://blog.csdn.net/feiren127/article/details/5571636
NAT穿透之NAT类型检测
http://www.yunsec.net/a/special/wlgf/wlrq/2011/0101/7820.html
P2P网络“自由”穿越NAT的“秘密”
http://www.cnblogs.com/lovko/archive/2008/10/12/1309094.html
Symmetric NAT Traversal
http://www.dialogic.com/webhelp/bordernet2020/1.0.0/webhelp/nat_traversal.htm
3 STUN 和 TURN 协议
旧版本STUN http://www.ietf.org/rfc/rfc3489.txt
新版本STUN http://www.ietf.org/rfc/rfc5389.txt
TURN http://www.ietf.org/rfc/rfc5766.txt
Symmetric NAT Traversal using STUN : http://tools.ietf.org/id/draft-takeda-symmetric-nat-traversal-00.txt
PS: 此协议是草稿,主要是关于基于 STUN 来做 Symmetric 类型的NAT穿透;但这不是100%可以成功的,有一定的概率。
PS: 新旧STUN协议及TURN协议在实现和使用上的差异?
久版的STUN主要是基于判断NAT类型的,而新版本的STUN以及其扩展的TURN协议,摒弃了原来的思路,以获得一个可靠可用的通信地址和端口为目标;
新版的STUN重在获得改地址,而TURN则提供了基于已知地址的数据传递协议规范。所以实践中,如果STUN告诉我们地址后,可以P2P,则优先P2P,否则TURN中转。
新旧版本的STUN协议完全不同,协议设计也不同,无法兼容;新版的STUN则和TURN关系密切,后者是基于前者扩展设计的,大多数服务端也兼容二者。
4 工具与开源项目
NAT 类型检测
NAT Check:Check Your Network Address Translator for Compatibility with Peer-to-Peer Protocols
http://midcom-p2p.sourceforge.net/
VC++实现NAT穿透之NAT类型检测
http://blog.csdn.net/yincheng01/article/details/4486359
– STUN
stund
http://sourceforge.net/projects/stun
pystun
http://code.google.com/p/pystun/
stunclient
http://code.google.com/p/stunclient/source/browse/#svn%2Ftrunk%2Fstun
– STUN & TURN
turnserver
http://turnserver.sourceforge.net/ (http://www.turnserver.org/)
turn-client
https://github.com/node/turn-client
PS: 下载按时时请注意,以上工具和项目中大多使用标准C和python(cpython) .
STUNMAN
http://www.stunprotocol.org/ , https://github.com/jselbie/stunserver
Features:
Compliant with the latest RFCs including 5389, 5769, and 5780. Also includes backwards compatibility for RFC 3489.
Supports both UDP and TCP on both IPv4 and IPv6.
Client test app provided.
STUNMAN 使用C++开发,实现了新版的STUN和TURN协议,同时兼容处理旧版的STUN协议请求。
jstun
http://jstun.javawi.de/
stung4j
https://stun4j.dev.java.net/
5 总结
– Q: 是否所有NAT都可以穿透?
A: 不是!简单说, 只要是cone类型的NAT,则可以穿透,100%地穿透,
即 full cone NAT, address restricted cone NAT 和 port restricted cone NAT 都可以穿透;
而 symmetric NAT则不能保证100%穿透,也就是说不可靠无法依赖穿透symmetric NAT来通信,必须提供备选方式如代理中转等。
– Q: 对于无法穿透的NAT该怎么办?
A: 既然有STUN和TURN甚至SOCK5等协议,那么在确定无法穿透或者不能确定穿透时,选择服务器中转是上策。
– Q: 实践中哪种类型的NAT更多一些?
A: 有时候应用只需要面对大多数用户即可,无需严格考虑所有情况,则需要参考实践中的NAT类型比例;
这个数据我没有实际调查过,但结合网络上提供的资料,目前大多数NAT都属于cone的,不是symmetric的;但典型的sysmmetric仍然存在,比如可能有:
– 安全要求较高的内部专属网/局域网
– 互联网与EGDE网络之间,互联网与3G网之间
– Q: Symmetric NAT 的穿透状况到底如何?
A: 可以穿透,但不是100%成功;那么如何提高成功率呢? http://www.goto.info.waseda.ac.jp/~wei/file/wei-apan-v10.pdf
这篇很早的文章显示他们的办法可以达到99%的NAT穿透率,高于当时SKYPE的46% 。其中的难点,主要在于不断变化的端口映射,导致mapping address无法稳定下来用于两个peer的通信。
6 辅助工具
在线NAT类型检测
nattest.net.in.tum.de
从外部测试本地端口是否可访问
http://canyouseeme.org/
关于STUN和NAT
http://my.oschina.net/MinGKai/blog/157015
下面大多数都是转载的,只做了少量的更改和优化。。
什么是STUN服务器?
虽然是在UDP 端口3478连接STUN服务器,但会暗示客户终端在另外一个IP和端口号上实施测试(STUN服务器有两个IP地址)。
公开的免费STUN服务器
当SIP终端在使用私有IP地址时,可能需要配置stun服务器。
公开的免费STUN服务器有:
//from origin post stunserver.org stun.xten.com stun.fwdnet.net stun.fwdnet.net:3478 stun.wirlab.net stun01.sipphone.com stun.iptel.org stun.ekiga.net stun.fwdnet.net stun01.sipphone.com (no DNS SRV record) stun.softjoys.com (no DNS SRV record) stun.voipbuster.com (no DNS SRV record) stun.voxgratia.org (no DNS SRV record) stun.xten.com stunserver.org stun.sipgate.net:10000 stun.softjoys.com:3478 //from https://gist.github.com/zziuni/3741933 # source : http://code.google.com/p/natvpn/source/browse/trunk/stun_server_list # A list of available STUN server. stun.l.google.com:19302 stun1.l.google.com:19302 stun2.l.google.com:19302 stun3.l.google.com:19302 stun4.l.google.com:19302 stun01.sipphone.com stun.ekiga.net stun.fwdnet.net stun.ideasip.com stun.iptel.org stun.rixtelecom.se stun.schlund.de stunserver.org stun.softjoys.com stun.voiparound.com stun.voipbuster.com stun.voipstunt.com stun.voxgratia.org stun.xten.com
如何使用STUN协议了解所在网络的NAT类型
在P2P应用盛行的今天,很多人对处在不同局域网中的主机间的通信方式都不陌生.
而UDP穿透作为这样一个主流技术也受到了很多人的关注,在UDP穿透中
有一个基本点就是要知道主机自身所在的网络类型以及经映射后的公网IP地址.
STUN(Simple Traversal of UDP over NATs,NAT的UDP简单穿越)是一种网络协议,
它允许位于NAT(或多重NAT)后的客户端找出自己的公网地址,查出自己位于哪种类型的NAT之后
以及NAT为某一个本地端口所绑定的Internet端端口.这些信息被用来在两个同时处于NAT 路由器之后的主机之间建立UDP通信.
该协议由RFC 3489定义.是一个客户机/服务器协议,在公网上存在着大量的STUN服务器,
用户可以通过在自己主机上运行STUN客户端远程连接STUN服务器来确认自身的网络状况.
客户端主机所在网络可以分为以下类型:
- Opened: 即主机拥有公网IP,并且没有,可自由与外部通信.
-
Full Cone NAT: 主机前有NAT设备,NAT规则如下:
从主机UDP端口A发出的数据包都会对应到NAT设备出口IP的端口B,并且从任意外部地址发送到该NAT设备UDP端口B的包都会被转到主机端口A. -
Restricted cone NAT: 主机前有NAT设备,NAT规则如下:
从主机UDP端口A发出的数据包都会对应到NAT设备出口IP的端口B,但只有从之前该主机发出包的目的IP发出到该NAT设备UDP端口B的包才会被转 到主机端口A. -
Port Restricted cone NAT: 主机前有NAT设备,NAT规则如下:
从主机UDP端口A发出的数据包都会对应到NAT设备出口IP的端口B,但只有从之前该主机发出包的目的IP/PORT发出到该NAT设备UDP端口B的 包才会被转到主机端口A. -
Symmetric UDP Firewall: 主机出口处没有NAT设备,但有防火墙,且防火墙规则如下:
从主机UDP端口A发出的数据包保持源地址,但只有从之前该主机发出包的目的IP/PORT发出到该主机端口A的包才能通过防火墙. - Symmetric NAT: 主机前有NAT设备,NAT规则如下:即使数据包都从主机UDP端口A发出,但只要目的地址不同,NAT设备就会为之分配不同的出端口B.
- Blocked: 防火墙限制UDP通信.
再来说STUN服务器,STUN服务器运行在UDP协议之上,它具有两个固定公网地址,能完成以下几个功能:
1, 告诉STUN客户端经NAT设备映射后的公网地址.
2, 根据STUN客户端的要求,从服务器的其他不同IP或端口向客户端回送包.
如何根据STUN服务器提供的功能来确认网络类型呢?rfc3489给出了如下图过程: 这个过程可概括如下:
1, STUN客户端向STUN服务器发送请求,要求得到自身经NAT映射后的地址:
a,收不到服务器回复,则认为UDP被防火墙阻断,不能通信,网络类型:Blocked.
b,收到服务器回复,对比本地地址,如果相同,则认为无NAT设备,进入第2步,否则认为有NAT设备,进入3步.
2, (已确认无NAT设备)STUN客户端向STUN服务器发送请求,要求服务器从其他IP和PORT向客户端回复包:
a,收不到服务器从其他IP地址的回复,认为包被前置防火墙阻断,网络类型:Symmetric UDP Firewall.
b,收到则认为客户端处在一个开放的网络上,网络类型:Opened.
3, (已确认存在NAT设备)STUN客户端向STUN服务器发送请求,要求服务器从其他IP和PORT向客户端回复包:
a,收不到服务器从其他IP地址的回复,认为包被前置NAT设备阻断,进入第4步.
b,收到则认为NAT设备类型为Full Cone,即网络类型:Full Cone NAT.
4, STUN客户端向STUN服务器的另外一个IP地址发送请求,要求得到自身经NAT映射后的地址,并对比之:
a,地址不相同,则网络类型:Symmetric NAT.
b,相同则认为是Restricted NAT,进入第5步,进一步确认类型.
5, (已确认Restricted NAT设备)STUN客户端向STUN服务器发送请求,要求服务器从相同IP的其他PORT向客户端回复包:
a,收不到服务器从其他PORT地址的回复,认为包被前置NAT设备阻断,网络类型:Port Restricted cone NAT.
b,收到则认为网络类型: Restricted cone NAT.
http://www.3cx.com/PBX/stun-server.html
What is a STUN Server?
A STUN (Simple Traversal of User Datagram Protocol [UDP] Through Network Address Translators [NATs]) server allows NAT clients
(i.e. computers behind a firewall) to setup phone calls to a VOIP provider hosted outside of the local network.
The STUN server allows clients to find out their public address, the type of NAT they are behind
and the internet side port associated by the NAT with a particular local port.
This information is used to set up UDP communication between the client and the VOIP provider and so establish a call.
The STUN protocol is defined in RFC 3489.
The STUN server is contacted on UDP port 3478, however the server will hint clients to perform tests on alternate IP and port number too
(STUN servers have two IP addresses). The RFC states that this port and IP are arbitrary.
http://zh.wikipedia.org/wiki/STUN
STUN(Session Traversal Utilities for NAT,NAT会话传输应用程序)是一种网络协议,
它允许位于NAT(或多重NAT)后的客户端找出自己的公网地址,查出自己位于哪种类型的NAT之后以及NAT为某一个本地端口所绑定的Internet端端口。
这些信息被用来在两个同时处于NAT 路由器之后的主机之间建立UDP通信。该协议由RFC 5389定义
一旦客户端得知了Internet端的UDP端口,通信就可以开始了。
如果NAT是完全圆锥型的,那么双方中的任何一方都可以发起通信。
如果NAT是受限圆锥型或端口受限圆锥型,双方必须一起开始传输。
需要注意的是,要使用STUN RFC中描述的技术并不一定需要使用STUN协议——
还可以另外设计一个协议并把相同的功能集成到运行该协议的服务器上。
SIP之类的协议是使用UDP分组在Internet上传输音频和/或视频数据的。
不幸的是,由于通信的两个末端往往位于NAT之后,因此用传统的方法是无法建立连接的。这也就是STUN发挥作用的地方。
STUN是一个客户机-服务器协议。
一个VoIP电话或软件包可能会包括一个STUN客户端。
这个客户端会向STUN服务器发送请求,之后,服务器就会向STUN客户端报告NAT路由器的公网IP地址以及NAT为允许传入流量传回内网而开通的端口。
以上的响应同时还使得STUN客户端能够确定正在使用的NAT类型——因为不同的NAT类型处理传入的UDP分组的方式是不同的。
四种主要类型中有三种是可以使用的:
完全圆锥型NAT、受限圆锥型NAT和端口受限圆锥型NAT——但大型公司网络中经常采用的对称型NAT(又称为双向NAT)则不能使用。
STUN 使用下列的算法(取自 RFC 3489)来发现 NAT gateways 以及防火墙(firewalls):
一旦路经通过红色箱子的终点时,UDP的沟通是没有可能性的。一旦通过黄色或是绿色的箱子,就有连线的可能。
http://aahhwwrrjj.blog.163.com/blog/static/207967412011112010530324
stun协议的简单解析以及python实现
stun协议主要用来UDP穿越NAT用的,也就是我们经常听到的UDP打洞。协议的细节内容大家可以参考rfc3489。
首先介绍NAT的类型:
引用于:http://www.cnblogs.com/my_life/articles/1908552.html
用语定义
1.内部Tuple:指内部主机的私有地址和端口号所构成的二元组,即内部主机所发送报文的源地址、端口所构成的二元组
2.外部Tuple:指内部Tuple经过NAT的源地址/端口转换之后,所获得的外部地址、端口所构成的二元组,
即外部主机收到经NAT转换之后的报文时,它所看到的该报文的源地址(通常是NAT设备的地址)和源端口
3.目标Tuple:指外部主机的地址、端口所构成的二元组,即内部主机所发送报文的目标地址、端口所构成的二元组
详细释义
1. Full Cone NAT:所有来自同一 个内部Tuple X的请求均被NAT转换至同一个外部Tuple Y,而不管这些请求是不是属于同一个应用或者是多个应用的。
除此之外,当X-Y的转换关系建立之后,任意外部主机均可随时将Y中的地址和端口作为目标地址 和目标端口,
向内部主机发送UDP报文,由于对外部请求的来源无任何限制,因此这种方式虽然足够简单,但却不那么安全
2. Restricted Cone NAT: 它是Full Cone的受限版本:所有来自同一个内部Tuple X的请求均被NAT转换至同一个外部Tuple Y,这与Full Cone相同,
但不同的是,只有当内部主机曾经发送过报文给外部主机(假设其IP地址为Z)后,外部主机才能以Y中的信息作为目标地址和目标端口,
向内部 主机发送UDP请求报文,这意味着,NAT设备只向内转发(目标地址/端口转换)
那些来自于当前已知的外部主机的UDP报文,从而保障了外部请求来源的安 全性
3. Port Restricted Cone NAT:它是Restricted Cone NAT的进一步受限版。
只有当内部主机曾经发送过报文给外部主机(假设其IP地址为Z且端口为P)之后,外部主机才能以Y中的信息作为目标地址和目标端 口,
向内部主机发送UDP报文,同时,其请求报文的源端口必须为P,这一要求进一步强化了对外部报文请求来源的限制,从而较Restrictd Cone更具安全性
4. Symmetric NAT:这是一种比所有Cone NAT都要更为灵活的转换方式:
在Cone NAT中,内部主机的内部Tuple与外部Tuple的转换映射关系是独立于内部主机所发出的UDP报文中的目标地址及端口的,即与目标Tuple无关;
在Symmetric NAT中,目标Tuple则成为了NAT设备建立转换关系的一个重要考量:只有来自于同一个内部Tuple 、且针对同一目标Tuple的请求才被NAT转换至同一个外部Tuple,
否则的话,NAT将为之分配一个新的外部Tuple;打个比方,当内部主机以相 同的内部Tuple对2个不同的目标Tuple发送UDP报文时,此时NAT将会为内部主机分配两个不同的外部Tuple,
并且建立起两个不同的内、外部 Tuple转换关系。与此同时,只有接收到了内部主机所发送的数据包的外部主机才能向内部主机返回UDP报文,
这里对外部返回报文来源的限制是与Port Restricted Cone一致的。
不难看出,如果说Full Cone是要求最宽松NAT UDP转换方式,那么,Symmetric NAT则是要求最严格的NAT方式,其不仅体现在转换关系的建立上,而且还体现在对外部报文来源的限制方面。
本文中测试的NAT类型属于第三种:端口限制的锥形NAT。
stun协议标准的目的就是为了在NAT上打开一个通透的端口路径到本机从而满足P2P通信等需求。
UDP打洞实现的基本原理就是通过一个中转服务器获取两个PEER的公网IP和port,
然后中转服务器向两个PEER发送各自的公网IP和PORT,让连个PEER同时使用原来的PORT向对方的公网IP和PORT发送UDP数据包,完成通信的目的。具体的G一下UDP打洞或者UDP穿越。
上图是一个stun协议的消息格式。消息协议的第一断是消息类型,第二段是消息长度,第三段是消息事务ID。
以一个简单的stun协议过程为例(以google的stun服务为例)
首先客户端发送的是消息类型,然后是消息长度。然后是128bit的的Transaction ID。
消息类型是0x0001;消息长度为:0x0000;事务ID为:1234
过段时间收到服务器相应:
按照上表,我们看出响应中第一个消息是MAPPED-ADDRESS:
数据中端口号是2字节,IP地址为4字节:
然后后面是第二个消息:
同样是服务器的PORT和IP。这样一次stun协议交互就算完成了。
http://stunovertcp.sourceforge.net/
This is the STUN-over-TCP project (“stunovertcp”)
This project was registered on SourceForge.net on Jul 1, 2008, and is described by the project team as follows:
This project adds TCP supports to the Vovida STUN (http://sourceforge.net/projects/stun/) which runs above UDP only.
http://sourceforge.net/projects/stun/
This project implements a simple STUN server and client on Windows, Linux, and Solaris.
The STUN protocol (Simple Traversal of UDP through NATs) is described in the IETF RFC 3489,
available at http://www.ietf.org/rfc/rfc3489.txt, http://www.ietf.org/rfc/rfc5389.txt