IPv6 vs. IPv4
我一直對IPv6這個(gè)名字感到困惑,因為我覺(jué)得IPv4名字來(lái)源于它用來(lái)表示32位的四個(gè)字節,所以IPv6應該被稱(chēng)為IP16。但實(shí)際上,這只是協(xié)議的版本號。在IPv4推出之前,曾存在過(guò)IPv1、IPv2和IPv3,它們主要用于內部研究IP協(xié)議,后來(lái)被我們現在的IPv4所取代。在上世紀80年代,還提出過(guò)IPv5的提案,旨在優(yōu)化實(shí)時(shí)通信,但大家發(fā)現IPv6能解決地址空間問(wèn)題后,該提案就被放棄了,因此才有了IPv6這個(gè)名字,代表互聯(lián)網(wǎng)協(xié)議第6版。后來(lái)有人嘗試創(chuàng )建IPv7、IPv8等更高版本,但它們要么已被廢棄,要么被擱置起來(lái)。和IPv4一樣,IPv6有自身的尋址方案,但它使用的是128位地址而非IPv4的32位地址。這兩種協(xié)議之間的差異不僅體現在地址空間大小上,而且與IPv4對比,IPv6有其獨特特性,比如:
IPv6沒(méi)有子網(wǎng)掩碼
IPv6和IPv4同樣支持CIDR(無(wú)類(lèi)別域間路由),但從用戶(hù)角度看,IPv6地址要簡(jiǎn)單得多:前半部分是全球互聯(lián)網(wǎng)地址,后半部分是本地地址。這是推薦的IPv6地址使用方式。當你訪(fǎng)問(wèn)某個(gè)顯示IP地址的網(wǎng)站如WhatismyipWhatever時(shí),它會(huì )顯示出你的IPv6地址形式如下:
1111:2222:3333:4444:5555:6666:7777:8888
但是,你的互聯(lián)網(wǎng)服務(wù)提供商(ISP)只知道你的前綴部分為1111:2222:3333:4444,并將這個(gè)/64的地址塊分配給你。地址的剩余部分對你的網(wǎng)絡(luò )中的每一臺設備都是獨一無(wú)二的。ISP只會(huì )將所有以1111:2222:3333:4444開(kāi)頭的數據包轉發(fā)至你的路由器,然后路由器會(huì )將數據包進(jìn)一步傳遞到目標設備。因此,地址的后半部分(5555:6666:7777:8888),我們可以稱(chēng)之為INTERFACE_ID,這部分對于你的設備來(lái)說(shuō)是唯一的。這就意味著(zhù)你擁有的每一臺設備都擁有一個(gè)獨特的IPv6地址,可以從世界任何地方單獨訪(fǎng)問(wèn),原因在于:
IPv6 不使用 NAT 技術(shù)
實(shí)際上,針對 IPv6 的 NAT(Network Address Translation,是指網(wǎng)絡(luò )地址轉換) 并不存在公開(kāi)的標準規范。雖然有一個(gè)名為 NAT66 的草案提議,但至今并未轉化為現實(shí)標準。之所以在 IPv6 中不需要 NAT,是因為理論上地球的每個(gè)設備都可以有一個(gè)獨立的全球可訪(fǎng)問(wèn)的地址。開(kāi)始我對此感到很奇怪,因為在玩網(wǎng)絡(luò )游戲時(shí)雖然我們常常痛恨 NAT 導致的種種不便,但它卻給人一種安全感,除非你明確通過(guò) UPnP 或端口轉發(fā)允許,否則你的本地設備永遠不會(huì )被外部網(wǎng)絡(luò )直接訪(fǎng)問(wèn)。有一個(gè)殘酷的事實(shí)是,NAT 并不是一道安全屏障,它只是一個(gè)替代的數據包轉發(fā)機制。在默認情況下,你的IPv6路由器本不應隨意將來(lái)自外部的連接嘗試轉發(fā)給本地設備。因此,在 IPv6 環(huán)境下,即便不使用 NAT,你也同樣可以獲得相同級別的安全保障。實(shí)際上,借助IPv6地址,你無(wú)需經(jīng)過(guò)路由器,或者不必另行配置VPN,就能直接訪(fǎng)問(wèn)本地網(wǎng)絡(luò )上的每一臺設備:只需要進(jìn)行身份驗證即可。盡管IPv6為每臺設備分配獨立的IPv6地址帶來(lái)了便利,但也存在一個(gè)與安全相關(guān)的問(wèn)題:由于每個(gè)設備都有獨一無(wú)二的地址,因此它們可以被個(gè)別識別和跟蹤,這對我們的隱私保護構成威脅。為此,現代操作系統引入了臨時(shí)IPv6地址的概念,該地址的INTERFACE_ID會(huì )定期變化。這樣一來(lái),你可以使用永久IPv6地址接收外部的連接請求,而在建立連接時(shí),對外展示的是一個(gè)頻繁變動(dòng)的二級臨時(shí)地址作為你的IPv6地址。
接下來(lái)我們繼續探討IPv6的特性:
IPv6地址具備自動(dòng)配置功能
IPv6協(xié)議無(wú)需依賴(lài) DHCP 服務(wù)器或手動(dòng)網(wǎng)絡(luò )配置來(lái)確定IP地址、子網(wǎng)掩碼及網(wǎng)關(guān)地址。一臺設備可以不通過(guò)詢(xún)問(wèn)中央服務(wù)器而自主獲取IP地址。這一過(guò)程是通過(guò)一個(gè)名為 SLAAC(Stateless Address Autoconfiguration,無(wú)狀態(tài)地址自動(dòng)配置)的協(xié)議實(shí)現的,具體步驟如下:
操作系統(特別是操作系統的IPv6堆棧)會(huì )生成一個(gè)64位的設備標識符,通常是隨機生成的,比如5555:6666:7777:8888,這個(gè)標識符構成了你的IPv6地址INTERFACE_ID部分。
- 操作系統會(huì )在該INTERFACE_ID前加上fe80,這是僅限本地使用的IPv6網(wǎng)絡(luò )前綴。因此,你現在得到的 IPv6 地址是:fe80::5555:6666:7777:8888。(請注意這里的”a::b”語(yǔ)法表示的是:“在’a’和’b’之間存在所有值為零的段”。關(guān)于這點(diǎn)我們稍后再詳細介紹。)
- 你的設備會(huì )將一個(gè)數據包發(fā)送到本地網(wǎng)絡(luò )上指定的鄰居多播組,以確保沒(méi)有其他設備使用相同的IPv6地址,這被稱(chēng)為重復地址檢測(DAD)。而分配到重復地址的幾率很小。
- 設備將它獲取到的本地地址發(fā)送給路由器(與IPv4不同,在IPv6中,路由器始終可以通過(guò)組播地址ff02::2被訪(fǎng)問(wèn)到),并通過(guò)發(fā)送一個(gè)RS(路由請求)ICMPv6數據包來(lái)請求路由器的實(shí)際前綴。路由器收到請求后,會(huì )通過(guò)RA(路由通告)數據包回應,并用回復的實(shí)際前綴替換掉fe80,設備隨后開(kāi)始使用這個(gè)新的地址作為其永久地址。這就是你現在的IPv6互聯(lián)網(wǎng)地址。
如此一來(lái),無(wú)狀態(tài)配置的優(yōu)勢在于減少了路由器上的管理開(kāi)銷(xiāo):路由器無(wú)需單獨維護網(wǎng)絡(luò )中每個(gè)設備的IP配置信息。意味著(zhù)這將可以帶來(lái)更好的性能表現,特別是在大型網(wǎng)絡(luò )中尤為明顯。
IPv6的“神話(huà)”
IPv6也有一些夸大的說(shuō)法,我們一起梳理澄清下:
確實(shí),你會(huì )使用同一個(gè)IPv6地址進(jìn)行本地和遠程連接。但是,“一統天下之IP地址,尋遍萬(wàn)物之IP地址”的說(shuō)法并不準確。正如我之前所提到的,你的設備會(huì )為了不同范圍的目的聲明多個(gè)IPv6地址,比如鏈路本地(fe80::)和互聯(lián)網(wǎng)。此外,你的設備也可能獲得兩個(gè)不同的公網(wǎng)IPv6地址:永久地址和臨時(shí)地址。臨時(shí)IPv6地址旨在保護你的隱私,它們會(huì )定期輪換。而永久IPv6地址主要用于必須具有靜態(tài)IPv6地址的服務(wù)器。
還遠遠不夠的。宇宙中大約有22?2個(gè)原子,地球約有21??個(gè)原子,所以我們至少需要168位(八位對齊)的地址空間來(lái)容納它們。實(shí)際上,IPv6的地址空間略小于128位:前16位是IANA預留的。因此,你只能用剩下的112位來(lái)標識設備。盡管這非常多,遠超過(guò)我們在未來(lái)幾千年里地球上可能制造的所有設備的數量,但并不能為每一個(gè)原子分配一個(gè)獨立的IP地址。然而,我們可以為地球上的每一粒沙子分配IPv6地址,甚至我們還可以將這些地址全部裝進(jìn)一個(gè)單一的/64前綴內??傊?,IPv6地址空間是極其龐大的。
沒(méi)錯,IPv6沒(méi)有NAT機制,這意味著(zhù)不再需要端口轉發(fā)或維護地址空間。但是,如果你想建立直接連接,仍然需要有一種機制允許遠程主機連接到你的設備。默認情況下,你的路由器/防火墻會(huì )阻止任何連接嘗試。你會(huì )怎么做呢?就像UPnP/IGD時(shí)代一樣,今天的應用程序仍然需要與PCP(端口控制協(xié)議)這類(lèi)協(xié)議配合工作,才能以編程方式打開(kāi)端口訪(fǎng)問(wèn)權限。所以,并不是說(shuō)你突然間就能憑借全局+本地IPv6地址實(shí)現通用連接。雖然你不必手動(dòng)設置端口轉發(fā),但應用程序仍需與路由器協(xié)作才能使自身變得可訪(fǎng)問(wèn)。
從我看來(lái),在某些情況下,IPv6的表現甚至不如IPv4:
IPv6的不足之處
在IPv4環(huán)境下,我們習以為常的一些功能,當過(guò)渡到IPv6后可能會(huì )讓你懷念,例如:
由于IPv6不采用NAT技術(shù),許多美國ISP默認只向你的路由器轉發(fā)一個(gè)64位前綴(通常稱(chēng)為“/64”)。這意味著(zhù)路由器無(wú)法在IPv6地址中嵌入子網(wǎng)信息。要知道,IPv6地址是由設備自動(dòng)配置的,因此路由器無(wú)法強制這些設備使用小于64位的本地地址,這讓路由器無(wú)法知道應該將數據包轉發(fā)到哪個(gè)子網(wǎng)。你得依賴(lài)于ISP提供短于64位的前綴,這樣你的路由器才能利用剩余的比特位來(lái)識別數據包應當發(fā)往哪個(gè)子網(wǎng)。理論上講,通過(guò)分配60位前綴,ISP實(shí)際上完全有能力給家庭用戶(hù)提供至少16個(gè)子網(wǎng),但不知道為何他們并沒(méi)有這樣做?;蛟S是因為他們在IPv4地址空間匱乏時(shí)期的心理創(chuàng )傷讓他們變得貪婪?或者是他們想通過(guò)額外收費來(lái)賺錢(qián):“嘿,如果你想要更短的前綴,那就多付點(diǎn)錢(qián)給我們?!睋宜?,Comcast Xfinity和AT&T兩家公司都只為家庭用戶(hù)提供了一個(gè)簡(jiǎn)單的/64前綴:即單個(gè)子網(wǎng)。你或許會(huì )說(shuō),家庭用戶(hù)可能根本不需要子網(wǎng)劃分,但是隨著(zhù)物聯(lián)網(wǎng)設備的普及以及我們對網(wǎng)絡(luò )安全越來(lái)越高的依賴(lài)性,隔離不可信設備的重要性正在日益凸顯。歐洲IP地址分配權威機構RIPE建議住宅ISP客戶(hù)使用56位前綴,這樣每位客戶(hù)可以獲得256個(gè)子網(wǎng),這是歐洲提出最貪婪、也最保守的選項,而在美國,這幾乎是可望而不可及的夢(mèng)想。當然,你可以手動(dòng)配置每一臺設備的IPv6地址,并以此方式賦予它們子網(wǎng)標識符,但這將是一項巨大的工程,尤其是考慮到添加新設備時(shí)帶來(lái)的管理負擔。難道你想退休后變成一個(gè)人工DHCP服務(wù)器嗎?
我們可能都試過(guò)在瀏覽器輸入“http://192.168.0.1”并訪(fǎng)問(wèn)路由器設置。在URI規范中“:”字符是為端口號保留的,所以如果沒(méi)有額外的編碼,無(wú)法直接采用相同的方式來(lái)訪(fǎng)問(wèn)IPv6地址。若想通過(guò)IPv6地址訪(fǎng)問(wèn)一臺設備托管的網(wǎng)頁(yè),必須采用如下格式:
http://[aaaa:bbbb:cccc:dddd:eeee:ffff:1111:2222]/path/?query
注意地址兩邊的方括號。但這還不是最糟糕的部分,因為:
理論上我們不應去記住IP地址,但實(shí)際情況并非如此。對于IPv6地址,我至今也無(wú)法確定可靠且一致地訪(fǎng)問(wèn)自家路由器所使用的地址。確切地說(shuō),我無(wú)法記下它的完整IP地址。mDNS有助于解決這個(gè)問(wèn)題,但它也不總是穩定有效。十六進(jìn)制數字相比十進(jìn)制數字也更為復雜。這就像是試圖記憶 Windows XP 產(chǎn)品激活碼一樣困難。記住IPv4地址是一種通用技能,由于普遍存在的NAT技術(shù),多數情況下“192.168.1.1”都能派上用場(chǎng),我們無(wú)需查詢(xún)。而在任意設備上找出路由器的IPv6地址則需要不同的技巧。從積極的一面看,現在你知道IPv6地址的最右側64位部分始終是隨機生成的,所以至少可以避免誤以為它是固定不變的或者是有意義的。你可以將這一部分稱(chēng)作BLABLA而非INTERFACE_ID。你可以記住你的/64前綴,至少能找到路由器的地址,通常是類(lèi)似1111:2222:3333:4444::1這樣的形式。
當然,IPv4地址同樣復雜。你知道2130706433是一個(gè)有效的IPv4地址嗎?或者換種寫(xiě)法,0x7F000001、0177.0000.0000.0001,以及127.1其實(shí)都是一回事?如果不信,你大可在終端嘗試ping它們。雖然很難相信,但它們全等同于127.0.0.1這個(gè)地址。
IPv6地址在表示形式上也有類(lèi)似的多樣性。以下是其一些特征:
IPv6地址的表示方法相對復雜,由8個(gè)十六進(jìn)制分組組成,這些組被稱(chēng)為“hextet”(實(shí)際上“Hextet”是hexadectet的誤稱(chēng),但現在已約定俗成)。這樣一來(lái),就可能出現類(lèi)似的十六進(jìn)制表達技巧:
IPv6地址中的零值前綴不會(huì )顯示,因此2600:00ab
實(shí)際上顯示為2600:ab
。
如前所述,如果某個(gè)十六進(jìn)制四字組的值為零值,可以完全從地址中刪除,并用雙冒號代替。因此,2600:ab:0:0:1234:5678:90ab:cdef將顯示為2600:ab::1234:5678:90ab:cdef??吹诫p冒號了嗎?不過(guò)要注意的是,這種簡(jiǎn)化方式只能應用于地址中首組連續的零值四字組。因此,2600:ab:0:0:1234:0:0:cdef仍顯示為2600:ab::1234::0:cdef。另外,不能僅僅簡(jiǎn)化單個(gè)零值的十六進(jìn)制四字組。因此,2600:0:1234:5678:abcd:ef01:2345:6789中的零值保持原樣,不會(huì )被省略。你可以指定區域ID:通過(guò)在地址末尾添加“%”后綴和區域ID來(lái)指定要通過(guò)哪個(gè)網(wǎng)絡(luò )接口訪(fǎng)問(wèn)該地址。例如,當你同時(shí)通過(guò)WiFi和以太網(wǎng)連接到同一網(wǎng)絡(luò )時(shí),你可能想要通過(guò)局域網(wǎng)來(lái)ping你的路由器。在這種情況下,你需要在地址后面追加“%”符號,并添加你的區域ID(即網(wǎng)絡(luò )適配器標識符),例如fe80::1%eth0或fe80::1%3。問(wèn)題是,在IPv6 URI中除了需要用到方括號之外,你在瀏覽器地址欄或其他需要在URI中使用區域ID的地方,還必須將“%”轉義為“%25”。IPv6地址還可以用來(lái)表示IPv4地址。因此,你可以通過(guò)在其前方添加IPv4轉換前綴的方式,使用IPv6地址語(yǔ)法來(lái)ping 127.0.0.1,這時(shí)它將被視為一個(gè)IPv4地址,即:::ffff:127.0.0.1。但這并不意味著(zhù)你的IPv4請求會(huì )通過(guò)IPv6網(wǎng)絡(luò )進(jìn)行傳輸,而是告訴底層網(wǎng)絡(luò )協(xié)議棧使用IPv4連接。如果選擇不同于::ffff的前綴,IPv4部分將會(huì )被合并到最后兩個(gè)十六進(jìn)制字節中,并通過(guò)IPv6網(wǎng)絡(luò )與該IP地址建立連接。例如,IPv6地址2600:1000:2000:3000::192.168.1.1會(huì )被視為2600:1000:2000:3000::c0a8:101,其中最后兩個(gè)十六進(jìn)制字節相當于IPv4地址192.168.1.1的十六進(jìn)制表示形式。
這些都是有效的IPv6地址:
:: 表示所有零,即0:0:0:0:0:0:0:0.
2600::相當于2600:0:0:0:0:0:0:0.
::ffff:1.1.1.1 等同于IPv4地址1.1.1.1 。
2607:f8b0:4005:80f::200e 是我ping google.com時(shí)獲取的地址,與2607:f8b0:4005:80f:0:0:0:200e等效??梢钥闯?,像Facebook一樣,Google也選擇了艱難的道路,決定為其IPv6地址手動(dòng)分配特定的INTERFACE_ID。
最終,在地址欄中輸入的IPv6地址可能看起來(lái)像下面這個(gè)人為構造的例子:
https://[542b:b2ae:ed5c:cb5a:e38b:2c49:123:192.168.1.1%25eth3]
我可記不住這么長(cháng)的地址。
通過(guò)這次學(xué)習,讓我對IPv6的相關(guān)知識有了更清晰的認識。例如,我以前不知道IPv6地址是通過(guò)無(wú)狀態(tài)協(xié)議自動(dòng)配置的,也不知道IPv6中沒(méi)有NAT技術(shù),更不了解地址空間是如何恰好被便捷地劃分為兩半的。
我希望我們能有一個(gè)指向默認網(wǎng)關(guān)的快捷IPv6地址,我提議使用fe80::1。國際互聯(lián)網(wǎng)工程任務(wù)組(IETF),不妨考慮一下這個(gè)提議哦!我還記得當初Windows 2000宣布支持IPv6時(shí),那是個(gè)重大的進(jìn)步,我們都認為IPv6將在十年左右的時(shí)間里被廣泛采用。沒(méi)想到我們錯得離譜!然而,通過(guò)對IPv6的學(xué)習,我才理解到為什么這項技術(shù)沒(méi)有快速普及起來(lái)。
- IPv6并未對終端用戶(hù)提供實(shí)質(zhì)好處
盡管IPv6在技術(shù)上較為先進(jìn),但IPv4卻簡(jiǎn)單實(shí)用,即使是在NAT(網(wǎng)絡(luò )地址轉換)之后,甚至是多層NAT環(huán)境下,面對地址空間極度緊張、DHCP配置繁瑣、端口轉發(fā)復雜的條件下,IPv4依然能夠正常運作。只要出現問(wèn)題,總有人找到解決方案使其繼續工作。理論上IPv6因無(wú)需NAT可能具有更低延遲的優(yōu)勢,但這點(diǎn)改進(jìn)還不足以顯著(zhù)提升用戶(hù)體驗,不足以讓用戶(hù)強烈要求切換至IPv6。正因為IPv6并未帶來(lái)直觀(guān)可見(jiàn)的好處,用戶(hù)并不會(huì )主動(dòng)要求使用,往往是在他們不知情的情況下被推向IPv6,就像我們現在在移動(dòng)網(wǎng)絡(luò )中幾乎默認使用IPv6一樣。這意味著(zhù),一旦互聯(lián)網(wǎng)服務(wù)提供商感受到IPv4的限制帶來(lái)的足夠壓力時(shí),它們將會(huì )立刻切換到IPv6。我希望IPv6能夠開(kāi)啟一些IPv4無(wú)法實(shí)現的獨特功能場(chǎng)景,讓用戶(hù)能夠因為想要使用這些功能而主動(dòng)需求IPv6。盡管如此,我還是喜歡IPv6特質(zhì),期待有一天我們完全放棄IPv4,轉而圍繞IPv6來(lái)構建所有網(wǎng)絡(luò )服務(wù)。
技術(shù)人怎么看?
正如作者在開(kāi)頭說(shuō)自己并非是IPv6、網(wǎng)絡(luò )工程的專(zhuān)家,讀完他的文章后,一些開(kāi)發(fā)者提出自己的觀(guān)點(diǎn):開(kāi)發(fā)者@9dev 表示,對終端用戶(hù)而言,真正的益處在于整個(gè)互聯(lián)網(wǎng)協(xié)議?;貧w到它應有的完全透明狀態(tài)。用戶(hù)不應該再需要操心IP地址問(wèn)題;IPv6使得設備真正實(shí)現“即插即用”,即設備能夠自行獲取地址,自行協(xié)商連接。理想情況下,用戶(hù)再也不必關(guān)心這部分連接問(wèn)題。的確,IPv6給網(wǎng)絡(luò )運營(yíng)商帶來(lái)了復雜性,但這也是復雜性應當的。
@lxgr 在學(xué)習這篇文章后,針對作者提到的一些看法,有不同的意見(jiàn):
針對“IPv6沒(méi)有子網(wǎng)掩碼”的說(shuō)法,他認為絕對是有子網(wǎng)掩碼的,只不過(guò)在IPv6中它們被稱(chēng)為前綴長(cháng)度。/64前綴剛好適合與SLAAC(無(wú)狀態(tài)地址自動(dòng)配置)配合使用。
針對“IPv6沒(méi)有NAT”的說(shuō)法,同樣,IPv4也沒(méi)有自帶NAT。NAT是一種路由器可以選擇實(shí)現的技術(shù),當然在IPv6中也同樣可行。例如,Linux操作系統就實(shí)現了IPv6的NAT,只擁有一個(gè)IPv6地址的情況下,例如從本地網(wǎng)絡(luò )獲得一個(gè)地址并在機器上運行虛擬機時(shí),IPv6的NAT可能是必不可少的。針對“IPv6地址是自配置的”的說(shuō)法,有時(shí)確實(shí)是這樣,但也有時(shí)候并非如此,還有DHCPv6和靜態(tài)配置的方式。針對“IPv6地址無(wú)法記住”的說(shuō)法,那又怎樣呢?反正他也沒(méi)興趣記住IPv4地址、電話(huà)號碼等信息。針對“IPv6對終端用戶(hù)沒(méi)有好處”的說(shuō)法,作為終端用戶(hù),他發(fā)現IPv6給我帶來(lái)了很多好處:
防火墻穿越比NAT穿越更可預測且成功率更高。像VoIP、Tailscale等服務(wù)在IPv6環(huán)境下相比跨越一層或多層NAT的成功率大大提高。
- 家里的所有設備都可以獲取公網(wǎng)地址,他可以通過(guò)路由器上的防火墻規則選擇性地開(kāi)放入站連接。
移動(dòng)網(wǎng)絡(luò )上的路由更為直接,從而降低了延遲(IPv4常常需要通過(guò)一系列昂貴且具有狀態(tài)的CG-NAT設備,在使用的移動(dòng)網(wǎng)絡(luò )服務(wù)商部署IPv6的地區,這種情況得以避免)。