2020年12月17日 星期四

穿透防火牆原理

UDP穿透NAT Firewall原理(基礎篇)


知道現在流行的P2P軟件和IM軟件是如何讓兩台分處在不同防火牆後面的電腦直接對話的嗎? SIP當然是一種,還有一種被廣泛應用的就是本文介紹的UDP Hole Punching技術。

為了便於講述,我們假設有這樣一個網絡拓撲結構:




運用這個技術,必須滿足下面的條件:

  • Host A和Host B分別通過Firewall A和Firewall B經過NAT用UDP連接到了Server
  • Firewall A和Firewall B都滿足這樣的特性,即來自相同IP相同Port的數據包,不管目的地IP是多少, 都會NAT成相同的IP+Port,舉個例子吧:Host A通過UDP Port 1234訪問主機S1時,防火牆會把數據包NAT成114.35.31.111:5566(舉例),那麼Host A通過UDP Port 1234訪問主機S2時,防火牆仍然會把數據包NAT成114.35.31.111:5566 。好在現在的NAT基本上都具備這個特性。

穿透原理:
現在,Host A用UDP端口1111連接到Server的5555端口,Host B用端口2222連接到Server的5555端口,在Server看來,Host A來自114.35.31.111:9676(Firewall A NAT過了嘛),Host B則來自114.33.22.222:6573。於是Server可以將HOST B的外部IP(114.33.22.222:6573)告訴Host A,反之亦然。IP當Host A想直接連接Host B時,它這樣做:

  • A用UDP端口1111發一個數據包給114.33.22.222:6573,這個數據包被Firewall A NAT成114.35.31.111:9676 -> 114.33.22.222:6573; 千萬別期望Host B會收到這個數據包,因為當包到達Firewall B時,Firewall B被弄糊塗了,它根本不知道114.35.31.111:9676 -> 114.33.22.222:6573的數據包應該轉給誰,當然這個包就會被丟棄並回一個ICMP包說Port不存在。但是,我們還是得到了我們想要的一些東西,那就是我們成功地告訴了Firewall A "如果有114.33.22.222:6573 -> 114.35.31.111:9676的數據包,請轉發到A的192.168.0.70:1111",這就是一個洞!!
  • 接下來,和你想像的一樣,Host A通過Server中轉,告訴Host B,用端口2222發一個數據包到114.35.31.111:9676,Host B照辦了,而且這個包一定會被Firewall B NAT成114.33.22.222: 6573 -> 114.35.31.111:9676。這個回復的數據包同樣在Firewall B上鑽了個孔,凡是114.35.31.111:9676 -> 114.33.22.222:6573的包都會被轉發到B的192.168.0.80:2222,當數據包到達Firewall A時,Firewall A很高興地把2.2 .2.2:6573 -> 114.35.31.111:9676的數據包轉發給A的192.168.0.70:1111。
  • 大功告成了,Host A和Host B開始愉快的交談起來。

很簡單吧?不過實施起來還要注意幾點,否則你都不知道為什麼總連不上:

  • 步驟1中那個Port不存在的ICMP是個殺手,至少對Linux上用iptables做的NAT來講是這樣,因為Firewall A收到這個ICMP會關閉剛鑽上的洞,想辦法不讓Firewall B發這個ICMP或者讓Firewall A丟掉這個ICMP吧;
  • 時間問題,步驟1在Firewall A上開的洞洞是有時間限制的,通常為30-60秒吧,如果超時了都沒收到114.33.22.222:6573 -> 114.35.31.111:9676的包,洞洞會自動關閉,同樣步驟2以後,Host A也應該及時在發個數據包給B,以保證Firewall B上的洞洞不會因為超時而關閉。值得提一下的是多數NAT防火牆會在看見進出雙向的數據包後延長關閉洞洞的時間,Linux默認設置時會延長到3分鐘。
  • Host A不能連到Host B,並不表示Host B一定連不到Host A,反一下方向試試也許會有意外驚喜。

NAT大致分為下面四類

1) Full Cone
這種NAT內部的機器A連接過外網機器C后,NAT會打開一個端口.然后外網的任何發到這個打開的端口的UDP數據報都可以到達A.不管是不是C發過來的.
例如 A:192.168.8.100 NAT:202.100.100.100 C:292.88.88.88
A(192.168.8.100:5000) -> NAT(202.100.100.100 : 8000) -> C(292.88.88.88:2000)
任何發送到 NAT(202.100.100.100:8000)的數據都可以到達A(192.168.8.100:5000)

2) Restricted Cone
這種NAT內部的機器A連接過外網的機器C后,NAT打開一個端口.然后C可以用任何端口和A通信.其他的外網機器不行.
例如 A:192.168.8.100 NAT:202.100.100.100 C:292.88.88.88
A(192.168.8.100:5000) -> NAT(202.100.100.100 : 8000) -> C(292.88.88.88:2000)
任何從C發送到 NAT(202.100.100.100:8000)的數據都可以到達A(192.168.8.100:5000)

3) Port Restricted Cone
這種NAT內部的機器A連接過外網的機器C后,NAT打開一個端口.然后C可以用原來的端口和A通信.其他的外網機器不行.
例如 A:192.168.8.100 NAT:202.100.100.100 C:292.88.88.88
A(192.168.8.100:5000) -> NAT(202.100.100.100 : 8000) -> C(292.88.88.88:2000)
C(202.88.88.88:2000)發送到 NAT(202.100.100.100:8000)的數據都可以到達A(192.168.8.100:5000)
以上三種NAT通稱Cone NAT.我們只能用這種NAT進行UDP打洞.

4) Symmetic
對於這種NAT.連接不同的外部目標.原來NAT打開的端口會變化.而Cone NAT不會.雖然可以用端口猜測.但是成功的概率很小.因此放棄這種NAT的UDP打洞.
https://link.zhihu.com/?target=http%3A//blog.csdn.net/jq0123/article/details/840302


把4種類型分別標為1234,有兩台主機A:portA和B:portB(port都為外網端口,是與打洞服務器通信的端口),以及打洞服務器S,情景是B拿到了A:portA的信息,要與A通信。
(1)、A為類型1;無論B為哪種類型,都可以直接與A:portA udp通信;

(2)、A為類型2;無論B為哪種類型,在A知道B之前都無法直接連接,B給S發一個打洞請求,S轉發該請求到A。若B的類型為1,則A:portA可直接與B:portB udp通信;若B的類型為2或3,則A:portA和B:portB各自向對方發送一個一字節的udp包,分別在自己的路由器上打洞,從此A:portA和B:portB可進行udp通信;若B為類型4,則portB在與不同的ip:port通信時會不一樣,所以A:portA先向B發送一個一字節的udp包,在路由器上打洞,然后等待B:portB先發送數據,A:portA接收到B:portB的數據后,即知道portB,也可互通數據了;

(3)、A為類型3;無論B為哪種類型,在A知道B之前都無法直接連接,B給S發一個打洞請求,S轉發該請求到A。若B的類型為1,則A:portA可直接與B:portB udp通信;若B的類型為2或3,則A:portA和B:portB各自向對方發送一個一字節的udp包,分別在自己的路由器上打下洞,從此A:portA和B:portB可進行udp通信;若B為類型4,則portB在與不同的ip:port通信時會不一樣,而A又要求知道portB的才可讓B:portB連進來,所以這種情況A只能猜測與A:portA通信的portB,通信概率小;

(4)、A為類型4;無論B為哪種類型,在A知道B之前都無法直接連接,B給S發一個打洞請求,S轉發該請求到A。若B的類型為1,則A:portA可直接與B:portB udp通信;若B的類型為2,則B:portB先向A發送一個一字節的udp包,在路由器上打洞,然后等待A:portA先發送數據,B:portB接收到A:portA的數據后,即知道portA,也可互通數據了;若B的類型為3,見(3)中B為類型4的描述;若B為4,雙方無法知道對方的端口,無法通信。ps:純手打,根據工作中的理解整理。

对称 NAT 的穿透方法
https://github.com/jflyup/nat_traversal

STUN :RFC 5389 - Session Traversal Utilities for (NAT) (STUN)
https://tools.ietf.org/html/rfc5389

ICE:RFC 5245 - Interactive Connectivity Establishment (ICE): A Methodology for Network Address Translator (NAT) Traversal for Offer/Answer Protocols
https://tools.ietf.org/html/rfc5245

REF

沒有留言:

張貼留言