邻居发现协议NDP
一、简述
邻居发现协议NDP(Neighbor Discovery Protocol)是IPv6协议体系中一个重要的基础协议。邻居发现协议替代了IPv4的ARP(Address Resolution Protocol)和ICMP路由器发现(Router Discovery)ICMP重定向等,它定义了使用ICMPv6报文实现地址解析,跟踪邻居状态,重复地址检测,路由器发现以及重定向等功能。
二、NDP消息
NDP主要通过ICMPv6消息实现所需功能,它定义了5种ICMPv6报文类型:
-
类型133 路由器请求(RS,Router Solicitation):由主机发起,用来请求一个路由器发送一个RA。很多情况下主机接入网络后希望尽快获取网络前缀进行通信,此时主机可以立刻发送RS报文,网络上的设备将回应RA报文。RS的源地址可以是未指定的地址(::),也可以是该主机的链路本地地址,目的地址则始终是所有路由器的多播地址(FE02::2)。
-
类型134 路由器通告(RA,Router Advertisement):由路由器发起,通告路由器的存在和链路的细节参数(链路前缀,MTU,跳数限制等)及其他一些标志位信息,周期性发送,也用于答RS。未经请求的RA源地址是路由器接口的链路地址,目的地址是所有节点的多播地址(FE02::1)。
-
类型135 邻居请求(NS,Neighbor Solicitation):Code字段值为0,在地址解析中的作用类似于IPv4中的ARP请求报文。由节点主机发起,用来请求另一台主机的链路层地址,或实现地址冲突检测、邻居不可达检测。
-
类型136 邻居通告(NA,Neighbor Advertisement):Code字段值为0,在地址解析中的作用类似于IPv4中的ARP应答报文。有节点发起用来响应NS,如果一个节点改变了他的链路层地址,那么它能够主动发送一个NA来通告这个新地址。
-
类型137 重定向(Redirect)
NDP消息通常在链路本地的范围内收发。
为了进一步增强安全性,承载所有NDP消息的IPV6数据包的跳数限制为255,如果收到的数据包跳数小于255的,说明该数据包最少已经经过一台路由器,因此该数据包应该被丢弃。这样可以防止NDP受到来自不与本地链路相连的源节点的攻击或欺骗。
三、地址解析(类PIv4的ARP)
此部分摘抄自:CSDN博主「曹世宏的博客」的原创文章
原文链接:https://blog.csdn.net/qq_38265137/article/details/80466128
做笔记时有部分添加改动
地址解析在报文转发过程中具有至关重要的作用。当一个节点需要得到同一条链路上另外一个节点的链路层地址时,需要进行地址解析。在IPv4中,必须先通过ARP协议获得目的主机的链路层地址。IPv6使用NDP实现了这个功能,且有所增强。IPv6的地址解析过程包括两部分:一部分解析目的IP地址所对应的链路层地址;另一部分是邻居可达性状态的维护过程,即邻居不可达检测。
ARP报文是直接封装在以太网报文中,以太网协议类型为0x0806,普遍观点认为ARP定位为第2.5层的协议。NDP本身基于ICMPv6实现,以太网协议类型为0x86DD,即IPv6报文,IPv6下一个报头字段值为58,表示ICMPv6报文,由于NDP协议使用的所有报文均封装在ICMPv6报文中,一般来说,NDP被看作第3层的协议。在三层完成地址解析,主要带来以下几个好处:
- 地址解析在三层完成,不同的二层介质可以采用相同的地址解析协议。
- 可以使用三层的安全机制避免防止ARP攻击和ARP欺骗。
- 使用组播方式发送请求报文,减少了二层网络的性能压力,节省了带宽。
地址解析过程中使用了两种ICMPv6报文:邻居请求报文NS(Neighbor Solicitation)和邻居通告报文NA(Neighbor Advertisement)。
-
类型135 邻居请求(NS,Neighbor Solicitation):Code字段值为0,在地址解析中的作用类似于IPv4中的ARP请求报文。由节点主机发起,用来请求另一台主机的链路层地址,或实现地址冲突检测、邻居不可达检测。
-
类型136 邻居通告(NA,Neighbor Advertisement):Code字段值为0,在地址解析中的作用类似于IPv4中的ARP应答报文。有节点发起用来响应NS,如果一个节点改变了他的链路层地址,那么它能够主动发送一个NA来通告这个新地址。
IPv6地址解析过程分析
简述
- Host A在向Host B发送报文之前它必须要解析出Host B的链路层地址,所以首先Host A会发送一个NS报文,其中源地址为Host A的IPv6地址,目的地址为Host B的被请求节点组播地址,需要解析的目标IP为Host B的IPv6地址,这就表示Host A想要知道Host B的链路层地址。同时需要指出的是,在NS报文的Options字段中还携带了Host A的链路层地址。
- 当Host B接收到了NS报文之后,就会回应NA报文,其中源地址为Host B的IPv6地址,目的地址为Host A的IPv6地址(使用NS报文中的Host A的链路层地址进行单播),Host B的链路层地址被放在Options字段中。这样就完成了一个地址解析的过程。
详细抓包过程
-
首先在两端各配上IPv6地址,然后在AR1上ping ipv6 -a 2000::1 2000::2。抓包如下:
-
NS报文内容如下:
AR1会以2000::1作为源地址,目标地址为2000::2的被请求节点组播地址 ff02::1:ff00:2。然后将AR1的MAC地址携带在ICMPv6的Option中。在ICMPv6中还会携带Target Address:2000::2,这个用来防止在广播网中有多个前缀不同,最后24bit相同,而造成的混乱。携带这个字段后,当主机收到这个报文后,会首先检查该字段是否是自己的IPv6地址,如果是,则接收并回应NA报文。如果该字段的地址不是自己的IPv6地址,则丢弃。 -
NA报文内容如下:
当AR2收到AR1发送的NA报文后,检查Target Address字段,如果是自己的IPv6地址,接收,并将对端的IP地址和MAC地址绑定到自己的邻居表中。然后以自己IPv6地址2000::2为源地址,对端IPv6地址:2000::1为目的地址。并将自己的MAC地址封装在ICMPv6的Option中,发送给对方。从而两端都知道了对方的MAC地址。可以进行二次封装。
邻居通告报文中Flags字段解释:
- R:路由器标记。当置1时,R位指出发送者是路由器。R位由Neighbor Unreachability Detection(NUD)使用,用于检测改变为主机的路由器。
- S:请求标记。当置1时,S位指出通告被发送以响应来自目的地地址的Neighbor Solicitation。S位用作Neighbor Unreachability Detection的可达性确认。在多播通告和非请求单播通告中置0。
- O:替代标记。替代标志,1表示通告中的信息替代缓存,如更新链路层地址时,对于任播的回应则不应置位。在针对任播地址的请求通告中,以及在请求的前缀通告中它不能被置1。在其他请求通告中和在非请求通告中它应当被置1。
- Target Address:对于请求的通告,是在Neighbor Solicitation消息(该消息催促这个通告)中的Target Address字段。对于非请求通告,是其链路层地址已经改变了的地址。Target Address必须不是多播地址。
四、邻居不可达检测(NUD)
NUD(Neighbor Unreachable Detection,邻居不可达检测)是节点确定邻居可达性的过程。邻居不可达检测机制通过邻居可达性状态机来描述邻居的可达性。
通过邻居或到达邻居的通信,会因各种原因而中断,包括硬件故障、接口卡的热插入等。如果目的地失效,则恢复是不可能的,通信失败;如果路径失效,则恢复是可能的。因此节点需要维护一张邻居表,每个邻居都有相应的状态,状态之间可以迁移。
邻居可达性状态机保存在邻居缓存表中,共有如下6种状态:
-
EMPTY(空闲状态):表示节点上没有相关邻接点的邻居缓存表项。
-
INCOMPLETE(未完成状态):表示正在解析地址,但邻居链路层地址尚未确定。
-
REACHABLE(可达状态):表示地址解析成功,该邻居可达。
-
STALE(陈旧状态):表示可达时间耗尽,未确定邻居是否可达。
-
DELAY(延迟状态):表示未确定邻居是否可达。DELAY状态不是一个稳定的状态,而是一个延时等待状态。
-
PROBE(探测状态):节点会向处于PROBE状态的邻居持续发送NS报文。
图中实线箭头表示由NS/NA报文交互导致的状态变化,各状态间的相互转换如下:
- A先发送NS报文,并生成缓存条目,此时,邻居状态为Incomplete。
- 若B回复NA报文,则邻居状态由Incomplete变为Reachable,否则固定时间后邻居状态由Incomplete变为Empty,即删除表项。
- 经过邻居可达时间,邻居状态由Reachable (默认30s)变为Stale,即未知是否可达。
- 如果在Reachable状态, A收到B的非请求NA报文,且报文中携带的B的链路层地址和表项中不同,则邻居状态马上变为Stale。
- 在Stale状态若A要向B发送数据,则邻居状态由Stale变为Delay,并发送NS请求。
- 在经过一段固定时间后, 邻居状态由Delay (默认5s)变为Probe (每隔1s发送一次NS报文, 连续发送3次),其间若有NA应答,则邻居状态由Delay变为Reachable。
- 在Probe状态, A每隔1s发送单播NS,发送3次后,有应答则邻居状态变为Reachable,否则邻居状态变为Empty,即删除表项。
NUD过程与地址解析过程的主要不同之处在于以下两点:
-
NUD的NS报文的目的MAC是目的节点的MAC地址;目的IPv6地址为NodeB的单播地址,而不是被请求节点组播地址。
-
NA报文中的S标记须置位,表示是可达性确认报文,即这个NA报文是专门响应NS报文的。
五、重复地址检测DAD(IPv4的FARP)
重复地址检测DAD(Duplicate Address Detect)是在接口使用某个IPv6单播地址之前进行的,主要是为了探测是否有其它的节点使用了该地址。尤其是在地址自动配置的时候,进行DAD检测是很必要的。一个IPv6单播地址在分配给一个接口之后且通过重复地址检测之前称为试验地址(Tentative Address)。此时该接口不能使用这个试验地址进行单播通信,但是仍然会加入两个组播组:ALL-NODES组播组和试验地址所对应的Solicited-Node组播组。
IPv6重复地址检测技术和IPv4中的免费ARP类似:节点向试验地址所对应的Solicited-Node组播组发送NS报文。NS报文中目标地址即为该试验地址。如果收到某个其他站点回应的NA报文,就证明该地址已被网络上使用,节点将不能使用该试验地址通讯。
例如:
Host A的IPv6地址FC00::1为新配置地址,即FC00::1为Host A的试验地址。Host A向FC00::1的Solicited-Node组播(请求节点组播)组发送一个以FC00::1为请求的目标地址的NS报文进行重复地址检测,由于FC00::1并未正式指定,所以NS报文的源地址为未指定地址(::)。如果并未收到来自FC00::1的NA回复,则该地址可以使用。当Host B收到该NS报文后,有两种处理方法:
- 如果Host B发现FC00::1是自身的一个试验地址,则Host B放弃使用这个地址作为接口地址,并且不会发送NA报文。
- 如果Host B发现FC00::1是一个已经正常使用的地址,Host B会向FF02::1(所有节点组播地址)发送一个NA报文,该消息中数据部分会包含FC00::1。这样,Host A收到这个消息后就会发现自身的试验地址是重复的。Host A上该试验地址不生效,被标识为duplicated(重复)状态。
如果两端同时发起检测
- 若2个节点配置相同地址,同时作重复地址检测时,该地址处于Tentative状态,当一方收到对方发出的DAD NS,则接收方将不启用该地址。
- 一种极端的情况,如果同时收到NS报文,则两端都放弃改地址。
六、前缀重新编址
前缀重新编址(Prefix Renumbering)允许网络从以前的前缀平稳地过渡到新的前缀,用于提供对用户透明的网络重新编址能力。路由器通过RA报文中的优先时间和有效时间参数来实现前缀重新编址。
(1)优先时间(Preferred Lifetime):无状态自动配置得到的地址保持优先选择状态的时间。
(2)有效时间(Valid Lifetime):地址保持有效状态的时间。
对于一个地址或前缀,优先时间小于或等于有效时间。当地址的优先时间到期时,该地址不能被用来建立新连接,但是在有效时间内,该地址还能用来保持以前建立的连接。在重新编址时,站点内的路由器会继续通告当前前缀,但是有效时间和优先时间将被减小到接近于0;同时,路由器开始通告新的前缀。这样,在每个链路上至少有两个前缀共存,RA消息中包括一个旧的和一个新的IPv6前缀信息。
在preferred time和valid lifetime之间叫做deprecated(弃用)状态,当地址达到这个时间段的时候,地址不能主动的发起连接只能是被动的接受连接,过了valid lifetime时间,地址就变为invalid,这时任何连接就会down掉。
七、路由器发现
路由器发现功能用来发现与本地链路相连的设备,并获取与地址自动配置相关的前缀和其他配置参数。
在IPv6中,IPv6地址可以支持无状态的自动配置,即主机通过某种机制获取网络前缀信息,然后主机自己生成地址的接口标识部分。路由器发现功能是IPv6地址自动配置功能的基础,主要通过以下两种报文实现:
-
路由器请求RS(Router Solicitation)报文:很多情况下主机接入网络后希望尽快获取网络前缀进行通信,此时主机可以立刻发送RS报文,网络上的设备将回应RA报文。RS报文的Tpye字段值为133。
-
路由器通告RA(Router Advertisement)报文:每台设备为了让二层网络上的主机和设备知道自己的存在,定时都会组播发送RA报文,RA报文中会带有网络前缀信息,及其他一些标志位信息。RA报文的Type字段值为134。
RA报文中存在3个关键的Flag
-
Autonomous flag(简称A flag):表示是否配置无状态IP。在一个RA报文中,可存在多个prefix,比如2401::/64、2402::/64、2403::/64,每个prefix都可以独立配置A flag(有多个A flag)。
为on时(对应bit位为1):表示客户端应当在该prefix范围内自动生成IPv6地址(客户端通过DAD自行保证地址可用),并配置子网路由条目、网关。
为off时(对应bit位为0):表示客户端不应当在该prefix范围内自动生成IPv6地址,但是可以配置子网路由条目、网关。 -
Managed flag(简称M flag):表示是否配置有状态IP。M flag是RA报文的全局参数,一个RA报文只有一个M flag。
为on时(对应bit位为1):表示在stateless流程结束后开始stateful流程,也就是告诉客户端可以通过DHCPv6来获得IPv6地址和其他参数(如DNS列表)
为off时(对应bit位为0):表示不通过DHCPv6来获得IPv6地址。
▷ Other flag(简称O flag):表示是否通过DHCPv6获得除IP以外的其他参数(如DNS列表)。O flag也是RA报文中的全局参数,一个RA报文只有一个O flag。注意:仅当M flag为off时,该参数才会被读取。
▪ 为on时(对应bit位为1):当M flag为on,或者M flag为off且至少有一个A flag为on时,将通过DHCPv6获得其他参数
▪ 为off时(对应bit位为0):当M flag为on时,依然将通过DHCPv6获得其他参数;当M flag也为off时,将不通过DHCPv6获得其他参数。
默认路由器优先级
当主机所在的链路中存在多个设备时,主机需要根据报文的目的地址选择转发设备。在这种情况下,设备通过发布默认路由优先级和特定路由信息给主机,提高主机根据不同的目的地选择合适的转发设备的能力。
在RA报文中,定义了默认路由优先级和路由信息两个字段,帮助主机在发送报文时选择合适的转发设备。
主机收到包含路由信息的RA报文后,会更新自己的路由表。当主机向其他设备发送报文时,通过查询该列表的路由信息,选择合适的路由发送报文。
主机收到包含默认设备优先级信息的RA报文后,会更新自己的默认路由列表。当主机向其他设备发送报文时,如果没有路由可选,则首先查询该列表,然后选择本链路内优先级最高的设备发送报文;如果该设备故障,主机根据优先级从高到低的顺序,依次选择其他设备。
八、地址自动配置:
NDP的无状态自动配置包含两个阶段:链路本地地址的配置和全球单播地址的配置。当一个接口启用时,主机会首先根据本地前缀FE80::/64和EUI-64接口标识符,为该接口生成一个链路本地地址,如果在后续的DAD中发生地址冲突,则必须对该接口手动配置本地链路地址,否则该接口将不可用。需要说明的是,一个链路本地地址的优先时间和有效时间是无限的,永远不超时。
在本地链路地址配置完成后对于主机上全球单播地址的配置步骤如下:
-
主机节点NodeA在配置好链路本地地址后,发送RS报文,请求路由器的前缀信息。
-
路由器收到RS报文后,发送单播RA报文,携带用于无状态地址自动配置的前缀信息,同时路由器也会周期性地发送组播RA报文。
-
NodeA收到RA报文后,根据前缀信息和配置信息生成一个临时的全球单播地址。同时启动DAD,发送NS报文验证临时地址的唯一性,此时该地址处于临时状态。
-
链路上的其他节点收到DAD的NS报文后,如果没有用户使用该地址,则丢弃报文,否则产生应答NS的NA报文。
-
NodeA如果没有收到DAD的NA报文,说明地址是全局唯一的,则用该临时地址初始化接口,此时地址进入有效状态。
地址自动配置完成后,路由器可以自动进行NUD,周期性地发送NS报文,探测该地址是否可达。
生成全球单播地址的方式
生成“全球单播地址”(或者“唯一本地地址”),有2种方式:
-
手动配置
-
自动配置
其中“自动配置”根据获取方式,又分为
-
无状态(Stateless):根据路由通告报文RA(Router Advertisement)包含的prefix前缀信息自动配置IPv6地址,组成方式是Prefix + (EUI64 or 随机)。Stateless也可以称为SLAAC(Stateless address autoconfiguration)
-
有状态(Stateful):通过DHCPv6方式获得IPv6地址
其中“有状态”又分为2种
-
有状态DHCPv6(Stateful DHCPv6):IPv6地址、其他参数(如DNS)均通过DHCPv6获取
-
无状态DHCPv6(Stateless DHCPv6):IPv6地址依然通过路由通告RA方式生成,其他参数(如DNS)通过DHCPv6获取
为了避免混淆,在此解释下有状态、无状态到底是什么意思:首先,请明确一点,有状态、无状态仅针对于IPv6地址分配方式,并不包含其他参数。
-
有状态:可控、可管理。在网络中存在一个IP地址管理者,它能够识别客户端,根据不同的客户端,分配对应的IPv6地址,客户端与服务端之间需要维护IP地址的租期及续约。目前实现这种效果的,就是DHCPv6协议,IP地址管理者就是DHCPv6 Server。
-
无状态:不可控、难管理。在网络中只有网关,没有IP地址管理者。因此无人去识别客户端,每个客户端根据网关发送的相同的RA报文内容,自行配置IPv6地址。
流程图
无状态和有状态并不是相互对立的,他们可以同时存在,也就是一张网卡上可以同时出现通过RA生成的IP以及通过DHCPv6获得的IP。通过下面流程图可知晓其中奥秘。
从图中可以看到,顺序为:
-
Stateless自动配置“链路本地地址”
-
Stateless自动配置“全球地址”(或“唯一本地地址”)
-
Stateful自动配置“全球地址”(或“唯一本地地址”)和其他参数,其中Stateful阶段中存在Stateful DHCPv6或Stateless DHCPv6。
九、重定向
当网关设备发现报文从其它网关设备转发更好,它就会发送重定向报文告知报文的发送者,让报文发送者选择另一个网关设备。重定向报文也承载在ICMPv6报文中,其Type字段值为137,报文中会携带更好的路径下一跳地址和需要重定向转发的报文的目的地址等信息。
Host A需要和Host B通信,Host A的默认网关设备是Router A,当Host A发送报文给Host B时报文会被送到Router A。Router A接收到Host A发送的报文以后会发现实际上Host A直接发送给Router B更好,它将发送一个重定向报文给主机A,其中报文中更好的路径下一跳地址为Router B,Destination Address为Host B。Host A接收到了重定向报文之后,会在默认路由表中添加一个主机路由,以后发往Host B的报文就直接发送给Router B。
当设备收到一个报文后,只有在如下情况下,设备会向报文发送者发送重定向报文:
- 报文的目的地址不是一个组播地址。
- 报文并非通过路由转发给设备。
- 经过路由计算后,路由的下一跳出接口是接收报文的接口。
- 设备发现报文的最佳下一跳IP地址和报文的源IP地址处于同一网段。
- 设备检查报文的源地址,发现自身的邻居表项中有用该地址作为全球单播地址或链路本地地址的邻居存在。