4、什么是NDP协议

4.1、NDP简介

NDP(Neighbor Discovery Protocol,邻居发现协议)是IPv6协议体系中最重要的基础协议,是TCP/IP协议栈的一部分,主要与IPv6共同使用。很多IPv6功能都依赖NDP来实现。NDP协议工作在网络层,负责在链路上发现其他节点和相应的地址,并确定可用路由和维护关于可用路径和其他活动节点的信息可达性。一般说来,NDP可以实现的功能包括:替代IPv4的ARP来形成邻居表;默认网关的自动获取;无状态地址自动配置;路由重定向等。这里需要补充一句:默认网关的自动获取是路由器先发送RA报文、在这个过程中路由器会通告自己的接口本地地址、终端收到这个地址以后就把这个接口本地地址作为自己的网关。而无状态地址自动配置、是路由器在RA通告中也会含有接口本地地址的前缀、终端收到接口本地地址的前缀以后再结合自己的终端接口ID进行组合、就行成了自己的IPv6地址。

与IPv4一样,IPv6报文在局域网中传输时,仍需要被封装在数据链路层的数据帧中。以常见的局域网为例,即需要将IPv6报文封装在以太网报文中。以太网报头中有源MAC地址和目的MAC地址,二层交换机就是根据MAC地址与端口的对应表进行转发。那么,以太网如何获知目的节点的MAC地址呢?在IPv4网络中,该地址是通过广播ARP报文来获取的,一旦获知目的节点的MAC地址,就将IP和MAC的对应关系写入自身的ARP表中。而在IPv6中,ARP换成了NDP,ARP表也换成了邻居表。邻居表中记录着同一局域网内邻居的IPv6地址与MAC地址的对应关系。当需要与局域网内的邻居通信时,首先查看邻居表中是否有邻居的MAC地址;如果有,则将自己的MAC作为源MAC,邻居MAC作为目的MAC,最终将IPv6报文封装起来发送到目的地址;如果邻居表中没有目的地址的MAC地址,则使用NDP来发现并形成邻居表。当然,NDP并不仅仅用来形成邻居表,它所包含的其他表项的详细内容及用途将在后文继续介绍。

除了解析同一局域网中IPv6邻居的链路层地址,NDP还增加了路由器网关发现功能。在局域网中,自动配置地址的主机会主动寻找默认网关,而路由器默认也会通告自己是默认网关。路由器在通告自己是默认网关的同时,会携带自身的链路层地址,因此主机无须再次运行NDP来解析默认网关的链路层地址。路由器在通告自己是默认网关的同时,可以携带前缀信息,使主机可以根据获得的前缀信息自动生成IPv6地址。路由重定向也属于NDP的作用范围;IPv6中的路由重定向与IPv4中的一样,即首选的默认网关发现到达目的地有更好的路由器网关时,会向其转发数据报文,并同时向源节点发送路由重定向报文,告知源节点有更好的下一跳到达目的节点,同时会在重定向报文中携带新的网关的链路层地址。

4.2、NDP常用报文格式

NDP定义了5类ICMPv6报文,即:RS(Router Solicitor,路由器请求)报文;RA(Router Advertisement,路由器通告)报文;NS(Neighbor Solicitor,邻居请求)报文;NA(Neighbor Advertisement,邻居通告)报文和路由重定向报文。这5种类型的ICMPv6报文都是消息类型的报文,用以实现邻居链路层地址解析、网关发现、地址自动配置和路由重定向等功能。

下面我们通过测试来分别捕获一下上面讲到的几个报文格式。

image-20220119205016517

路由器配置如下:

Router>en 
Router#conf t
Enter configuration commands, one per line.  End with CNTL/Z.
Router(config)#ipv6 unicast-routing 
Router(config)#int e0/0
Router(config-if)#ipv6 add 2001:da8::1/64
Router(config-if)#no shutdown 
Router(config-if)#
*Jan 20 19:51:12.908: %LINK-3-UPDOWN: Interface Ethernet0/0, changed state to up
*Jan 20 19:51:13.914: %LINEPROTO-5-UPDOWN: Line protocol on Interface Ethernet0/0, changed state to up
Router(config-if)#

配置完成之后我们就可以在终端操作系统上看到IPv6通告报文、从下图可以看到系统提示我们是否在网络上开启设备发现功能。

image-20220119205006341

这里我们也可以看到终端的IPv6地址、如下图我们可以看到有IPv6地址、临时IPv6地址、默认网关、本地链接IPv6地址等信息。这里需要说明一下默认网关就是路由器发送的RA报文中携带的路由器本地链路地址,终端会把路由器的本地链路地址作为自己的网关;而IPv6地址就是所谓的公共IPv6地址、他是由路由器发送的RA报文中包含的前缀2001:DA8加上自己的终端自己的接口ID组合而成;临时IPv6地址是随机产生的、默认的有效期是7天、首选有效期是1天;过期之后系统会随机生成一个临时IPv6地址。

Router#sh ipv6 int e0/0
Ethernet0/0 is up, line protocol is up
  IPv6 is enabled, link-local address is FE80::A8BB:CCFF:FE00:300 
  No Virtual link-local address(es):
  Global unicast address(es):
    2001:DA8::1, subnet is 2001:DA8::/64 
  Joined group address(es):
    FF02::1
    FF02::2
    FF02::1:FF00:1
    FF02::1:FF00:300
  MTU is 1500 bytes
  ICMP error messages limited to one every 100 milliseconds
  ICMP redirects are enabled
  ICMP unreachables are sent
  ND DAD is enabled, number of DAD attempts: 1
  ND reachable time is 30000 milliseconds (using 30000)
  ND advertised reachable time is 0 (unspecified)
  ND advertised retransmit interval is 0 (unspecified)
  ND router advertisements are sent every 200 seconds
  ND router advertisements live for 1800 seconds
  ND advertised default router preference is Medium
  Hosts use stateless autoconfig for addresses.
Router#

image-20220119210823603

当然、我们也可以通过下面的命令查看邻居信息(如果没有的话、可以通过ping命令强制刷新邻居信息):

image-20220119211954836

好了、下面我们一起来看看报文的抓包情况。

RS报文

RS报文供IPv6主机用以寻求本地链路上存在的路由器,主机发送RS报文后会触发同网段的路由器立即回复RA报文,以获取前缀信息、MTU信息等;而不用等待路由器周期性的发送RA报文。IPv6主机发送RS报文时,目的地址为预定义的本地链路所有路由器的组播地址 FF02::2,原地址是自身接口以FE80打头的链路本地地址。当源地址以FE80地址打头时,源接口可以把自己的链路层地址放在RS报文的选项字段中通告给路由器,使得路由器创建IPv6地址到链路层本地地址映射关系的邻居表。

16550424183150

上图是我们捕获的RS报文。IPv6主机发送RS报文时,目的地址为预定义的本地链路所有路由器的组播地址FF02::2,源地址是自身接口以FE80打头的链路本地地址。数据链路层源地址是发送RS报文主机的MAC地址,目的地址是FF02::2对应的组播MAC地址3333.0000.0002。

RA报文

路由器会周期性(思科路由器默认是200秒)地发送RA报文,向邻居节点通告自己的存在。RA报文可以携带一些路由前缀、自身链路层等参数信息。

8141213779491

路由器会周期性(思科路由器默认是200秒)地发送RA报文通告其存在,也可以发送收到RS报文的应答报文。上图是我们捕获的RA报文,通过抓包发现:无论是路由器主动的周期性通告,还是收到RS报文后的被动应答,RA报文的目的地址都是组播地址FF02::1,这一点可能与有些文档描述的不一样,本人也认为应答的RA报文和目的地址没必要是FF02::1,是对应RS报文的发送者更合适,当然FF01::1也能达到效果,只是多骚扰了其他IPv6主机一次而已。跳数限制字段用来告知IPv6主机后面发送的单播报文将使用的默认跳数值。M位和O位(大写字母O,不是数字0)是DHCPv6相关的选项。当M位是1时,告知IPv6主机使用DHCPv6来获取IPv6地址;当O位是1时,则是告知IPv6主机使用DHCPv6获取其他参数信息,如DNS地址信息等。路由器生存期字段占16位,用来告知IPv6主机本路由器作为默认网关时的有效期,单位是秒。当该字段值为0时,表示本路由器不能作为默认路由器。可达时间选项用来告知IPv6主机邻居表中关于自己的可达信息。重传时间字段为周期性发送RA报文的时间间隔。选项字段可以包括路由器接口的链路层地址、MTU、单播前缀信息等。

NS报文

NS报文用于查询邻居节点的链路层地址。

image-20220119210404243

上图是我们捕获的NS报文。NS报文中的目的地址字段存放的是想要解析成链路层地址的IPv6单播地址。选项字段可以携带自身的链路层地址。当NS报文用于邻居可达性检测时,目的地址是单播地址;当用于邻居解析时,目的地址是被请求节点的组播地址FF02::1:FF00:0/104加目的单播地址的最后24位。IPv6节点在检测IPv6地址冲突时,也会发送邻居请求报文,此时目的IPv6地址是被请求节点的组播地址FF02::1:FF00:0/104加自己IPv6地址的最后24位,若收不到回复则表示IPv6地址没有冲突,IPv6地址配置生效。在实际配置中发现,在为Windows计算机配置IPv6地址时若存在地址冲突,不会弹出提示信息,这一点与IPv4地址的配置不同(在地址冲突时会弹出提示信息)。因此只能在命令行模式下执行ipconfig命令来查看IPv6地址是否生效。若没有生效,则可能是地址配置存在冲突。在路由器上配置IPv6地址时,若存在地址冲突,则会出现下面的提示信息:

*Jan 20 20:18:49.579: %IPV6_ND-6-DUPLICATE_INFO: DAD attempt detected for 2001:DA8::1 on Ethernet0/0

NA报文

IPv6节点通过使用NA报文来通告自己的存在,或者告诉邻居需要更新自己的链路层地址信息。

image-20220119210417278

当节点发送NA报文来回应NS报文时,目的地址使用单播地址,如果目的是告诉邻居需要更新自己的链路层地址信息,则使用组播地址FF02::1作为目的地址。需要注意的是,路由器除了发送RA报文,也会发送NA报文。NA报文中有3个标志位:当R位为1时表示此报文是由路由器发送的;当S位为1时表示这是NS报文的回复;当O位为1时则表示需要更改原先的邻居表条目。在S位为1的情况下,NA报文的源地址字段是对应的NS报文中的目的地址字段,如果S位为0,则NA报文的源地址就是自身需要更新链路层地址信息的接口IPv6地址。选项字段是发送NA报文设备的链路层地址。 上图是一个捕获的NA报文,注意其中的R、S、O位。

重定向报文

当IPv6主机设置的默认网关不是最优的下一跳时,作为默认网关的路由器会发送重定向报文告诉IPv6主机:到达某目的地址的最优网关是另外一台路由器。

4.3、默认路由自动发现

1、IPv6主机维护的表项

在NDP中,每一个IPv6节点都需要跟踪和维护至少包括邻居表在内的多张表,每种表都有自己的用途。

邻居表:记录着同一局域网中相邻IPv6节点的MAC地址等信息。与ARP一样,表项内容既可以手动绑定,也可以通过NDP自动获取,且超过一定时间过期后需再通过NDP获取。邻居表不同于ARP的地方是,因为IPv6节点可能会有除了必需的链路本地地址之外的其他单播地址,因此邻居表会有两个以上的IPv6地址与同一个MAC地址对应,而且会标明邻居是路由器网关还是普通主机。在计算机上查看邻居表的命令是netsh interface ipv6 show neighbors

C:\Users\Administrator>netsh interface ipv6 show neighbors | more

接口 1: Loopback Pseudo-Interface 1


Internet 地址                                 物理地址           类型
--------------------------------------------  -----------------  -----------
ff02::c                                                          永久
ff02::16                                                         永久
ff02::fb                                                         永久
ff02::1:2                                                        永久
ff02::1:3                                                        永久

接口 6: 以太网


Internet 地址                                 物理地址           类型
--------------------------------------------  -----------------  -----------
2001:250:5005:1111::1                         00-00-00-00-00-00  无法访问
240e:369:506d:200:f62a:7dff:fe2e:eabd         f4-2a-7d-2e-ea-bd  停滞 (路由器)
fe80::41b8:2b51:3103:1b94                     00-00-00-00-00-00  无法访问
fe80::d07c:f077:373:a353                      00-00-00-00-00-00  无法访问
fe80::f62a:7dff:fe2e:eabd                     f4-2a-7d-2e-ea-bd  可以访问 (路由器)
ff02::1                                       33-33-00-00-00-01  永久
ff02::2                                       33-33-00-00-00-02  永久
ff02::c                                       33-33-00-00-00-0c  永久
ff02::16                                      33-33-00-00-00-16  永久
ff02::fb                                      33-33-00-00-00-fb  永久
ff02::1:2                                     33-33-00-01-00-02  永久
ff02::1:3                                     33-33-00-01-00-03  永久
-- More  --

目的地缓存表:记录的是最近发送的目的地址,可实现快速转发功能。可以将目的地缓存表理解为缓存下来的路由表,它类似于思科的快速转发表。有了它,无须每次都查路由表即可实现快速转发。在计算机上查看缓存表的命令是netsh interface ipv6 show Destinationcache。

C:\Users\Administrator>netsh interface ipv6 show Destinationcache | more

接口 6: 以太网


PMTU 目标地址                                      下一个跃点地址
---- --------------------------------------------- -------------------------
1500 2001:4860:4860::8888                          fe80::f62a:7dff:fe2e:eabd
1500 2408:822e:2ebe:2190:48ea:eaa0:8342:d506       fe80::f62a:7dff:fe2e:eabd
1500 2409:8a38:803a:c820:1270:4f2d:2b33:b936       fe80::f62a:7dff:fe2e:eabd
1500 2409:8a55:3337:400:106a:253d:6269:a9c8        fe80::f62a:7dff:fe2e:eabd
1500 240e:33d:7a3e:e900:8dce:9d7f:d323:2f3e        fe80::f62a:7dff:fe2e:eabd
1500 240e:369:506d:200:c62a:7dff:fe2e:eabd         fe80::f62a:7dff:fe2e:eabd
1500 240e:460:4c50:13bd::1                         fe80::f62a:7dff:fe2e:eabd
1500 240e:95d:c02:200::3a                          fe80::f62a:7dff:fe2e:eabd
1500 2408:4004:100:2e02:2c2c:fce3:74d9:6d45        fe80::f62a:7dff:fe2e:eabd
1500 2408:843d:4a50:150f:a583:d950:76ca:3a36       fe80::f62a:7dff:fe2e:eabd
1500 2409:8a6a:b01e:5e00:2d0a:e395:98eb:78b7       fe80::f62a:7dff:fe2e:eabd



C:\Users\Administrator>

路由表:与IPv4类似,就是主机在发送报文前,为了决定该如何到达目的地址而查询的表。路由表中至少包括自身接口所在的前缀列表(网段地址),可以将前缀列表理解为主机的直连路由,如FE80::/64和自身IPv6单播地址的前缀(前面已有介绍)。对于不在本网段的目的地址,路由表中可以有明确的下一跳或者能匹配到的默认路由。在计算机上查看路由表的命令是route print。

C:\Users\Administrator>route print
===========================================================================
接口列表
 16...00 ff a7 db ce ce ......SVN Adapter V1.0
 10...02 50 f2 00 00 02 ......iNode VPN Virtual NIC
  6...00 e0 70 80 ed cc ......Realtek PCIe GbE Family Controller
 20...00 ff aa bb cc dd ......Gateway NC Adapter
  1...........................Software Loopback Interface 1
 21...00 d0 f8 00 00 01 ......RuiJie SSLVPN 虚拟网卡
===========================================================================

IPv4 路由表
......

IPv6 路由表
===========================================================================
活动路由:
 接口跃点数网络目标                网关
  6    281 ::/0                     fe80::f62a:7dff:fe2e:eabd
  1    331 ::1/128                  在链路上
  6    281 2001:250:5005:1111::/64  在链路上
  6    281 2001:250:5005:1111::1/128
                                    在链路上
  6    281 240e:369:5055:c300:f62a:7dff:fe2e:ecbd/128
                                    fe80::f62a:7dff:fe2e:eabd
  6    281 240e:369:506d:200::5b/128
                                    在链路上
  6    281 fe80::/64                在链路上
 16    311 fe80::/64                在链路上
 16    311 fe80::795b:2271:f9aa:cab9/128
                                    在链路上
  6    281 fe80::8d80:8348:2b70:2116/128
                                    在链路上
  1    331 ff00::/8                 在链路上
  6    281 ff00::/8                 在链路上
 16    311 ff00::/8                 在链路上
===========================================================================
永久路由:
  无

C:\Users\Administrator>

2、IPv6主机发送报文过程

一台主机如果要向某目的地发送报文,需要经历以下过程。

首先、查找目的地缓存表,看目的地址是否与表中的表项有匹配,如果有匹配,直接跳到第三步查找邻居表,否则到第二步查找路由表。然后开始查找路由表,看目的地址是否有匹配项。一般情况下,主机如果有默认路由,则最差也能匹配到默认路由。如果有匹配,则转下一步;如果没匹配,则会向数据包中的源IPv6地址发送ICMPv6差错报文。最后、检查下一跳地址在邻居表中是否有匹配项,如果有,则提取其对应的链路层地址进行封装转发;如果没有,则通过NDP来获取下一跳节点的链路层地址,再进行封装转发。

3、默认路由自动发现过程

对于一般主机节点而言,我们可以手动在路由表中添加明细路由或默认路由。在IPv6中,如果要自动获取默认路由,即默认网关,那么都是通过RS和RA报文来完成的。这与IPv4通过DHCP来下发默认路由的机制不一样,即便是DHCPv6,默认路由也只能由RS和RA报文来完成。首先,路由器会周期性地向组播地址FF02::1发送RA报文,向网段中的主机通告自己是默认路由;其次,主机自动获取网络配置时,也会发送RS报文,以查找网段中的默认路由。

在这个过程中,可能会出现多个路由器同时发送RA报文的情况,从而导致主机有多个默认路由。这在某些情况下是不允许的。比如存在非法路由器时,非法路由器通告错误的网关,会导致用户不能正常使用网络。此时就可以在交换机的非信任端口上禁止接受路由器的RA报文,以避免用户获取到错误的网关。后面我们详细会介绍如何在二层交换机上进行配置,以拒绝非法的RA报文进入网络。还有一种办法是在主机上手动设置默认路由的优先级,但该方法比较专业,一般用户不一定会设置。

4.4、网关防欺骗试验

本实验将用路由器向主机通告自己是默认路由,同时也会将自己的链路层地址发送给主机,以便主机更新自己的邻居表。通过本实验,我们可以了解当同网段有多台路由器通告自己是默认路由时,主机如何选择正确的默认路由;路由器如何发送RA报文,以及如何修改路由器RA报文中的属性;在主机上如何查看邻居表和路由表,如何手动设置路由表以及如何手动选择正确的默认路由等。

image-20220119221520352

基本配置。开启Win10、Switch和R1。这里的Switch暂不配置。R1的配置如下:

Router>en
Router#conf t 
Enter configuration commands, one per line.  End with CNTL/Z.
Router(config)#ipv6 unicast-routing 
Router(config)#int e0/0
Router(config-if)#ipv6 enable 
Router(config-if)#ipv6 add 2001:2022::1/64
Router(config-if)#no shutdown 
Router(config-if)#int lo0
*Jan 20 21:08:22.274: %LINK-3-UPDOWN: Interface Ethernet0/0, changed state to up
*Jan 20 21:08:23.274: %LINEPROTO-5-UPDOWN: Line protocol on Interface Ethernet0/0, changed state to up
Router(config-if)#int lo0
Router(config-if)#
*Jan 20 21:08:24.948: %LINEPROTO-5-UPDOWN: Line protocol on Interface Loopback0, changed state to up
Router(config-if)#ipv6 add 2001:2022:1::1/64
Router(config-if)#

查看地址分配。在Win10的命令提示符窗口中使用ipconfig命令查看获得的地址及默认网关,如下图:

image-20220119220923122

默认网关是路由器R1的 ethernet0/0 接口的链路本地地址,我们可以在R1上执行命令show ipv6 interface e0/0进行验证。Win10自动获得一个IPv6地址和一个临时IPv6地址,两者的前缀都是2001:2022::/64,后面我们会解释临时地址的作用以及如何禁用临时地址。前缀信息也是通过RA报文来通告的,后面同样会对此详细介绍,这里只关注默认路由。

Router#show ipv6 interface e0/0
*Jan 20 21:11:19.855: %SYS-5-CONFIG_I: Configured from console by console
Router#show ipv6 interface e0/0
Ethernet0/0 is up, line protocol is up
  IPv6 is enabled, link-local address is FE80::A8BB:CCFF:FE00:400 
  No Virtual link-local address(es):
  Global unicast address(es):
    2001:2022::1, subnet is 2001:2022::/64 
  Joined group address(es):
    FF02::1
    FF02::2
    FF02::1:FF00:1
    FF02::1:FF00:400
  MTU is 1500 bytes
  ICMP error messages limited to one every 100 milliseconds
  ICMP redirects are enabled
  ICMP unreachables are sent
  ND DAD is enabled, number of DAD attempts: 1
  ND reachable time is 30000 milliseconds (using 30000)
  ND advertised reachable time is 0 (unspecified)
  ND advertised retransmit interval is 0 (unspecified)
  ND router advertisements are sent every 200 seconds
  ND router advertisements live for 1800 seconds
  ND advertised default router preference is Medium
  Hosts use stateless autoconfig for addresses.
Router#

然后我们在Win10上使用命令 netsh interface ipv6 show neighbors 查看所有邻居表。也可以只看某个接口对应的邻居表,比如要查看接口4对应的邻居表,可
使用命令 netsh interface ipv6 show neighbors“4”,如下图可知,默认网关的物理地址已经解析到,类型为“停滞(路由器)”,之所以是停滞状态,是因为还没进行可达性检测。

image-20220119221212212

image-20220119221247673

在上图中,2001:2022::1是路由器R1的e0/0接口配置的IPv6地址,fe80::a8bb:ccff: fe00:400 是路由器R1的e0/0接口的链路本地地址,对应的都是路由器
R1的 e0/0 接口,所以两者的MAC地址是一样的。这里能看到MAC地址是问题的关键,假如网络中有非法的路由器通告了非法的网关,通过在计算机上查看邻居表,就可以看到非法网关对应的MAC地址,然后在交换机上就可以根据MAC地址找到对应的交换机端口,最后关闭这个端口即可。交换机上的命令如下:

Switch#show mac address-table address aabb.cc00.0400
          Mac Address Table
-------------------------------------------

Vlan    Mac Address       Type        Ports
----    -----------       --------    -----
   1    aabb.cc00.0400    DYNAMIC     Et0/3
Total Mac Addresses for this criterion: 1
Switch#

show mac address-table 命令用来查看交换机的MAC地址表,生产环境中交换机上的MAC地址条目众多,可以加上address aabb.cc00.0400进行过滤,从而只查看某个MAC地址。从上面的输出中可以看到,这个MAC地址在交换机的Et0/3端口。这是一种事后处理方法,第7章会介绍如何在二层交换机上配置,以拒绝非法的RA报文进入网络。

在Win10上ping路由器的链路本地地址,强制对邻居表中默认网关的物理地址进行可达性检测,再次查看邻居表,默认网关变为了“可以访问”类型。

在计算机上使用 route print 命令查看路由表,可以同时显示IPv4和IPv6的路由表。若在命令后使用带“-6”的参数,则只显示IPv6的路由表。在Win10上使用 route print -6 命令查看IPv6的路由表,如下图

image-20220119221748488

在R1上将RA报文的Lifetime属性改为0,即执行如下命令:

Router(config)#int e0/0
Router(config-if)#ipv6 nd ra life
Router(config-if)#ipv6 nd ra lifetime ?
  <0-9000>  RA Lifetime (seconds)

Router(config-if)#ipv6 nd ra lifetime 0
Router(config-if)#

在Win10上使用ipconfig命令查看网络配置,发现默认网关没有了,这是因为RA报文的Lifetime一旦为0,就表明路由器不再是默认网关,但IPv6地址仍在,即RA报文还是可以携带前缀信息给客户主机。当然我们还可以在路由器R1的ethernet0/0下对RA报文的其他属性,如hop-limit(跳限制)、interval(周期性发送的间隔时间)等进行修改,其方法都是在ipv6 nd ra命令后面跟上相应的参数,这里不再详细描述了;感兴趣的小伙伴请自行测试。

image-20220119222001899

将前面RA报文的Lifetime属性修改成默认值,命令如下:

Router(config)#int e0/0
Router(config-if)#no ipv6 nd ra lifetime 

再打开路由器R2进行配置,其配置与R1类似,如下所示:

Router>en
Router#conf t 
Enter configuration commands, one per line.  End with CNTL/Z.
Router(config)#host R2
R2(config)#ipv6 unicast-routing 
R2(config)#int e0/0
R2(config-if)#ipv6 enable 
R2(config-if)#ipv6 add 2001:2020::1/64
R2(config-if)#no shutdown 
R2(config-if)#int lo0
R2(config-if)#
*Jan 20 21:23:56.270: %LINK-3-UPDOWN: Interface Ethernet0/0, changed state to up
*Jan 20 21:23:57.275: %LINEPROTO-5-UPDOWN: Line protocol on Interface Ethernet0/0, changed state to up
*Jan 20 21:23:58.507: %LINEPROTO-5-UPDOWN: Line protocol on Interface Loopback0, changed state to up
R2(config-if)#ipv6 add 2001:2020:1::1/64
R2(config-if)#

此时网络中的两台路由器同时发送RA报文。在Win10上使用命令route print -6(也可以使用netsh interface ipv6 show route命令)查看路由表,如下图

image-20220119222335953

从上图中可以看出,在Win10主机上自动获取到了两条跃点数都是266的等价默认路由,分别是R1和R2的对应接口的链路本地地址。在主机上使用ipconfig命令也会看到同时存在两个默认网关。有了两条等价的默认路由,通信中就会产生负载均衡效果,但具体到哪一个数据包走哪一条默认路由却不可控,这还会涉及缓存技术、快速交换技术等。

image-20220119222445199

在本次实验中,小伙伴们也可以在Win10或Win7上分别ping R1上的环回接口2001:2022:1::1和R2上的环回接口2001:2020:1::1,以查看网络的连通情况。从理论上来讲,这两个ping测试各自发出去的包应该是一个发送成功一个发送失败。可事实并非如此,去往2001:2022:1::1的ping包全通,去往2001:2020:1::1的ping包全不通,这说明两台主机的默认路由都是选择的R1。经过多次尝试后发现,这居然与网关的链路本地地址有关。可以使用下面的命令改变路由器接口的链路本地地址:

R1(config)#int e0/0
R1(config-if)#ipv6 address FE80::A8BB:CCFF:FE00:600 link-local
R1(config-if)#

改完后,可以发现两台主机的默认路由都选择了R2。使用下面的命令改变路由器R2接口的链路本地地址。

R2(config)#int e0/0
R2(config-if)#ipv6 address FE80::A8BB:CCFF:FE00:4 link-local

改完后,可以发现两台主机的默认路由又选回了R1,该情况与链路本地地址有关,但与大小无关,这种结果太难控制,以致大多数实际应用场景中不允许出现这种情况。因为除了一个合法的默认网关外,其他的通告自己是默认网关的路由器很可能是冒充的。

测试完成后,在R1的e0/0接口下使用命令no ipv6 addressFE80::A8BB:CCFF:FE00:600 link-local还原链路本地地址。同样在R2的e0/0接口下使用命令no ipv6 address FE80::A8BB: CCFF:FE00:4 link-local还原链路本地地址。

避免出现上述情况发生的最理想办法就是在网络中仅允许合法的路由器发送RA报文,禁止其他终端设备发送RA报文,这部分内容将在后面详细介绍。接下来介绍如何在主机上配置优选某条默认路由。

配置优选默认路由有两种方法、一种是修改跃点数、还有一种是添加明细路由。在前面我们可以看到,两条默认路由的跃点数(也称为metric)都为266。主机在选择默认路由时,总是优先选择跃点数较小的路由。可以通过命令route change将优选默认路由的metric值设置为小于256(进入路由表时,这个metric会被自动加10)。这里使用route change命令把metric值改成100,如下图所示。

注:下图中多了“-p”参数,表示永久的意思,不然在主机重启后,修改的跃点数就不存在了。

image-20220119223133865

再次使用router print –6命令查看路由表,可以发现只有一条默认路由了,其跃点数是110(100+10=110),如图3-46所示。跃点数是266的默认路由没有出现在路由表中,使用ipconfig命令也会发现默认网关现在只有一个。

注:将合法默认路由的metric值改小后,其他的默认路由过会儿又出现在路由表中,但因为其优先级低于合法默认路由,所以不会影响通信。

上面的截图中如果细看我们会发现最下方提示永久路由为“无”,永久路由是需要管理员使用命令route add手动添加的。route add命令在路由控制方面非常有用,可
以用来添加某条具体路由,且具体路由会优于默认路由。假如在本实验中,R2上的环回地址也是一条合法的路由,也需要被主机访问,则可以通过命令添加一条明细路由,在Win10的命令行窗口中执行route add 2001:2020:1::/64 fe80::a8bb:ccff:fe00:500 –p命令(如下图),添加明细路由,其中fe80::a8bb:ccff:fe00:500是路由器R2的e0/0接口的链路本地地址,参数-p的意思是把这条路由写入注册表,保证其永久有效,即使计算机重启后也仍然有效。

image-20220119223711811

此时再使用route print -6命令查看路由表时,会发现路由表最后多出一条永久路由。此时在主机上不管是ping R1上的环回地址2001:2022:1::1还是ping R2上的环回地址2001: 2020:1::1,都可以ping通。

4.5、地址解析过程及邻居表

1、地址解析过程

地址解析过程即主机或路由器将邻居节点的IPv6地址解析成链路层MAC地址,然后再保存在邻居表中的过程。这个解析过程是通过NS和NA报文来完成的,主要步骤如下。

首先、节点发送一个目的地址是被请求者节点组播地址的NS报文,此请求报文选项中携带了节点自身的链路层MAC地址,以便邻居能快速解析自身的链路层MAC地址。被请求节点的组播地址是FF02::1:FF00:0/104外加单播地址的末24位。比如要想解析FE80:abcd: 1234的链路层MAC地址,发送的NS报文的目的地址就是FF02::1:FFcd:1234。

然后、目的节点收到NS报文后,首先提取源地址和报文选项中的源链路层MAC地址,形成映射关系,再添加或更新本地邻居表。然后再向请求者发送目的地址为单播地址的NA报文,并在报文中携带自己的链路层MAC地址。

最初的节点收到NA报文后,根据其内容更新自己的本地邻居表。

2、邻居表及邻居状态信息

前面讲到,每个IPv6节点都会跟踪和维护邻居表,但前面只讲解了IPv6地址和MAC地址的映射关系,并没有介绍邻居表中记录的邻居状态信息。邻居表记录邻居状态信息的目的也是为了尽快发现和解决网络中断问题。就像路由表中记录路由是处于停滞状态还是可以访问状态那样,邻居表中也记录着每个邻居的状态。

3、查看邻居表

前面实验已经介绍了可在Win10上通过使用netshinterface ipv6 show neighbor命令查看邻居表,这里只介绍如何查看邻居状态。
在上图中我们可以看到,有一个fe80::a8bb:ccff:fe00:400的选项,类型是“停滞(路由器)”状态(超时)。前面已经介绍过可以通过ping命令强制进行可达性检测,使地址的类型为“可以访问”。另外邻居表中还有一些组播地址对应的链路层地址,其类型都是“永久”。这些对应的链路层MAC地址都是固定的33-33加上组播地址的低32位地址。

在IPv4中,攻击者可以不断发送伪造的ARP报文给被攻击者,ARP报文携带了网关的IPv4地址和错误的网关MAC地址,从而达到中间人攻击或破坏网络的目的。在IPv6中,攻击者除了使用非法网关,还可以发送RA或NA报文,让主机将默认路由或主机的错误链路层地址更新到邻居表中。如何避免这种情况呢?与IPv4一样,也是将正确的链路层地址手动绑定在邻居表中。对于Windows主机,手动绑定的命令是“netshinterface ipv6 set neighbor‘接口ID’邻居IPv6地址 邻居链路层MAC地址”。在Win10主机上绑定后查看邻居表,结果如下图。

image-20220119224341750

在路由器R1上通过命令show ipv6 neighbors查看邻居表,显示如下:

R1#show ipv6 neighbors
IPv6 Address                              Age Link-layer Addr State Interface
2001:2022::2521:9CD6:5747:AC01              0 5000.0002.0000  STALE Et0/0
2001:2022::5D03:AE85:29E0:6B2B             14 5000.0002.0000  STALE Et0/0
2001:2022::C03F:7381:699:4764               0 5000.0001.0000  DELAY Et0/0
FE80::5D03:AE85:29E0:6B2B                   1 5000.0002.0000  STALE Et0/0
FE80::FD70:2E95:9D73:6B85                   0 5000.0001.0000  STALE Et0/0

R1#

同样,在路由器上也可以手动绑定邻居的链路层MAC地址,可在路由器上执行如下命令:

# 手动绑定
R1(config)#ipv6 neighbor 2001:2022::C01D:6C23:990:570 ethernet 0/0 5000.0002.0000
# 再次查看邻居表;若不想在特权模式下执行show命令,可以在show命令前面加do,相当于特权调用
R1(config)#do show ipv6 neighbors 
IPv6 Address                              Age Link-layer Addr State Interface
2001:2022::2521:9CD6:5747:AC01              0 5000.0002.0000  REACH Et0/0
2001:2022::5D03:AE85:29E0:6B2B             15 5000.0002.0000  STALE Et0/0
2001:2022::C01D:6C23:990:570                - 5000.0002.0000  REACH Et0/0
2001:2022::C03F:7381:699:4764               0 5000.0001.0000  REACH Et0/0
FE80::5D03:AE85:29E0:6B2B                   2 5000.0002.0000  STALE Et0/0
FE80::FD70:2E95:9D73:6B85                   0 5000.0001.0000  REACH Et0/0

R1(config)#

注:在手动绑定后,该条目的Age栏中显示为“-”,这表示永不过期的意思;保存路由器的配置文件时,这条配置命令也被保存,路由器在重启后绑定仍然有效。

4.6、路由重定向

前面在介绍重定向报文格式时已经提过,当路由器收到一个报文时,若发现同网段有更好的下一跳,则向发送方发送重定向报文(这与IPv4类似)。路由重定向的具体过程如下。

发送方在向一个目的地址发送IPv6单播报文时,根据路由表中的最佳匹配原则,将报文发送给下一跳路由器。路由器收到报文后查找路由表,发现去往目的地的下一跳地址与报文中的源地址处于同一网段。路由器继续转发报文给下一跳路由器,同时向发送方发送路由重定向报文,告知源节点去往此目的地有更好的下一跳。这个更好的下一跳地址在重定向报文中的目的地址字段中指定,且该地址与源节点处于同一网段。源节点收到路由重定向报文后,是否采用新的下一跳地址转发后续报文,由源节点的配置决定。

推荐文章