1. 程式人生 > >STUN協議資料格式及抓包分析

STUN協議資料格式及抓包分析

        最近做一個伺服器,在預先建立會話那塊,協議提到了一種穿越NAT/防火牆的方案——ICE(Interactive Connectivity Establishment)互動式連線。ICE是通過綜合運用STUN,TURN,RSIP等NAT穿透方式,使之能在最適合的情況下工作,以彌補單獨使用其中任何一種所帶來的固有缺陷。對於SIP來說,ICE只需要定義一些SDP(Sessionescription Protoc01)附加屬性即可,對於別的多媒體信令協議也需要制定一些相應的機制來實現。

        ICE的演算法可以分為以下幾個流程:

(1)收集本地傳輸地址

會話者從伺服器上獲得主機上一個物理(或虛擬)介面繫結一個埠的本地傳輸地址。

(2)啟動STUN

與傳統的STUN不同,ICE使用者名稱和密碼可以通過信令協議進行交換。

(3)確定傳輸地址的優先順序

優先順序反映了UA在該地址上接收媒體流的優先級別,取值範圍0到1之間,按照被傳輸媒體流量來確定。

(4)構建初始化資訊(Initiate Message)

初始化訊息由一系列媒體流組成,每個媒體流的任意Peer之間實現最人連通可能性的傳輸地址是由公網L轉發伺服器(如TURN)提供的地址。

(5)響應處理

連通性檢查和執行ICE演算法中描述的地址收集過程。

(6)生成接受資訊(Accept Message)

若接受則傳送Accept訊息,其構造過程與InitiateMessage類似。

(7)接受資訊處理

接受過程需要發起者使用Send命令,由伺服器轉發至響應者。

(8)附加ICE過程

Initiate或Accept訊息交換過程結束後,雙方可能仍將繼續收集傳輸地址。

        簡單的說,就是SIP終端在註冊時,訪問STUN伺服器,獲得NAT/防火牆的結構型別;當發起呼叫資訊(INVITE)或接收到呼叫資訊迴應(200 OK)之前根據NAT/防火牆型別通過訪問STUN伺服器進行對RTP進行地址收集(任非對稱性NAT/防火牆後需要收集NAT對映地址,在對稱性NAT/防火牆後還需要收集TURN地址);然後在RTP的地址埠啟動接收執行緒RSTUN服務程式;最後傳送SIP訊息,收集的地址放列SDP訊息中的alt屬性中。

        STUN(Simple Traversal of UDP over NATs,NAT 的UDP簡單穿越),首先在RFC3489中定義,作為一個完整的NAT穿透解決方案,英文全稱是Simple Traversal of UDP Through NATs,即簡單的用UDP穿透NAT。在新的RFC5389修訂中把STUN協議定位於為穿透NAT提供工具,而不是一個完整的解決方案,英文全稱是Session Traversal Utilities for NAT,即NAT會話穿透效用。RFC5389與RFC3489除了名稱變化外,最大的區別是支援TCP穿透。

        TURN,首先在RFC5766中定義,英文全稱是Traversal Using Relays around NAT:Relay Extensions to Session Traversal Utilities for NAT,即使用中繼穿透NAT:STUN的擴充套件。簡單的說,TURN與STURN的共同點都是通過修改應用層中的私網地址達到NAT穿透的效果,異同點是TURN是通過兩方通訊的“中間人”方式實現穿透。一般來說,實在P2P通訊無法實現時,TURN就會派上用場。

 STUN的報文結構為:

Ø  訊息頭

所有的STUN訊息都包含20個位元組的訊息頭,包括16位的訊息型別,16位的訊息長度和128位的事務ID。

位元組

0                                 1                                 2                                 3

訊息型別

訊息長度

事務ID

訊息型別許可的值如下:

0x0001:捆綁請求

0x0101:捆綁響應

0x0111:捆綁錯誤響應

0x0002:共享私密請求

0x0102:共享私密響應

0x0112:共享私密錯誤響應

訊息長度,是訊息大小的位元組數,但不包括20位元組的頭部。

事務ID,128位的識別符號,用於隨機請求和響應,請求與其相應的所有響應具有相同的識別符號。

Ø  訊息屬性

訊息頭之後是0個或多個屬性,每個屬性進行TLV編碼,包括16位的屬性型別、16位的屬性長度和變長屬性值。

位元組

0                                 1                                 2                                 3

屬性型別

屬性長度

屬性值

……

屬性型別定義如下:

MAPPED-ADDRESS

MAPPED-ADDRESS屬性表示對映過的IP地址和埠。它包括8位的地址族,16位的埠號及長度固定的IP地址。

RESPONSE-ADDRESS

RESPONSE-ADDRESS屬性表示響應的目的地址

CHASNGE-REQUEST

客戶使用32位的CHANGE-REQUEST屬性來請求伺服器使用不同的地址或埠號來發送響應。

SOURCE-ADDRESS

SOURCE-ADDRESS屬性出現在捆綁響應中,它表示伺服器傳送響應的源IP地址和埠。

CHANGED-ADDRESS

如果捆綁請求的CHANGE-REQUEST屬性中的“改變IP”和“改變埠”標誌設定了,則CHANGED-ADDRESS屬性表示響應發出的IP地址和埠號。

USERNAME

USERNAME屬性用於訊息的完整性檢查,用於訊息完整性檢查中標識共享私密。USERNAME通常出現在共享私密響應中,與PASSWORD一起。當使用訊息完整性檢查時,可有選擇地出現在捆綁請求中。

PASSWORD

PASSWORD屬性用在共享私密響應中,與USERNAME一起。PASSWORD的值是變長的,用作共享私密,它的長度必須是4位元組的倍數,以保證屬性與邊界對齊。

MESSAGE-INTEGRITY

MESSAGE-INTEGRITY屬性包含STUN訊息的HMAC-SHA1,它可以出現在捆綁請求或捆綁響應中;MESSAGE-INTEGRITY屬性必須是任何STUN訊息的最後一個屬性。它的內容決定了HMAC輸入的Key值。

ERROR-CODE

ERROR-CODE屬性出現在捆綁錯誤響應或共享私密錯誤響應中。它的響應號數值範圍從100到699。

下面的響應號,與它們預設的原因語句一起,目前定義如下:

400(錯誤請求):請求變形了。客戶在修改先前的嘗試前不應該重試該請求。

401(未授權):捆綁請求沒有包含MESSAGE-INTERITY屬性。

420(未知屬性):伺服器不認識請求中的強制屬性。

430(過期資格):捆綁請求沒有包含MESSAGE-INTEGRITY屬性,但它使用過期

的共享私密。客戶應該獲得新的共享私密並再次重試。

431(完整性檢查失敗):捆綁請求包含MESSAGE-INTEGRITY屬性,但HMAC驗

證失敗。這可能是潛在攻擊的表現,或者客戶端實現錯誤

432(丟失使用者名稱):捆綁請求包含MESSAGE-INTEGRITY屬性,但沒有

USERNAME屬性。完整性檢查中兩項都必須存在。

433(使用TLS):共享私密請求已經通過TLS(Transport Layer Security,即安全

傳輸層協議)傳送,但沒有在TLS上收到。

500(伺服器錯誤):伺服器遇到臨時錯誤,客戶應該再次嘗試。

600(全域性失敗):伺服器拒絕完成請求,客戶不應該重試。

UNKNOWN-ATTRIBUTES

UNKNOWN-ATTRIBUTES屬性只存在於其ERROR-CODE屬性中的響應號為420的捆綁錯誤響應或共享私密錯誤響應中。

REFLECTED-FROM

REFLECTED-FROM屬性只存在於其對應的捆綁請求包含RESPONSE-ADDRESS屬性的捆綁響應中。屬性包含請求發出的源IP地址,它的目的是提供跟蹤能力,這樣STUN就不能被用作DOS攻擊的反射器。

        屬性空間分為可選部分與強制部分,值超過0x7fff的屬性是可選的,即客戶或伺服器即使不認識該屬性也能夠處理該訊息;值小於或等於0x7fff的屬性是強制理解的,即除非理解該屬性,否則客戶或伺服器就不能處理該訊息。

        現在在公網上有很多可以直接使用的STUN伺服器,比如我在測試時使用的STUN伺服器的IP為:77.72.169.211,埠為3478,以下為測試的其中事務ID部分直接填寫為了全0,傳送的資料如圖所示,其中,傳送的環境為windows 10環境,傳送埠為50000埠:

        測試抓包截圖如圖所示:

        其中,在第三個伺服器上同時抓包,目的就是驗證STUN伺服器傳送給我的資料是否是正確的。

        從本機發送到STUN伺服器上的資料如圖所示:

        從STUN伺服器返回到本機的資料如圖所示:

        在第三個伺服器上抓取得到的資料包如圖所示:

        傳送的源IP和源埠如圖所示:

        可見,本機的公網經過NAT對映後的IP和埠和STUN伺服器返回的IP和埠資料保持一致。

        當然,網上也有資料顯示,如果一段時間經過NAT對映後的IP和埠沒有被使用,那麼NAT會回收相關的資源。所以這就要求在NAT後的終端定時和STUN伺服器保持通訊,防止NAT回收相關資源導致在後面的業務之中出現了錯誤。

結論:在一些種類的NAT下,STUN是一種穿透NAT的有效手段。