IPv6 地址分配----实验
IPv6 地址分配----实验
本文是配合上一篇IPv6地址分配理论部分的实验,部分理论细节也会在本文说明。
由于IPv6协议相关的概念于对比IPv4增加很多,而且标准至今为止仍然在变动,本文为了更贴近现实部分实验直接使用实际网络环境进行观察,笔者互联网环境为 FTTH 家庭宽带--天津联通,光猫/ONU为 Huawei OptiXstar HN8346X6 (10G EPON)。
网卡 IPv6 地址初始化过程
-
虚线框不是网络通信,代表在系统本地执行;
-
首先系统在网卡上执行 link-local 自动配置,使用某种算法生成该网卡的 link-local 地址(单播);
-
一个单播地址生成时,会随之产生一个对应的节点组播地址(solicited-node multicast address),作为 NS 的目的地址,接收来自其他节点的 NS 请求;
-
系统发送
MLDv2 Report Exclude 模式报文
用于加入上面提到的节点组播地址
组,图中并未体现; -
接下来对刚生成的 link-local 地址进行 DAD 检测,通过 DAD 后 link-local 单播地址才可以使用;
-
随后发起 RS 请求,使用刚刚生成的 link-local 地址作为原地址向 ff02::02 组播组发送 RS 请求,该组播组代表链路内全体路由器,也就是说路由器会监听此地址;
-
路由器收到 RS 后会向组播地址 ff02::01 发送 RA 作为响应,ff02::01 代表链路范围内全体节点;路由器也可以使用单播的形式发送 RA 作为响应,这取决于路由器的配置;
-
收到路由器回复的 RA 后,提取出 RA 报文内可用的信息用于网络配置;
-
根据 RA 中的 flag 网卡采取相应的配置方式:
- A = 1:使用 RA 中的信息采用 SLAAC 方式配置网卡地址;
- M = 1:使用 DHCPv6 有状态方式配置网卡;
- M = 0 and O = 1:使用 DHCPv6 无状态方式配置网卡;
-
同样的,生成的单播地址同样需要 DAD 才算正式生效,并加入对应的节点组播组;
-
至此,网卡的自动配置基本结束;
下面看一个win10 网卡启动的抓包:
图中展示了win10系统开机后,通过SLAAC加无状态DHCPv6方式对IPv6网络进行配置,下面对各个报文分别解释说明(图中序号并不连续是因为过滤了IPv4等不相关的报文)。
-
No.28 这是一个NS报文用于 link-local 单播地址的DAD
- 源MAC: 终端mac地址
- 目的MAC: IPv6组播mac地址,33:33/16的mac前缀,ipv6组播mac地址的数量还是很大的,不再像ipv4组播那样局促;
- 源IP: :: 空白源IP,因为此时还没有没有源ip只能使用空白代;
- 目的IP: DAD solicited node multicast地址;
- Target: DAD 的地址(单播)---- fe80::8ccd:2fb1:8357:b9a6;
-
No.29 RS 报文,请求 RA
- 源MAC : 终端mac地址
- 目的MAC : 组播mac,对应ff02::2
- 源IP : 刚刚通过 DAD 的link-local 地址
- 目的IP : ff02::2 代表广播域内的路由器;
-
No.30 这是 link-local 地址对应的 solicited node multicast地址加组报文
- 源MAC :终端mac
- 目的MAC :组播mac,对应 ff02::16
- 源IP :link-local 地址
从逻辑上说 DAD 和 solicited node multicast地址加组应该是有先后顺序的,正常认为应该先加组再DAD,因为DAD的目的地址为solicited node multicast地址,但实际抓包发现不同系统处理的方式并不一致,上述的win10执行的是先DAD后加组,下面的linux终端先加组再DAD;不同的操作系统或网络栈在处理IPv6地址配置和DAD过程中可能存在实现上的差异。一些实现可能在DAD开始时延迟加入solicited-node组播组,直到DAD过程需要发送邻居请求消息时才执行加入操作。再有就是有可能是加组和DAD是并行发送的,数据包的前后时间差很短。
- 目的IP :ff02::16 代表广播域内所有支持MLDv2的路由器;用于组播地址加组;
- MLRM报文 :此报文使用加入指定的IPv6组播组,此例中加入的组播组为 link-local 地址的 solicited node multicast地址---- ff02::1:ff75:b9a6 。
-
No.31 RA 报文,包含prefix等重要信息
- 源MAC :路由器的mac地址
- 目的MAC :组播mac,对应ff02::1
- 源IP :路由器的link-local 这里是fe80::1
- 目的IP :ff02::1 代表广播域内所有支持IPv6的节点。
- flag: M=0 O=1 使用DHCPv6 无状态方式配置网络
- PIO:
- prefix:IPv6 前缀
- Valid lifetime:有效期3天,如果此处为0意味着需要撤销该prefix;
- flag:A=1 这意味着要求终端使用 SLAAC,加上前面的flag O协同完成IPv6地址配置;
- Recursive DNS server:RA推送的DNS,此方式配置DNS的方式比较新,老旧的终端不一定支持,仍需要从DHCPv6中获取。
-
No.32 这是两个SLAAC地址对应的 solicited node multicast地址加组报文
- 源MAC :终端mac
- 目的MAC :ff02::16 对应的组播mac
- 源IP : link-local 地址,此时 SLAAC 地址尚未通过 DAD
- 目的IP :ff02::16
-
No.34 & 35 DHCPv6无状态,请求和回复
- 源MAC:请求DHCP的终端mac
- 目的MAC:ff02::1:2 对应的组播 mac
- 源IP:link-local 地址
- 目的IP:ff02::1:2 代表DHCP服务器、代理、或者中继
- DHCPv6内部字段见后面解释:由于 RA 中 flag M=0 O=1,此处终端DHCPv6 client仅仅请求Option,即无状态模式;
- 源MAC:DHCP 服务器mac地址
- 目的MAC:终端的单播mac,此处终端发起时候使用的是link-local地址,服务器回包的时候也单播回复。
- 源IP:服务器 link-local 单播地址
- 目的IP:终端的 link-local 单播地址
-
No.40 & 41 NS请求网关的 link-local 地址及 NA 回复
- 源MAC:终端mac
- 目的MAC:fe80::1对应的组播mac,此处可知NS为组播发送;(NS 也有单播发送的,主要用于探测邻居当前可达性)
- 源IP:终端link-local地址
- 目的IP:网关的link-local fe80::1
- 源MAC:路由器的mac
- 目的MAC:终端的mac,由此可知NA为单播回复
- 源IP:路由器的link-local fe80::1
- 目的IP:终端的link-local
- Flags:
- R:路由器标记,置1表明 NA 的发送者是一个路由器,正如此报文中显示的。
- S:请求标记,1表明 NA 是为了回复 NS 发送的,否则是主动发送的 NA 或是一个 DAD,主动发送的行为类似IPv4环境下中的免费arp(Gratuitous ARP)
- O:替代标志,置1表示通告中的信息替代缓存,如更新链路层地址时,对于任播的回应则不应置位。在针对任播地址的请求通告中,以及在请求的前缀通告中它不能被置1。在其他请求通告中和在非请求通告中它应当被置1。目标节点请求的链路层地址,响应多播的 NS 时(DAD、地址解析),必须使用该选项;响应单播的 NS 时(NUD 邻居不可达检测),可以使用该选项。
这里着重说明一下,IPv6 环境下的邻居表更新可以是单向的,也就是说如果请求报文中没有标记O=1,对方是不应该刷新邻居表项,仅需要回复NA。更进一步的讲 NS 请求的“源”、“目”和“被请求地址”之间没有强相关性;对于普通单播里这好像没什么用,这种情况主要出现在任播情况下,所以上面才说
对于任播的回应则不应置位
。
-
No.44 45 48 50 MDNS和LLMNR组播加组
mDNS 对应的组播地址为:ff02::fb
LLMNR 对应的组播地址为:ff02::1:3
-
No.53 55 56 均为组播 dns 查询相关,不予细节展示
-
No.62 & 63 NS报文,两个 SLAAC 地址的DAD
这两个地址分别是 win10 生成的基于硬件标识产生的地址以及临时IPv6地址,由于硬件标识生成的地址有可能被追溯的风险,所以大多数操作系统会启用临时地址作为隐私拓展。此处显示的仅仅是干刚刚开机网卡获取的地址,随着开机时间的增长会有更多IPv6地址被系统使用,比如这里显示的。
-
No.64 一次性组播加组
此处把前面出现过的组播地址汇总同一再次加组,具体为什么会有这种行为笔者也不是很清楚;估计是系统定期发送,用于定期刷新加入的组播组。
-
No.66 67 68 网关NS请求 SLAAC 地址并收到NA回复,并对此 SLAAC地址使用 ping 方式探活
此处返回的 NA 中,flag R 并没有置1,和No.41 报文对比,回复者的身份并非路由器,而是终端;S和O按照要求正常置1;
此处路由器发起了icmpv6 echo request用于终端探活,由于win系统防火墙的默认设置不响应ping请求,所以此请求没有对应的回应;由于前面已经响应了路由器的NS请求,此处ping探活只是辅助非强制。
-
No.69 70 73 SSDP 组播地址加组,并发起SSDP,细节略;
-
其余报文大多为 DNS 解析和发起tcp连接,用于探测internet连通信,细节略;
从上可以看出,伴随IPv6地址的生成或获取,会有DAD和solicited node multicast地址加组行为:
- IPv6单播地址,无论是独立生成的还是从其他地方获取的,即使是静态地址,系统在使用之前都需要进行 DAD,只有通了 DAD 的地址才可以使用。
- 节点多播地址 (Solicited-node Multicast)和单播地址是对应的,但不是一一对应的。一个 IPv6 单播地址对应一个节点多播地址,但是反过来不成立。在 IPv6 环境中,每个单播地址对应的Solicited-node Multicast地址是通过将单播地址的最后24位添加到一个固定的前缀(FF02::1:FF00:0/104)形成的。这意味着多个单播地址可能会对应同一个Solicited-node Multicast地址,因为不同的单播地址可能有相同的最后24位。
ff02/16 的组播地址是 IANA 定义的 well-known 组播地址,用于代表一些特殊的节点组;下面一些例子:
- ff02::1 all nodes 本地链路范围的所有节点
- ff02::2 all routers 本地链路范围的所有路由器
- ff02::1:2 DHCP_Relay_Agents_and_Servers
- ff02::16 所有MLDv2-capable routers
- ff02::fb mDNSv6
- ff02::1:3 LLMNR
- ff02::c SSDP
- 完整的列表请参见这里
SLAAC
和 SLAAC 相关的算法是 eui-64,基于 RA 中的 prefix 和length 使用 eui-64 算法生成全局地址,然后发起 DAD,通过 DAD 后的地址才供操作系统使用;但是 eui-64 是基于硬件标识的,有一定的概率泄露终端的隐私,所以现今操作系统出于隐私考虑会使用其他算法生成地址,避免关联硬件标识;
所以广义的 SLAAC 为:基于 RA 中的 Prefix/Length,通过某种算法生成单播地址并通过 DAD,即可称为 SLAAC。
DHCPv6 无状态
以一下描述主要来自这里
DHCPv6(Dynamic Host Configuration Protocol for IPv6,支持IPv6的动态主机配置协议)针对IPv6编址方案设计,用来为主机分配IPv6前缀、IPv6地址和其他网络配置参数。
DHCPv6服务器可以为已经具有IPv6地址/前缀的客户端分配其他网络配置参数,该过程称为DHCPv6无状态配置。
DHCPv6客户端通过地址无状态自动配置功能成功获取IPv6地址后,即DHCPv6客户端根据路由器发现/前缀发现所获取的信息自动配置IPv6地址后,如果接收到的RA(Router Advertisement,路由器通告)报文中M标志位(Managed address configuration flag,被管理地址配置标志位)取值为0、O标志位(Other stateful configuration flag,其他配置标志位)取值为1,则DHCPv6客户端会自动启动DHCPv6无状态配置功能,以获取除地址/前缀外的其他网络配置参数。
DHCPv6无状态配置的具体过程为:
1.客户端以组播的方式向DHCPv6服务器发送Information-request报文,该报文中携带Option Request选项,指定客户端需要从服务器获取的配置参数。
2.服务器收到Information-request报文后,为客户端分配网络配置参数,并单播发送Reply报文将网络配置参数返回给客户端。
3.客户端检查Reply报文中提供的信息,如果与Information-request报文中请求的配置参数相符,则按照Reply报文中提供的参数进行网络配置;否则,忽略该参数。如果接收到多个与请求相符的Reply报文,客户端将选择最先收到的Reply报文,并根据该报文中提供的参数完成客户端无状态配置。
DHCPv6 无状态请求与回复的细节:
DHCPv6 有状态
DHCPv6 服务器为客户端分配地址/前缀的过程分为两类:
- 交互四个消息的分配过程
- 交互两个消息的快速分配过程
常规 DHCPv6 请求
步骤 | 发送的消息 | 说明 |
---|---|---|
1 | Solicit | DHCPv6客户端发送该消息,请求DHCPv6服务器为其分配IPv6地址/前缀和网络配置参数 |
2 | Advertise | 如果Solicit消息中没有携带Rapid Commit选项,或Solicit消息中携带Rapid Commit选项,但服务器不支持快速分配过程,则DHCPv6服务器回复该消息,通知客户端可以为其分配的地址/前缀和网络配置参数 |
3 | Request | 如果DHCPv6客户端接收到多个服务器回复的Advertise消息,则根据消息接收的先后顺序、服务器优先级等,选择其中一台服务器,并向该服务器发送Request消息,请求服务器确认为其分配地址/前缀和网络配置参数 |
4 | Reply | DHCPv6服务器回复该消息,确认将地址/前缀和网络配置参数分配给客户端使用 |
快速确认 DHCPv6 请求
快速分配过程:
(1)DHCPv6 客户端在向 DHCPv6 服务器发送的 Solicit 消息中携带 Rapid Commit 选项,标识客户端希望服务器能够快速为其分配地址/前缀和其他网络配置参数。
(2)如果DHCPv6服务器支持快速分配过程,则直接返回Reply消息,为客户端分配IPv6地址/前缀和其他网络配置参数。如果DHCPv6服务器不支持快速分配过程,则采用“交互四个消息的分配过程”为客户端分配IPv6地址/前缀和其他网络配置参数。
DHCP-PD
PD 是一类特殊的有状态 DHCPv6,用于分配分一个网段给dhcp client 而不是一个主机地址;(上篇文章中谈到的pd-only由于是草案,当前并没有相关的软件/硬件实现此项功能,故无法实验,此处仅演示了常规DHCP-PD)
既然是是一种有状态DHCPv6,两包(rapid commit)交互和四包交互同样适用:
此时,DHCP返回的就不是一个主机地址而是一个网段。
地址撤销
如上图,当修改路由接口的ipv6地址前缀时候,路由器会发送prefix lifetime = 0的 RA 用于通知终端此网段撤销请重新监听后续 RA,用新 RA 中的prefix 重新 SLAAC(下图就是重新发送的ra)。
基于策略的地址配置
本文至此已经太长了😁,此部分是对 RS/RA 和 DHCPv6的灵活应用,独立成文。
环境和配置
上述所有演示和抓包都是基于下面环境完成,由于在时间上不是一次性完成,不同案例之间获取的地址可能不一致。
路由器(H3C vSR1000)使用DHCP-PD 从光猫获取了一段地址(此处是/63的地址段),分别使用DHCPv6无状态(结合SLAAC)和有状态分配给 WIN10-1 和 WIN10-2 两台电脑(win10 系统)。
拓扑:
WIN10网卡:
有状态,即服务器段会保留终端信息,就像IPv4 中的 DHCP一样:
完整配置:
#以下配置基于H3C vSR1000 Version 7.1.064, Release 1362P12
#
dhcp enable
# 定义prefix-pool , 此处pool 引用了pd拿到的prefix 1
ipv6 dhcp prefix-pool 1 prefix 1 assign-len 64
# IPv4 地址池vlan100
dhcp server ip-pool vlan100
gateway-list 192.168.100.254
network 192.168.100.0 mask 255.255.255.0
address range 192.168.100.11 192.168.100.200
dns-list 223.5.5.5
forbidden-ip 192.168.100.1
forbidden-ip 192.168.100.254
# IPv4 地址池vlan200
dhcp server ip-pool vlan200
gateway-list 192.168.200.254
network 192.168.200.0 mask 255.255.255.0
address range 192.168.200.11 192.168.200.200
dns-list 223.5.5.5
forbidden-ip 192.168.200.1
forbidden-ip 192.168.200.254
# IPv6 有状态地址池
ipv6 dhcp pool statefull
network prefix 1 0:0:0:1::/64 ## pd获取的 prefix 生成的/64 network
dns-server 2001:4860:4860::8888 ## DNS
dns-server 2001:4860:4860::8844 ## DNS
prefix-pool 1 preferred-lifetime 86400 valid-lifetime 259200 ## 引用prefix-pool
option-group 1
# IPv6无状态地址池
ipv6 dhcp pool stateless
option-group 1 # 引用了从PD获取的option
#
interface GigabitEthernet1/0
port link-mode route
ip address dhcp-alloc
nat outbound
ipv6 address auto ## SLAAC 地址
ipv6 address auto link-local ## SLAAC link-local
ipv6 dhcp client pd 1 option-group 1 ## 使用PD获取网段和option,获取到的prefix命名为“1”,option也命名为“1”,供其他服务引用
# 无状态
interface GigabitEthernet2/0
port link-mode route
description ipv6_stateless
ip address 192.168.100.254 255.255.255.0
dhcp server apply ip-pool vlan100
ipv6 dhcp select server
ipv6 dhcp server apply pool stateless
ipv6 address FE80::1 link-local ## 修改 link-local ,link-local的scope为link,多个接口可以使用相同link-local
ipv6 address 1 ::1/64 ## 使用pd获取的prefix生成地址
ipv6 nd autoconfig other-flag ## 置位 O flag
undo ipv6 nd ra halt ## 发送 RA(默认不发送RA)
ipv6 nd ra interval 60 20 ## ra 周期发送间隔
ipv6 nd ra invalid-delegated-prefix advertise enable ## 发送地址撤销 RA(如有)
ipv6 nd ra dns server 2400:3200::1 60 sequence 0 ## DNS
ipv6 nd ra dns server 2400:3200::BABA:1 60 sequence 1 ## DNS
# 有状态
interface GigabitEthernet3/0
port link-mode route
description ipv6_statefull
ip address 192.168.200.254 255.255.255.0
dhcp server apply ip-pool vlan200
ipv6 dhcp select server
ipv6 dhcp server apply pool statefull
ipv6 dhcp server allow-hint preference 255 rapid-commit ## 开启DHCPv6 rapid-commit 模式(可选)
ipv6 address FE80::1 link-local ## 修改 link-local ,link-local的scope为link,多个接口可以使用相同link-local
ipv6 address 1 ::1:0:0:0:1/64 ## 使用 pd 获取的 prefix 生成地址
ipv6 nd autoconfig managed-address-flag ## RA M flag 置位
ipv6 nd autoconfig other-flag ## RA O flag 置位,兼容不支持有状态模式的终端
undo ipv6 nd ra halt ## 发送 RA
ipv6 nd ra interval 60 20 ## RA 周期发送间隔
ipv6 nd ra invalid-delegated-prefix advertise enable ## 发送地址撤销 RA (如有)
ipv6 nd ra dns server 2400:3200::1 60 sequence 0 ## DNS
ipv6 nd ra dns server 2400:3200::BABA:1 60 sequence 1 ## DNS
参考
https://support.huawei.com/enterprise/zh/doc/EDOC1100174722/d14d2c80
https://www.h3c.com/cn/d_202403/2063140_30005_0.htm
https://blog.csdn.net/u013237642/article/details/101026357