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