小男孩‘自慰网亚洲一区二区,亚洲一级在线播放毛片,亚洲中文字幕av每天更新,黄aⅴ永久免费无码,91成人午夜在线精品,色网站免费在线观看,亚洲欧洲wwwww在线观看

分享

IPv6的NAT原理以及MAP66

 印度阿三17 2019-02-17

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)的RFC

RFC6296的標(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的算法:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

//以下2個(gè)函數(shù)就是計(jì)算校驗(yàn)碼的,具體的原理請參見RFC1071/RFC1624/RFC1141
static inline u_int16_t add16(
    u_int16_t a,
    u_int16_t b)
{
    a  = b;
    return a   (a < b);
}

static inline u_int16_t csum16(const u_int16_t *buf, int len)
{
    u_int16_t csum = 0;
    while(len--) csum = add16(csum, *buf  );
    return csum;
}


int main(int argc, char **argv)
{

    u_int16_t buf[18] = {0};
    int i = 0;
    memcpy(buf, "efghhijk", 8);
    memcpy(buf 4, "12345678", 8);
    memcpy(buf 8, "xxyywert", 8);
    memcpy(buf 12, "zxcvkljh", 8);
    //正確做法是打印16進(jìn)制數(shù)據(jù),此處為了簡單,打印了字符串
    printf("原始數(shù)據(jù):%s  長度:%d\n", (char*)buf, strlen((char*)buf));    
    printf("原始數(shù)據(jù)的校驗(yàn)碼:%X\n", csum16(buf, 16));    
    
    u_int16_t tip[3] = {0};
    memcpy(tip, "#$!%", 4);
    u_int16_t tip_sum = csum16(tip, 2);
    printf("\nNAT規(guī)則: efghhijk1234/12 -〉efghhijk#$!%/12\n\n");
    printf("固定從第9個(gè)字節(jié)開始修改4個(gè)字節(jié)為:%s 其校驗(yàn)碼為:%X\n", (char*)tip, tip_sum);
    
    //定位固定修改后的動(dòng)態(tài)修改的初始地址,注意,我們僅僅修改16位信息
    u_int16_t* pcsum = buf   4 2;  
    
    //計(jì)算動(dòng)態(tài)修改的值
    *pcsum = ~add16(
        add16(
            ~(*pcsum),
            ~csum16(buf 4, 2)
        ),
        tip_sum
    );
    printf("動(dòng)態(tài)修改的值為:%X\n", *pcsum);
    memcpy(buf 4, tip, 4); //完成修改
    
    printf("當(dāng)前數(shù)據(jù):%s  長度:%d\n", buf, strlen((char*)buf));    
    printf("當(dāng)前校驗(yàn)碼:%X\n", csum16(buf, 16));    
    printf("-------------以下是還原操作-------------\n");
    printf("\n反向NAT規(guī)則: efghhijk#$!%/12 -〉efghhijk1234/12\n\n");

    u_int16_t tip2[3] = {0};
        memcpy(tip2, "1234", 4);
    printf("我們只需要記住原始數(shù)據(jù)被固定修改前的:%s\n", tip2);

    u_int16_t tip_sum2 = csum16(tip2, 2);
    
    u_int16_t* pcsum2 = buf 6;

    *pcsum2 = ~add16(
        add16(
            ~(*pcsum2),
            ~csum16(buf 4, 2)
        ),
        tip_sum2
    );
    //還原
    memcpy(buf 4, tip2, 4);
    
    printf("原始數(shù)據(jù):%s\n", (char *)buf);
    printf("原始校驗(yàn)碼:%X\n", csum16(buf, 16));    
    
}


運(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。

    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多