• <ruby id="5koa6"></ruby>
    <ruby id="5koa6"><option id="5koa6"><thead id="5koa6"></thead></option></ruby>

    <progress id="5koa6"></progress>

  • <strong id="5koa6"></strong>
  • iptables下udp穿越實用篇----iptables與natcheck

    發表于:2007-05-26來源:作者:點擊數: 標簽:
    iptables下udp穿越實用篇----iptables與natcheck 文章標題iptables下udp穿越實用篇----iptables與natcheck 張貼者:shixudong(member) 張貼日期10/16/0405:51PM iptables與natcheck Stun協議(Rfc3489、詳見http://www.ietf.org/rfc/rfc3489.txt)提出了4種N
    iptables下udp穿越實用篇----iptables與natcheck

    文章標題   iptables下udp穿越實用篇----iptables與natcheck    
    張貼者: shixudong (member) 
    張貼日期 10/16/04 05:51 PM 



    iptables與natcheck 

    Stun協議(Rfc3489、詳見http://www.ietf.org/rfc/rfc3489.txt) 提出了4種NAT類型的定義及其分類,并給出了如何檢測在用的NAT究竟屬于哪種分類的標準。但是,具體到P2P程序如何應用Stun協議及其分類法穿越NAT,則是仁者見仁、智者見智。(因為Stun協議并沒有給出也沒有必要給出如何穿越NAT的標準) 
    在拙作“iptables與stun”一文中,筆者花大幅精力闡述了iptables理論上屬于Symmetric NAT而非Port Restricted Cone。對此,很多人(包括筆者最初學習Stun協議時)心中都有一個疑惑,即僅就Stun協議本身來說,Port Restricted Cone和Symmetric NAT的區別似乎不大,雖然兩者的映射機制是有點不同,但他們都具有端口受限的屬性。初看起來,這兩者在穿越NAT方面的特性也差不多,尤其是對于外部地址欲往NAT內部地址發包的情況。既然如此,又為何有必要把iptables分得這么清呢,本文順帶解決了讀者在這一方面的疑惑。 
    網站http://midcom-p2p.sourceforge.net/給出了P2P程序具體如何穿越NAT的一個思路,并提供了一個P2P協議穿越NAT兼容性的測試工具natcheck。讓我們仍舊用實例(例1)來說明這一思路吧! 
    A機器在私網(192.168.0.4) 
    A側NAT服務器(210.21.12.140) 
    B機器在另一個私網(192.168.0.5) 
    B側NAT服務器(210.15.27.140) 
    C機器在公網(210.15.27.166)作為A和B之間的中介 
    A機器連接過C機器,假使是 A(192.168.0.4:5000)-> A側NAT(轉換后210.21.12.140:8000)-> C(210.15.27.166:2000) 
    B機器也連接過C機器,假使是 B(192.168.0.5:5000)-> B側NAT(轉換后210.15.27.140:8000)-> C(210.15.27.166:2000) 
    A機器連接過C機器后,A向C報告了自己的內部地址(192.168.0.4:5000),此時C不僅知道了A的外部地址(C通過自己看到的210.21.12.140:8000)、也知道了A的內部地址。同理C也知道了B的外部地址(210.15.27.140:8000)和內部地址(192.168.0.5:5000)。之后,C作為中介,把A的兩個地址告訴了B,同時也把B的兩個地址告訴了A。 
    假設A先知道了B的兩個地址,則A從192.168.0.4:5000處同時向B的兩個地址192.168.0.5:5000和210.15.27.140:8000發包,由于A和B在兩個不同的NAT后面,故從A(192.168.0.4:5000)到B(192.168.0.5:5000)的包肯定不通,現在看A(192.168.0.4:5000)到B(210.15.27.140:8000)的包,分如下兩種情況: 
    1、B側NAT屬于Full Cone NAT 
    則無論A側NAT屬于Cone NAT還是Symmetric NAT,包都能順利到達B。如果P2P程序設計得好,使得B主動到A的包也能借用A主動發起建立的通道的話,則即使A側NAT屬于Symmetric NAT,B發出的包也能順利到達A。 
    結論1:只要單側NAT屬于Full Cone NAT,即可實現雙向通信。 
    2、B側NAT屬于Restricted Cone或Port Restricted Cone 
    則包不能到達B。再細分兩種情況 
    (1)、A側NAT屬于Restricted Cone或Port Restricted Cone 
    雖然先前那個初始包不曾到達B,但該發包過程已經在A側NAT上留下了足夠的記錄:A(192.168.0.4:5000)->(210.21.12.140:8000)->B(210.15.27.140:8000)。如果在這個記錄沒有超時之前,B也重復和A一樣的動作,即向A(210.21.12.140:8000)發包,雖然A側NAT屬于Restricted Cone或Port Restricted Cone,但先前A側NAT已經認為A已經向B(210.15.27.140:8000)發過包,故B向A(210.21.12.140:8000)發包能夠順利到達A。同理,此后A到B的包,也能順利到達。 
    結論2:只要兩側NAT都不屬于Symmetric NAT,也可雙向通信。換種說法,只要兩側NAT都屬于Cone NAT,即可雙向通信。 
    (2)、A側NAT屬于Symmetric NAT 
    因為A側NAT屬于Symmetric NAT,且最初A到C發包的過程在A側NAT留下了如下記錄:A(192.168.0.4:5000)->(210.21.12.140:8000)-> C(210.15.27.166:2000),故A到B發包過程在A側NAT上留下的記錄為:A(192.168.0.4:5000)->(210.21.12.140:8001)->B(210.15.27.140:8000)(注意,轉換后端口產生了變化)。而B向A的發包,只能根據C給他的關于A的信息,發往A(210.21.12.140:8000),因為A端口受限,故此路不通。再來看B側NAT,由于B也向A發過了包,且B側NAT屬于Restricted Cone或Port Restricted Cone,故在B側NAT上留下的記錄為:B(192.168.0.5:5000)->(210.15.27.140:8000)->A(210.21.12.140:8000),此后,如果A還繼續向B發包的話(因為同一目標,故仍然使用前面的映射),如果B側NAT屬于Restricted Cone,則從A(210.21.12.140:8001)來的包能夠順利到達B;如果B側NAT屬于Port Restricted Cone,則包永遠無法到達B。 
    結論3:一側NAT屬于Symmetric NAT,另一側NAT屬于Restricted Cone,也可雙向通信。 
    顯然,還可得出另一個不幸的結論4,兩個都是Symmetric NAT或者一個是Symmetric NAT、另一個是Port Restricted Cone,則不能雙向通信。 
    上面的例子雖然只是分析了最初發包是從A到B的情況,但是,鑒于兩者的對稱性,并且如果P2P程序設計得足夠科學,則前面得出的幾條結論都是沒有方向性,雙向都適用的。 
    通過上述分析,我們得知,在穿越NAT方面,Symmetric NAT和Port Restricted Cone是有本質區別的,盡管他們表面上看起來相似。我們上面得出了四條結論,而natcheck網站則把他歸結為一條:只要兩側NAT都屬于Cone NAT(含Full Cone、Restricted Cone和Port Restricted Cone三者),即可雙向通信。而且natcheck網站還建議盡量使用Port Restricted Cone,以充分利用其端口受限的屬性確保安全性。目前,國內充分利用了上述思路的具有代表性的P2P軟件是“E話通”(www.et66.com)。 
    在對natcheck提供的思路進行詳細分析后,開始探討本文主題:iptables與natcheck。 
    Natcheck脫胎于Stun協議,由拙作“iptables與stun”一文可知,其對iptables進行的穿越NAT兼容性測試結果必然是GOOD。此外,我在該文中還提到一句,如果在每個NAT后面僅有一個客戶端這種特殊情況下,iptables就是一個標準的Port restricted Cone。根據前面natcheck的結論,這樣兩個iptables后面的客戶端應該可以互相穿越對方的NAT。讓我們來看一下實際情況(例2)呢? 
    仍然參考前例,只是兩側都使用iptables來進行地址轉換。(因為采用了iptables,故此處和前例稍有點區別,即轉換后源端口不變) 
    A與B通過C交換對方地址的初始化環節此處略去,我們從A(192.168.0.4:5000)向B(210.15.27.140:5000)(注意因使用iptables而導致端口和前例不一樣)發包開始分析,因為在本例中,兩側均只有一個客戶端,我們姑且把iptables簡化成Port restricted Cone看待。 
    如前例一樣,從A(192.168.0.4:5000)到B(210.15.27.140: 5000)的第一個包必不能到達B,但其會在A側iptables上留下記錄,在這條記錄沒有超時之前(iptables下默認30秒),如果B也向A(210.21.12.140:5000)發包,如前所述,按理該包應該能夠到達A,但事實上卻是永遠到不了。 
    難道是natcheck的結論錯了,或者是特殊情況下iptables并不是Port restricted Cone(即仍然是Symmetric NAT),我們還是別忙著再下結論,先來看看來兩側iptables上留下的記錄吧: 
    A側:cat /proc/net/ip_conntrack | grep 192.168.0.4 | grep udp 
    udp 17 18 src=192.168.0.4 dst=210.15.27.140 sport=5000 dport=5000 [UNREPLIED] src=210.15.27.140 dst=210.21.12.140 sport=5000 dport=5000 use=1 
    B側:cat /proc/net/ip_conntrack | grep 192.168.0.5 | grep udp 
    udp 17 26 src=192.168.0.5 dst=210.21.12.140 sport=5000 dport=5000 [UNREPLIED] src=210.21.12.140 dst=210.15.27.140 sport=5000 dport=1026 use=1 
    把兩條記錄翻譯如下:(關于ip_conntrack文件的分析,請見http://www.sns.ias.edu/~jns/secu ... bles_conntrack.html) 
    A(192.168.0.4:5000)-> A側NAT(轉換后210.21.12.140:5000)-> B(210.15.27.140:5000) 
    B(192.168.0.5:5000)-> B側NAT(轉換后210.15.27.140:1026)-> A(210.21.12.140:5000) 
    奇怪,B到A的包在映射后源端口號怎么變了呢,按理不應該呀?因為按照iptables轉換原則(詳見“iptables與stun”),要求盡量保持源端口號不變,除非socket有重復。難道B側NAT上還有重復記錄,再cat一下呢? 
    B側:cat /proc/net/ip_conntrack | grep 210.21.12.140 | grep udp 
    udp 17 10 src=210.21.12.140 dst=210.15.27.140 sport=5000 dport=5000 [UNREPLIED] src=210.15.27.140 dst=210.21.12.140 sport=5000 dport=5000 use=1 
    udp 17 16 src=192.168.0.5 dst=210.21.12.140 sport=5000 dport=5000 [UNREPLIED] src=210.21.12.140 dst=210.15.27.140 sport=5000 dport=1026 use=1 
    操!還果真有兩條差不多的記錄,第一條與NAT無關,是A到B的包在B側iptables上留下的記錄,產生時間上略早于第二條記錄,其構成的socket是(210.21.12.140:5000,210.15.27.140:5000)。第二條即B到A的包產生的記錄,其構成的socket是(210.15.27.140:1026,210.21.12.140:5000),如果其源端口不改動,即是(210.15.27.140:5000,210.21.12.140:5000),還真和第一條記錄重復了呢,怪不得轉換后需要修改源端口,也怪不得B發包到不了A。 
    為什么是這樣的結果呢?我們知道,iptables是一個有狀態的防火墻,他通過連接跟蹤模塊來實現狀態檢測的功能,該模塊檢查所有到來的數據包,也就是說,該模塊不僅對NAT起作用,而且對普通的包過濾也起作用。顯然,在上述例子里,A到B的包就是作為普通的包過濾而被記載在B側iptables的連接跟蹤表里,導致后來B到A的包為避免socket重復而不得不改換端口號,從而導致無法實現雙向通信??磥?,natcheck的結論并沒有錯,只是由于iptables具有狀態檢測的新特性導致即使在特殊情況下iptables又從Port restricted Cone變成了Symmetric NAT而已。 
    那么,有辦法解決這一問題嗎?根據連接跟蹤的特性,在iptables下,只要啟用了NAT,就肯定要啟用連接跟蹤功能,而只要啟用了連接跟蹤功能,就必然順帶跟蹤普通包過濾(啟用連接跟蹤后,似乎無法控制不讓跟蹤普通包過濾),也就是說,只要用NAT,就無法避免上述情況,真殘酷!然而,這卻是事實,即只要兩端都采用了iptables作為NAT,則盡管兩側都通過了natcheck的兼容性測試,但iptables兩側永遠也不能互相穿越。 
    在“iptables與stun”一文中曾經附帶提到,Win2000下的ics或nat在Stun協議下的表現和iptables是完全一樣的。那么,在natcheck下,表現是否還一致呢?答案是否定的,雖然Win2000下的ics或nat也具有狀態檢測的功能,但該狀態檢測,僅對NAT起作用,不對普通包過濾起作用。所以在兩側都是Win2000下的ics或nat可以作為Port restricted Cone的特殊情況下,是允許被穿越的。另外,在一側使用iptables,另一側使用Win2000下的ics或nat,但兩者都表現為Port restricted Cone的特殊情況下,從某個方向發起,最終是允許互相穿越的,但是這種穿越不具有對稱性,即從另一個方向發起,則永遠無法穿越,具體原理,讀者可以參考例2自行分析。 

    即將推出其結尾篇----iptables下udp穿越結尾篇----“iptables與socks5” 

    [email]shixudong@163.com[/email]

    原文轉自:http://www.kjueaiud.com

    老湿亚洲永久精品ww47香蕉图片_日韩欧美中文字幕北美法律_国产AV永久无码天堂影院_久久婷婷综合色丁香五月

  • <ruby id="5koa6"></ruby>
    <ruby id="5koa6"><option id="5koa6"><thead id="5koa6"></thead></option></ruby>

    <progress id="5koa6"></progress>

  • <strong id="5koa6"></strong>