![](https://img.laitimes.com/img/__Qf2AjLwojIjJCLyojI0JCLicmbw5SZxUmY0UTMkVGM3YmNhdDOiFWYkVGNhdTZ1kTO1UjM58CX0JXZ252bj91Ztl2Lc52YucWbp5GZzNmLn9Gbi1yZtl2Lc9CX6MHc0RHaiojIsJye.png)
趙大寶
别信廣告,看療效呗~
導 言
網絡上的一台主機想和其他裝置通信,首先要擁有一個IP位址,除此之外還需要網關、路由、DNS server等,隻有正确的配置了這些資訊,它才能和網絡上的其他裝置正常通信。在IPv4中,這些資訊通常是通過DHCP(Dynamic Host Configuration Protocol)配置到主機上的。
但是在IPv6中,事情要更複雜一些……
1 DHCP協定
DHCP是C/S結構,每一個區域網路都會部署本子網的DHCP server,監聽并響應本地鍊路上的DHCP請求,主機在接入網絡之後主動發送DHCP請求消息,由于此時主機還沒有IP位址,也不知道DHCP server的IP位址,是以DHCP請求的源IP位址是0.0.0.0,目的IP位址是255.255.255.255(廣播位址),這個封包在本地鍊路上廣播。
DHCP server在收到DHCP請求之後,會為目前的client配置設定IP位址,并且将client和IP位址的映射關系記錄在其資料庫中,最後發送DHCP應答消息給client。DHCP協定完整的互動過程如下:
DHCP除了配置設定IP位址之外,還定義了豐富的可選字段(Options),通過這些可選字段為主機提供豐富的配置資訊。常用的配置資訊包括:
- IP位址
- 字首資訊
- 網關位址
- 路由資訊
- MTU
- DNSserver、domain等
與IPv4類似,IPv6也需要某種動态的位址配置協定,來實作主機IPv6位址的動态配置,不過在IPv6中,這件事情要更複雜一些。
2 IPv6位址自動配置
IPv6中相關的協定有兩個,NDP和DHCPv6,通常情況下需要兩個協定的配合才能完成IPv6主機位址的自動配置。
- NDP:全稱鄰居發現協定(Neighbor Discovery Protocol),是IPv6協定體系中最重要的一個基礎協定,它實作了位址解析、驗證鄰居是否可達、重複位址檢測、路由器發現/字首發現、位址自動配置和重定向等功能。
- DHCPv6:DHCP協定的IPv6版本,類似于IPv4的DHCP協定。
因為存在以上兩個協定,是以IPv6位址的配置分為三種模式:
- SLAAC:全稱無狀态位址自動配置(Stateless Auto Address Configuration),利用NDP下發網關和子網字首等資訊,主機根據子網字首自動生成IPv6位址;沒有DHCPv6。
- DHCPv6Stateless:利用NDP下發網關和子網字首等資訊,主機根據子網字首自動生成IPv6位址;利用DHCPv6配置DNSserver和域名等其他資訊。
- DHCPv6Stateful:利用NDP下發網關和子網字首等資訊;利用DHCPv6配置IPv6位址、DNS server和域名等其他資訊。
三種模式的對比如下表所示:
ar路由器 pppoe下發ipv6 dns_IPv6中的位址配置
3 為什麼IPv6的主機網絡配置如此複雜呢?
IPv6工作委員會認為IP位址、網關、位址字首和MTU屬于網絡層資訊(MTU雖然是鍊路層的大小,但是它決定了網絡層分片的大小),IPv6作為網絡層協定,這些資訊的配置在其鄰居發現協定中實作,承載在網絡層協定ICMPv6封包中下發。
但是DNS server和域名等被認為是應用層資訊,沒有在最初的鄰居發現協定中實作。
後來又有了DHCPv6協定,除了下發IPv6位址外,也支援下發DNS等應用層資訊。但是DHCPv6屬于應用層協定,是以它不支援下發網關、子網字首、主機路由、MTU等網絡層資訊,這些資訊還需要通過NDP來擷取。
IETF委員會的成員在此問題上分為兩派,一派認為應該在NDP中增加DNS等應用層資訊,以簡化IPv6主機的網絡配置,另一派認為應該保持設計的“純粹”,不應該在網絡層協定中下發應用層資訊,這樣的争論一直持續到了今天。同樣的争論也發生在DHCPv6協定的标準制定過程中,是以導緻了如今複雜的局面。
其實在RFC6106中,已經為NDP增加一個option字段RDNSS(Recursive DNS Server),用來設定DNS server位址,但是因為以上争議的存在,各作業系統對此支援不太一緻,Linux各發行版都已經支援,Windows目前隻有Windows 10 1703 Creators Update支援;
詳細的支援情況請參考:
Comparison of IPv6 support in operating systems
(https://en.wikipedia.org/wiki/Comparison_of_IPv6_support_in_operating_systems)
4 鄰居發現協定
鄰居發現協定是IPv6協定體系中最重要的一個基礎協定,它實作的功能很多,這裡隻介紹與主機配置相關的功能,也就是路由器發現與字首發現。
路由器發現/字首發現通過路由器請求消息(Router Solicitation,RS)和路由器通告消息(Router Advertisement,RA)來實作,具體過程如下:
- 主機啟動時,通過RS消息向路由器送出請求,源位址是Link local位址,目的位址是FF02::2(所有路由器多點傳播位址),請求位址字首和其他配置資訊,以便用于主機的配置。
- 路由器傳回RA消息,其中包括字首資訊選項(路由器也會周期性地釋出RA消息)。
- 節點利用路由器傳回的RA消息中的位址字首及其他配置參數,自動配置接口的IPv6位址及其他資訊,接口位址可以使用按照IEEE EUI-64的定義構造,其他資訊包括了網關位址、其他明細路由、DNS等。
協定的互動過程如下圖所示:
5 IEEEEUI-64
路由器下發的RA封包隻攜帶子網字首,沒有具體的IP位址。在Stateless和SLAAC模式下,主機需要根據字首資訊自動構造IPv6位址,一種常見的構造方式成為EUI-64。
EUI-64格式位址由位址字首和接口辨別兩部分組成,字首固定為64位,接口辨別符64位。IEEEEUI-64規定了這種情況下64位接口辨別符的構造方式。
IEEE EUI-64規定接口辨別符由MAC位址構造,而MAC位址隻有48位,是以在MAC位址的中間位置(從高位開始的第24位後)插入十六進制數FFFE,二進制表示為1111111111111110。
為了確定從MAC位址得到的接口辨別符是唯一的,還要将MAC位址的Universal/Local 位(從高位開始的第7位)設定為“1”,最後得到的這組數就作為EUI-64格式的接口辨別符。
IEEE EUI-64隻是接口辨別符構造的方式之一,Linux系統預設使用該标準。不過還有其他的構造方式,比如Windows預設就采用随機生成方式産生接口标志符。
6 Linux主機的配置
前面介紹的三種配置方式各有優缺點,比如SLAAC雖然最簡單,但是要求掩碼長度必須為64,位址浪費嚴重,另外也不支援下發DNS sever和域名等應用層資訊;DHCPv6 Stateful最靈活,可以對IP位址精确控制,但是需要部署DHCPv6 server,比較複雜。
使用者在将自己的主機接入IPv6網絡的時候,需要根據目前網絡使用的位址配置模式來配置作業系統,才能正确的擷取IPv6位址,這裡以CentOS7為例介紹主機作業系統的配置。
配置的關鍵有兩點,一是是否接受RA封包,二是DHCP client的配置。
是否接收RA通過sysctl的accept_ra參數配置,其中0表示不接受RA;1表示如果forwarding是關閉的就接受RA,如果forwarding是打開的則不接受RA(代表主機可能作為一個路由器);2表示不論forwarding是打開還是關閉,都接受RA。
在上面的介紹中,無論是stateful、stateless還是slaac,都需要通過RA配置網關和MTU等,accept_ra需要配置為1或者2。
編輯檔案/etc/sysctl.conf,添加如下内容:
net.ipv6.conf.all.autoconf=1
net.ipv6.conf.all.accept_ra=1
net.ipv6.conf.all.forwarding=0
net.ipv6.conf.default.autoconf=1
net.ipv6.conf.default.accept_ra=1
net.ipv6.conf.default.forwarding=0
net.ipv6.conf.eth0.autoconf=1
net.ipv6.conf.eth0.accept_ra=1
net.ipv6.conf.eth0.forwarding=0
DHCP client可以通過sysconfig腳本配置。比如要配置DHCPv6 Stateful時編輯配置檔案/etc/sysconfig/network-scripts/ifcfg-eth0,内容如下:
BOOTPROTO=dhcp
DEVICE=eth0
IPV6INIT=yes
IPV6_AUTOCONF=yes
DHCPV6C=yes
DHCPV6C_OPTIONS=-nw # 支援dhclient立即(nowait)變為daemon,而不是等待直到擷取一個IPv6位址
ONBOOT=yes
TYPE=Ethernet
USERCTL=no
如果要配置DHCPv6 stateless模式,隻需要将上面配置檔案中的DHCPV6C_OPTIONS設定為"-S",訓示dhclient隻擷取IPv6位址之外的其他資訊。
如果要配置SLAAC模式,隻需要将上面配置檔案中的DHCPV6C設定為"no",表示關閉DHCPv6 client。
另外目前CentOS 7發行版的dhclient有BUG,它将掩碼長度固定為64,導緻實際子網路遮罩長度不等于64的時候路由會出問題。DHCPv6下發的位址資訊中隻包含了IPv6位址,沒有提供子網的掩碼資訊,實際的掩碼/鄰居資訊是通過路由器的RA封包下發的,dhclient正确的做法是設定IPv6位址的掩碼為128,然後由路由器通過RA封包配置路由資訊。
往期精彩内容回顧
1 | S3請求來了,該怎麼處理? |
2 | 初探Docker的網絡模式 |
3 | OpenStack Policy鑒權大解密! |
聽說長得好看的人都點了贊和在看!