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