ICMPv6 并非可选
在 IPv4 中, 是一项诊断性的事后补充,你可以阻断它而不破坏基本连通性。在 IPv6 中,ICMPv6(RFC 4443)是承重的:协议为其核心的链路运作而依赖于它,所以不加区分地过滤它会破坏网络。其缘由在于,IPv6 把 IPv4 曾分散于 、ICMP 路由器发现与 ICMP 重定向之间的数项工作,移入了一个单一的、基于 ICMPv6 的协议、称为邻居发现(Neighbor Discovery,RFC 4861)。理解邻居发现,便是理解一条 IPv6 链路实际上如何运作。
五条消息完成工作
邻居发现定义了五种 ICMPv6 消息类型,而一条链路上几乎一切都是它们的某种组合:
- 路由器请求(RS):一台主机请求路由器们宣告自身。
- 路由器通告(RA):一台路由器宣告前缀与配置标志(地址配置一文中自动配置的输入)。
- 邻居请求(NS):一台主机询问“谁拥有这个地址,而你的链路层地址是什么?”
- 邻居通告(NA):给出那个链路层地址的应答。
- 重定向(Redirect):一台路由器告诉一台主机、通往某目的地的一个更好的下一跳。
路由器请求与通告处理“我如何配置自己”;邻居请求与通告处理“我如何抵达这个邻居”;重定向处理“有一条更好的路径”。这便涵盖了一条链路的日常生活。
无广播的地址解析
ARP 在 IPv4 中所做的工作——把一个 IP 地址映射到一个硬件地址——在 IPv6 中由邻居请求与通告这一对来完成。重要的差别在于那问题如何被问出。ARP 向广播地址大喊,打扰网段上的每一台设备。IPv6 转而把邻居请求发送到目标的被请求节点多播地址(solicited-node multicast address)——一个仅由共享相同地址后缀的那一小撮主机才会在其上侦听的组。目标以一条携带其链路层地址的邻居通告作答。查询方把结果缓存起来,恰如一个 ARP 缓存之运作,并在流量暗示某邻居或已离去时、通过邻居不可达检测(Neighbor Unreachability Detection)来重新验证它。
那个被请求节点多播地址
被请求节点多播地址自目标地址构建而来:取前缀 ff02::1:ff00:0/104,并附加目标地址的末 24 位。因为解析仅瞄准共享那低 24 位的那一小撮主机、而非整条链路,该请求所抵达的机器,远少于一个 ARP 广播所会抵达的。这一构造便是为何编址一文把被请求节点多播当作地址规划的一部分、而非事后补充:每一台配置一个地址的主机,都自动加入对应的被请求节点组,以便他者能寻得它。
全然没有广播
IPv6 没有广播地址。IPv4 曾用广播去做的一切——包括地址解析与路由器发现——都由发往特定的、范围良好界定之组的多播来处理。有一个全节点多播组(ff02::1)与一个全路由器组(ff02::2),但例行的解析转而瞄准那些狭窄的被请求节点组。以“恰好通知相关的侦听者”取代“打扰所有人”,在繁忙的链路上更为高效,且是 IPv6 较 IPv4 所作的较为静默的改进之一。
信任那条链路
因为邻居发现默认是未经认证的,同一条链路上的一台恶意主机可发送伪造的路由器通告或邻居通告,以重定向或截获流量——此乃 ARP 欺骗的 IPv6 类比。那些防御栖身于网络的边缘:交换机上的 RA Guard 丢弃来自不应有路由器的端口的路由器通告,而安全邻居发现(SEcure Neighbor Discovery,SEND)在其被部署之处添加密码学保护。一如 IPv4,本地链路是一道值得守护的信任边界。
那条链路的神经系统
总而言之,IPv6 把地址解析、路由器发现与重定向折入了一个单一的、基于 ICMPv6 的协议,以有的放矢的多播换下了广播式的大喊,并使整件事变得必不可少、而非可选。当你在工具中看到一个地址、并注意到它的被请求节点组或它的链路本地形式时,你所注视的,便是邻居发现用以让主机们在一条链路上彼此寻得、而从不惊扰那些并不相干的邻居的那些部件。