天天看點

一文讀懂IPv6協定棧

作者:yongfxu

1.前言

目前我們接觸得比較多的主流作業系統核心,已經能夠很好地支援IPv6協定棧,例如:

  1. Windows: windows 7、windows 8.x、windows 10,預設開啟IPv6;
  2. Linux: 核心2.6.x、核心3.x、核心4.x 已經支援IPv6(需要手動開啟);
  3. iOS:IOS9開始已經支援IPv6 Only,2016年蘋果已經強制要求app必須支援IPv6。

本系列文章提到的IPv6節點,沒有特殊說明,一般指的是純IPv6節點(IPv6 Only),也就是隻支援IPv6協定棧。IPv4節點,是指純IPv4的節點,也就是隻支援IPv4協定棧。如果節點支援IPv6和IPv4雙棧,會指明是雙棧節點。

2.基本概念

2.1 IPv6的封包格式

衆所周知,32位的IPv4位址已經接近耗竭,IPv6采用128位的位址長度擁有更大的位址空間。

一文讀懂IPv6協定棧

圖表 1 IPv6資料封包

上圖是我們最熟悉的ping的IPv6版本ICMPv6,可以看到,IPv6資料封包和IPv4有很大的差别:

  • 資料鍊路層(L2)的type字段辨別為 0x86dd,表示承載的上層協定是IPv6(IPv4對比:type字段為0x0800);
  • IPv6的頭部字段,和IPv4差别巨大,是以IPv6和IPv4無法相容。
一文讀懂IPv6協定棧

圖表 2 IPv6封包頭部

IPv6封包頭部更精簡,字段更少,對比起IPv4,有以下幾個地方值得注意:

  • IPv6封包頭部是定長(固定為40位元組),IPv4封包頭部是變長的。這個意味着,寫代碼處理IPv6資料封包的效率會提高很多;
  • IPv6中Hop Limit字段含義類似IPv4的TTL;
  • IPv6中的Traffic Class字段含義類似IPv4中的TOS(Type Of Service);
  • IPv6的封包頭部取消了校驗和字段:取消這個字段也是對IPv4協定的一個改進。當IPv4封包在網路間傳輸,每經過一個路由器轉發就是修改TTL字段,就需要重新計算校驗和,而由于資料鍊路層L2和傳輸層L4的校驗已經足夠強壯,是以IPv6取消這個字段會提高路由器的轉發效率。值得一提的是,在IPv6協定下,傳輸層L4協定UDP、TCP是強制需要進行校驗和的(IPv4是可選的);
  • IPv6封包頭部中的Next Header字段表示“承載上一層的協定類型”或者“擴充頭部類型”。當IPv6資料封包承載的是上層協定ICMPv6、TCP、UDP等的時候,Next Header的值分别為58、6、17,這個時候和IPv4封包頭部中的Protocol字段很類似;當不是以上3種協定類型的時候,IPv6封包頭部緊接的是擴充頭部。擴充頭部是IPv6引入的一個新的概念,每個IPv6的資料封包可以承載0個或多個擴充頭部,擴充頭部通過連結清單的形式組織起來。當IPv6資料封包承載着擴充頭部的時候,Next Header的數值為擴充頭部的類型值。引入擴充頭部這個概念,是IPv6對IPv4改進的一個方面,用擴充頭部取代了IPv4的可選項資訊,精簡了IPv6的頭部,增強了IPv6的擴充性。
一文讀懂IPv6協定棧

圖表 3 IPv6分片封包

當發送一個分片IPv6資料封包的時候,IPv6使用的是擴充頭部的形式組織各個分片的資訊,如圖IPv6封包頭部Next Header字段值為44表示存在擴充頭部,擴充頭部是IPv6分片資料資訊。在IPv4的報頭中包含了幾乎所有的可選項,是以每個中間路由器都必須檢查這些選項是否存在。在IPv6中,這些相關選項被統一移到了擴充報頭中,這樣中間路由器不必處理每一個可能出現的選項(僅有“逐跳選項”報頭是必須要處理的),提高了處理器處理資料封包的速度,也提高了其轉發的性能。

2.2 IPv6的位址文法

一個IPv6的位址使用冒号十六進制表示方法:128位的位址每16位分成一段,每個16位的段用十六進制表示并用冒号分隔開,例如一個普通公網IPv6位址:

2001:0D12:0000:0000:02AA:0987:FE29:9871

IPv6位址支援壓縮前導零的表示方法,例如上面的位址可以壓縮表示為:

2001: 0D 12:0:0:2AA:987:FE29:9871

為了進一步精簡IPv6位址,當冒号十六進制格式中出現連續幾段數值0的位段時,這些段可以壓縮為雙冒号的表示,例如上面的位址還可以進一步精簡表示為:

2001:12:0:2AA:987:FE29:9871

又例如IPv6的位址FF80:0:0:0:FF:3BA:891:67C2可以進一步精簡表示為:

FE80::FF:3BA:891:67C2

注意:雙冒号隻能出現一次。

2.2.1号段劃分和字首表示法

IPv6擁有128位巨大的位址空間,對于那麼大的空間,也不是随意的劃分,而是使用按照bit位進行号段劃分。IPv6的位址結構如下圖:

一文讀懂IPv6協定棧

圖表 4 IPv6位址結構

例如RFC4291中定義了n=48, m=16,也就是全局路由字首與子網和接口ID各占64位。IPv6支援子網字首辨別方法,類似于IPv4的無分類域間路由CIDR機制(注意:IPv6沒有子網路遮罩mask的概念)。

使用“IPv6位址/字首長度”表示方法,例如:2001:C3:0:2C6A::/64表示一個子網;而2001:C3:0:2C6A:C9B4:FF12:48BC:1A22/64表示該子網下的一個節點位址。可以看到,一個IPv6的位址有子網字首+接口ID構成,子網字首由位址配置設定和管理機構定義和配置設定,而接口ID可以由各作業系統實作生成。

2.2.2 接口ID生成算法

從前面的介紹中可以看出,IPv6單點傳播位址是由字首(64位)+接口ID(64位)組成。接口ID的生成算法主要有以下幾種:

  • 接口ID可以從EUI-64位址生成(EUI-64就是mac位址中間插入FFFE,然後第七位置位。例如:一台電腦的MAC是00:0C:85:AB:50:01,中間插入FFFE:00:0C:85:FF:FE:AB:50:01,然後由左到右第七位置位: 02:0C:85:FF:FE:AB:50:01,這台電腦的EUI-64就是020C:85FF:FEAB:5001)
  • 為了可以具備某種程度的匿名信,接口ID可以使用一個随機配置設定的,windows作業系統預設就是使用這種生成算法,Linux下也是預設開啟這個算法;
  • 使用狀态化的自動配置技術配置設定,例如DHCPv6配置設定;
  • 手工配置。

2.3IPv6的位址類型

IPv6位址分三種類型:

  • 單點傳播,對應于IPv4的普通公網和私網位址;
  • 多點傳播,對應于IPv4的多點傳播(多點傳播)位址;
  • 任意播,IPv6新增的位址概念類型。

IPv6沒有廣播位址,用多點傳播位址實作廣播的功能。實際上我們工作和生活最多接觸的就是單點傳播位址。

2.3.1 單點傳播位址

IPv6單點傳播位址主要有以下幾種。

全球單點傳播位址

一文讀懂IPv6協定棧

圖表 5 IPv6全球單點傳播位址結構

字首2000::/3,相當于IPv4的公網位址。這種位址在全球的路由器間可以路由。

鍊路本地位址

一文讀懂IPv6協定棧

圖表 6 鍊路本地位址結構

字首FE80::/10,顧名思義,此類位址用于同一鍊路上的節點間的通信,主要用于自動配置位址和鄰居節點發現過程。Windows和Linux支援或開啟IPv6後,預設會給網卡接口自動配置一個鍊路本地位址。也就是說,一個接口一定有一個鍊路本地位址。如下圖:

一文讀懂IPv6協定棧

圖表 7 Linux下檢視鍊路本地位址

一文讀懂IPv6協定棧

圖表 8 Windows下檢視鍊路本地位址

每個接口必須至少有一個鍊路本地位址;每個接口可以配置1個以上的單點傳播位址,例如一個接口可以配置一個鍊路本地位址,同時也可以配置一個全球單點傳播位址。

注意:很容易會把鍊路本地位址和IPv4的私網/内網位址對應起來,其實鍊路本地位址對應于IPv4的APIPA位址,也就是169.254開頭的位址(典型場景就是windows開啟自動擷取位址而擷取失敗後自動配置設定一個169.254的位址)。

唯一本地位址

一文讀懂IPv6協定棧

圖表 9 唯一本地位址結構

字首FC00::/7,相當于IPv4的私網位址(10.0.0.0、172.16.0.0、192.168.0.0),在RFC4193中新定義的一種解決私網需求的單點傳播位址類型,用來代替廢棄使用的站點本地位址。

在IPv4中,利用NAT技術私網内的網絡節點可以使用統一的公網出口通路網際網路資源,大大節省了IPv4公網位址的消耗(IPv6推進緩慢的原因之一)。另一方面,由于預設情況下私網内節點與外界通信的發起是單向的,網絡通路僅僅能從私網内發起,外部發起的請求會被統一網關或者防火牆阻隔掉,這樣的網絡架構很好的保護了私網内的節點安全性和私密性。是以,在安全性和私密性要求下,IPv6中同樣需要支援私網,并且也需要支援NAT。在Linux核心3.7版本開始加入對IPv6 NAT的支援,實作的方式和IPv4下的差别不大

站點本地位址

字首FEC9::/48,以前是用來部署私網的,但RFC3879中已經不建議使用這類位址,建議使用唯一本地位址。

回環位址

0:0:0:0:0:0:0:1或::1,等同于IPv4的127.0.0.1

過渡位址

過度位址是指在IPv6的某一些十六進制段内嵌這IPv4的位址,例如IPv6位址中64:ff9b::10.10.10.10,此IPv6位址最後4個位元組内嵌一個IPv4的位址,這類位址主要用于IPv6/IPv4的過渡技術中。

2.3.2 多點傳播位址

IPv6的多點傳播位址通常是為IPv6的多點傳播服務,而IPv6通信的核心大量的使用了多點傳播,IPv6不再使用廣播,這與IPv4的通信不同。(注意:IPv6的通信過程依賴于鄰居發現協定(NDP),而NDP協定又是基于IPv6的多點傳播進行工作的)

而對于IPv6多點傳播位址是由固定的8bit位址字首FF::/8,4bit的标志位,4bit多點傳播範圍和112bit多點傳播組辨別符(組ID)組成。如下圖所示。“标志”字段用于說明多點傳播位址是“永久性(由IANA指定的一個位址)”的,還是“臨時性”的。而對于該4bit标志字段,一般情況下,其高3bit位為0,剩下的低1bit位就是用于判斷多點傳播位址是“永久性”還是“臨時性”。如果低1bit位為0,則表示為“永久性多點傳播位址”,也就是一個衆所周知的多點傳播位址,如FF02::1表示在IPv6環境中一個鍊路上的所有計算機節點、FF02::2表示一個鍊路上的所有路由器節點,類似于IPv4的224.0.0.1和224.0.0.2。如果為“1”就是“臨時性多點傳播位址”。

一文讀懂IPv6協定棧

圖表 10 多點傳播位址格式

"範圍"的取值:

  • 1代表本地接口範圍
  • 2代表本地鍊路範圍
  • 3代表本地子網範圍
  • 4代表本地管理範圍
  • 5代表本地站點範圍
  • 8代表組織機構範圍
  • E代表全球範圍

2.4 位址配置

IPv6一個比IPv4更厲害的方面,就是可以自動配置位址,甚至這個配置過程不需要DHCPv6(在IPv4中是DHCPv4)這樣的位址配置協定。最典型的例子就是,隻要開啟了IPv6協定棧的作業系統,每個接口就能自動配置了鍊路本地位址,這個是和IPv4最重要的差別之一。IPv6的位址配置有以下幾種:

  • 隻要開啟了IPv6協定棧,接口自動配置設定鍊路本地位址;
  • 無狀态自動配置位址;
  • 有狀态自動配置位址,例如DHCPv6。
  • 手動配置。

2.5 域名解析

由于IPv6的位址擴充為128位,比IPv4的更難書寫和記憶,是以IPv6下的DNS變得尤為重要。IPv6的的DNS資源記錄類型為AAAA(又稱作4A),用于解析指向IPv6位址的完全有效域名。下面是一個示例:

Hostipv6.example.wechat.com IN AAAA 2001:db8:1::1

3. PingV6流程解析

本章節的目的是,根據上述章節的理論基礎,通過抓包分析ping指令的流程。抓包結果如下:

一文讀懂IPv6協定棧

圖表 11 ping ipv6位址的抓包結果

如上圖,發現在發送Echo之前,有一個類似于IPv4的ARP過程,該過程即為NDP鄰居發現協定的基礎。通過上述描述,我們可以了解到,IPv6是沒有廣播位址的,而是通過多點傳播位址來實作資料鍊路層位址解析

在IPv4環境的的ARP位址解析協定是使用目标MAC位址為廣播位址(255.255.255.255或者FFFF.FFFF.FFFF)将MAC位址請求消息發送到整個以太網鍊路上的所有主機,即便是A主機隻請求D主機的MAC,B主機與C主機也同樣會收到這個請求廣播,從性能與效率上講這明顯不科學。是以在IPv6的環境中放棄了廣播的的方式,而是采用多點傳播方式将MAC位址的解析請求,以點對點的形式直接多點傳播到D主機的請求節點多點傳播位址FF02::1:FF54:319E。而不再将請求消息發送到無關的主機B和主機C,是以IPv6的節點請求的确是高效率去替代IPv4的ARP協定。總而言之就是使用點到點的方式去代替廣播。

節點請求主機能夠以一種“點對點”的形式将MAC位址請求消息發送到目标主機D,是因為D主機的請求節點多點傳播位址FF02::1:FF54:319E在整個鍊路上是唯一的,是以源主機可以直接将節點請求資訊發到目标主機節點請求多點傳播位址上。目的鍊路本位址為fe80::202:c9ff:fe54:319e,取出IPv6主機的本地鍊路位址的後24位“54:319e”,填充到“FF02:0000:0000:0000:0000:0001:FF”字首中,形成最後的位址:FF02:0000:0000:0000:0000:0001:FF54:319e,使用“零壓縮”法表示成為:FF02::1:FF54:319e。

在IPv4的ARP位址解析協定中的ARP請求封包的目标MAC位址為FFFF.FFFF.FFFF,在IPv6中,多點傳播的MAC位址是通過IPv6的多點傳播IP位址映射而來,映射的原則是:将IPv6多點傳播位址的後32位取出,填充到固定字首是3333的MAC位址中來生成資料鍊路層位址。多點傳播IP位址為FF02::1:FF54:319e,取出該位址的最後32個二進制位,一個十六進制位就為4個二進制位,是以最後32個二進制位就是FF54:319e,将這部分填充到IPv6多點傳播MAC的固定字首3333,就得到多點傳播MAC位址是3333: FF54:319e。

一文讀懂IPv6協定棧

圖表 12多點傳播IP位址與多點傳播MAC位址

目的PC在收到該請求後,即應答請求:

一文讀懂IPv6協定棧

圖表 13 鄰居應答消息

主機收到應答後,即可取出源MAC位址,儲存到MAC表中。之後就開發發送Echo,如下圖所示:

一文讀懂IPv6協定棧

圖表 14 ICMPv6的Echo請求

一文讀懂IPv6協定棧

圖表 15 ICMPv6的Echo應答