1.引IPv6的標(biāo)準(zhǔn)中不建議使用NAT,個中緣由何在?這是一個問題,正如我很早之前解釋的那樣,IPv4的NAT打破了互聯(lián)網(wǎng)本身的“互聯(lián)”特性,使得一部分IP地址不再雙向可達,NAT為無方向的IP協(xié)議增加了一個方向,特別是stateful的NAT類型。然而IPv4的NAT旨在節(jié)約IP地址,而非所謂的增加IP的方向性以及隱藏私有IP,這些只是一種難以擺脫的副作用罷了。IPv6的時代已經(jīng)到來,只要不擴展到外太空,地球上的螞蟻都可以使用IP設(shè)備了。IPv4的一些修補手段將不再需要,為了保持協(xié)議本身以及相關(guān)標(biāo)準(zhǔn)的純潔性,IPv6幾乎不再提起NAT。雖然不再提起,并不是說“你已不是你”,實現(xiàn)IPv6的NAT還是可能的,并且在某些情形下還是必要的。 2.相關(guān)的RFCRFC6296的標(biāo)題是IPv6-to-IPv6 Network Prefix Translation,描述了IPv6下的NAT的實現(xiàn)要點,給出了一個合理的建議,既保持了IP的無方向性,又可以滿足NAT的語義,這就是IPv6之NAT stateless的緣由,你不能再指望像IPv4的NAT那樣只需要配置一條rule,然后反方向的rule動態(tài)生成,IPv6情況下,兩個方向的rule都需要你自己手工來配置。3.IPv6子網(wǎng)和NAT的關(guān)系IP地址可以劃分為幾個段,包括網(wǎng)絡(luò)前綴,子網(wǎng)標(biāo)識,主機標(biāo)識,這在IPv4和IPv6中沒有什么不同。IPv4的NAT為了節(jié)約IP地址,也就是說,可供映射的IP地址pool中的地址小于或者遠(yuǎn)遠(yuǎn)小于其內(nèi)部主機的數(shù)量,因此很有可能多個內(nèi)部主機被映射成了同一個外部IP地址,這如何來區(qū)分它們,因此不得不引入諸如第四層協(xié)議,端口等信息了,也就是我們熟知的五元組信息,因此IPv4的NAT實現(xiàn)大多數(shù)都是基于五元組流的,這樣就保證了內(nèi)核保持的NAT信息項的唯一性,同時也引入了很多副作用。IPv6地址持有將近128位可隨意調(diào)配的位,鑒于地址空間的龐大,一般的單位都會被分配到一個擁有很大量地址的網(wǎng)段,此網(wǎng)段擁有足夠多的地址來和內(nèi)網(wǎng)主機進行一一映射,也就是說可用于映射的IP地址pool容量巨大無比,關(guān)鍵是這個一一映射如何來保持,既然不想再使用非IP層的信息來保持信息,那就要用純IP層的信息了,這樣對上層影響最小。對于IPv4,經(jīng)典NAT使用了五元組來保持流標(biāo)識信息,而對于IPv6,則更加絕妙,它利用(而不是使用)了checksum的算法,絲毫不管這個checksum是誰的checksum,因為它根本就不改變數(shù)據(jù)包的checksum... 4.IPv6和鏈路層的關(guān)系IP標(biāo)識一臺主機,而MAC標(biāo)識一個網(wǎng)絡(luò)接口,它們其實是一對多的關(guān)系,然而現(xiàn)實中,一個IP往往會和一塊網(wǎng)卡相關(guān)聯(lián),其中一個緣由就是可以自動生成鏈路層的路由信息。這是很方便的,然而對于IPv4,地址是自己配置或者通過DHCP來分配的,管理過程十分復(fù)雜,一不小心就會有地址沖突,不得不依靠ARP廣播/RARP等技術(shù)來檢測,之所以出現(xiàn)這種狀況,一則因為分層理念太教條,誰說IP和鏈路層就不能有關(guān)聯(lián),誰說IP標(biāo)示主機就不能關(guān)聯(lián)網(wǎng)卡;二則因為IPv4地址空間太小,而MAC地址長度一般都會超過IP地址,雖然滿足了RFC標(biāo)準(zhǔn)上的一對多的關(guān)系,但是使用起來很不方便。IPv6解決了這個問題,使得地址沖突問題減緩以致幾乎消失。我們知道,MAC地址標(biāo)示了一塊物理設(shè)備,是看得見摸得著的,有時你摸一下還會碰到靜電,MAC地址和你的身份證號碼一樣不會重復(fù),IPv6將MAC地址映射到IPv6地址解決了IP地址沖突的大問題,同時這對于NAT也是有益的,這會影響到地址的自動轉(zhuǎn)換,每一個不會重復(fù)的內(nèi)部地址轉(zhuǎn)換為一個不會重復(fù)的外部地址,這一切都要歸功于IPv6的地址空間的巨大,可以隨意雜耍。 5.checksum無關(guān)性和自動轉(zhuǎn)換這個很好解釋,小學(xué)畢業(yè)就應(yīng)該能理解??紤]a b c d=X 其中X就是checksum,我們把a,b當(dāng)成源IP地址的兩部分,c,d當(dāng)成目的IP地址的兩部分,我們作源地址轉(zhuǎn)換,將a和b都改變,比如a改變成了A,試問將b改成多少才能保持checksum的值X不變,這其實很簡單,就是一個簡單的一元一次方程求解的問題。IPv6的建議NAT實現(xiàn)也是這個原理,只不過上面的一元一次方程是實數(shù)域的,而這個是計算機布爾數(shù)域。既然可以不觸動第四層的checksum值,那么NAT對第四層協(xié)議的影響也就減小了,雖然它還是解決不了諸如ESP/AH等穿越NAT的問題。 基于以上算法,IPv6在做NAT的時候,在給定的子網(wǎng)網(wǎng)段內(nèi),可以自動生成一個新的IP地址供映射之用,從算法本身來看,沖突的可能性非常之小致于0,上述的做法對于IPv4幾乎是不可能的,因為IPv4地址空間太小了,每個單位保有的地址池容量也有限,你不能指望一個算法為你生成一個IP地址,因為這種生成的地址要不根本就不屬于自己,地址沖突,要么就是重復(fù),和其它的映射沖突。 既然IPv6的NAT機制“自動”為一個連接選擇了一個IP地址,那么當(dāng)返回包到來的時候,如何來把地址轉(zhuǎn)換回原來的呢?我們知道,IPv6的NAT已經(jīng)不再使用五元組來維護NAT映射信息,也不在內(nèi)核維護這種信息,那么“轉(zhuǎn)換回去”這件事就要完全靠算法本身了,恰恰就是算法本身能將轉(zhuǎn)換后的地址再轉(zhuǎn)回原來的,其依據(jù)就是本小節(jié)最開始處給出的一元一次方程解的唯一性,在IPv6的NAT實現(xiàn)中,算法只針對IP地址中16位的地址信息進行自動生成,而其它的則需要手工顯式配置,由于內(nèi)網(wǎng)IPv6地址可以使用MAC地址映射成唯一的地址,由于一元一次方程解的唯一性,那么轉(zhuǎn)換后的地址也是唯一的,將這一切反過來,最后還是能映射回原始的IP地址的。 如果拋開地址轉(zhuǎn)換這一說,僅僅考慮算法本身,那還是可以給出一個實際可以運行的代碼的,該代碼使用了計算checksum的算法:
運行結(jié)果如下: 結(jié)果斐然。把以上的原理套用在IPv6的NAT上,就是一種實現(xiàn)。 6.Linux上的MAP66如果有一個點子,總會有人實現(xiàn)它,何況如果不僅僅是一個點子而是一個標(biāo)準(zhǔn),那么實現(xiàn)它就更是情理之中了。Linux是一個大熔爐,更是一個實驗場,一些草案的最新進展總是會體現(xiàn)了Linux上,IPv6的NAT也不例外。MAP66是一個基本遵循RFC6296建議的Linux實現(xiàn),編譯安裝很簡單,詳見其README,想試一下嗎?很簡單,和IPv4的iptables一樣:1.配置正向的轉(zhuǎn)換規(guī)則,將源地址fdca:ffee:babe::/64網(wǎng)段的地址轉(zhuǎn)換為2008:db8:1::/64網(wǎng)段的地址 ip6tables -t mangle -A POSTROUTING -s fdca:ffee:babe::/64 -o eth2 -j MAP66--src-to 2008:db8:1::/64 可以看出,沒有顯式指定任何具體地址,類似IPv4的MASQUERADE和IPv4的IP Pool,原理詳見第5節(jié)。 2.配置反向包的轉(zhuǎn)換規(guī)則,將正向包被轉(zhuǎn)換過的地址再轉(zhuǎn)換回去 ip6tables -t mangle -A PREROUTING -d 2008:db8:1::/64 -i eth2 -j MAP66 --dst-to fdca:ffee:babe::/64 可以看出,也沒有顯式指定任何具體的地址,更值得一提的是,內(nèi)核并不維護任何關(guān)于NAT映射的信息,因此MAP66也不再依賴ip(6)_conntrack。 |
|
|