13.2 ICMPv6、NDP 与地址自动配置
IPv6 主机接入链路后,需要确认地址不冲突、寻找路由器、学习前缀和解析邻居的链路层地址。这些能力主要由 ICMPv6 Neighbor Discovery 承担。把 ICMPv6 一刀切地屏蔽,常常等于切断 IPv6 自己的控制回路。
NDP 不只是“IPv6 版 ARP”
Neighbor Discovery Protocol 使用五类 ICMPv6 消息:
| 消息 | Type | 主要作用 |
|---|---|---|
| Router Solicitation, RS | 133 | 主机请求路由器尽快发送 RA |
| Router Advertisement, RA | 134 | 通告默认路由、前缀和其他链路参数 |
| Neighbor Solicitation, NS | 135 | 地址解析、邻居可达性检测、重复地址检测 |
| Neighbor Advertisement, NA | 136 | 回应 NS,或主动通告邻居信息变化 |
| Redirect | 137 | 路由器告诉主机同链路上更合适的下一跳 |
ICMPv6 还用 Packet Too Big、Destination Unreachable 和 Time Exceeded 分别支持 PMTUD、错误报告与路径探测。安全策略应按功能和作用域精细过滤,而不是简单丢弃所有 ICMPv6。
从单播地址得到 solicited-node multicast
地址解析不向所有节点广播。节点为自己的每个 unicast/anycast 地址加入对应的 solicited-node multicast group:
unicast: 2001:db8::1234:5678
low 24 bits: 34:5678
solicited-node group: ff02::1:ff34:5678
Ethernet multicast: 33:33:ff:34:56:78发送方对目标地址发起 NS 时,把请求发往这个多播组。共享相同低 24 位的节点也可能收到请求,因此接收端仍须检查 NS 中的 Target Address。
import ipaddress
def solicited_node(address: str) -> ipaddress.IPv6Address:
target = int(ipaddress.IPv6Address(address))
prefix = int(ipaddress.IPv6Address("ff02::1:ff00:0"))
return ipaddress.IPv6Address(prefix | (target & 0xFFFFFF))
assert str(solicited_node("2001:db8::1234:5678")) == "ff02::1:ff34:5678"Neighbor Cache 不是永久 ARP 表
NDP 会维护邻居可达性状态。常见状态包括:
| 状态 | 含义 |
|---|---|
| INCOMPLETE | 正在解析链路层地址 |
| REACHABLE | 最近有证据表明邻居可达 |
| STALE | 条目存在,但可达性证据已过新鲜期 |
| DELAY | 暂缓主动探测,等待上层提供可达性确认 |
| PROBE | 正在发送单播 NS 探测 |
| FAILED | 解析或可达性确认失败 |
Linux 上查看:
ip -6 neigh showSTALE 不等于故障。它表示需要使用时可能进入后续确认流程;把所有非 REACHABLE 条目当成坏邻居会制造误报。
Duplicate Address Detection
地址进入正常使用前,节点通常执行 Duplicate Address Detection(DAD):以 unspecified address :: 为源,对候选地址发送 NS。若收到表明地址已被使用的 NA/NS,就不应启用该地址。
查看 Linux 地址状态:
ip -6 address show输出中的 tentative 表示 DAD 尚未完成,dadfailed 表示检测失败。DAD 降低同链路地址冲突风险,却不能提供密码学所有权证明。
RA 提供什么
主机可以发送 RS 请求通告,路由器也会周期发送 RA。RA 及其选项可能包含:
- Router Lifetime:该路由器可作为默认路由的时间;
- Prefix Information Option:on-link 前缀和 autonomous address-configuration 标志;
- MTU;
- 可达时间与重传计时建议;
- RDNSS/DNSSL:递归 DNS 服务器和搜索域;
- Route Information Option:更具体的路由信息。
前缀选项中的 L 与 A 标志含义不同:L 指示前缀可用于 on-link 判断;A 指示可用于 SLAAC。两者不应被当成同一个开关。
RA 的 M/O 标志能提示有状态地址配置或其他 DHCPv6 信息,但客户端行为和操作系统策略并不能仅靠两个标志完整描述。部署时要针对目标客户端验证。
SLAAC 的完整流程
普通主机的典型过程:
1. 形成 link-local address
2. 对候选地址执行 DAD
3. 发送 RS,或等待 RA
4. 从带 A 标志的 prefix information 形成地址
5. 对新地址执行 DAD
6. 根据 RA 学习 default router、on-link prefix、MTU 等
7. 按 preferred/valid lifetime 管理地址生命周期地址超过 preferred lifetime 后会成为 deprecated,现有连接可继续使用,但新连接通常避免选择它作为源地址。超过 valid lifetime 后,地址不再有效。
Interface ID 不应再默认为暴露 MAC 的 EUI-64
早期教材常用 modified EUI-64 从 MAC 生成 64 位 interface identifier。这便于讲位结构,却会让地址跨网络可关联,并暴露链路层标识。
现代主机通常结合两类机制:
- RFC 7217:为每个前缀生成稳定但不暴露 MAC 的 opaque interface identifier;
- RFC 8981:生成有生命周期的 temporary address,降低跨时间跟踪能力。
具体默认值由操作系统决定。同一接口可以同时拥有 link-local、稳定地址、temporary address 和 DHCPv6 地址;应用不应假设“一个网卡只有一个 IP”。
SLAAC 与 DHCPv6 不是二选一
| 能力 | RA/SLAAC | DHCPv6 |
|---|---|---|
| 默认路由 | 由 RA 提供 | DHCPv6 通常不替代 RA 提供默认路由 |
| 地址 | SLAAC 可形成 | stateful DHCPv6 可租用 |
| DNS 信息 | RA 的 RDNSS/DNSSL 可提供 | DHCPv6 也可提供 |
| 额外配置 | RA 选项有限 | DHCPv6 可承载更多配置 |
常见部署包括 SLAAC-only、SLAAC + stateless DHCPv6,以及 RA + stateful DHCPv6。客户端支持情况很重要,例如部分终端平台对 DHCPv6 地址配置的支持策略与桌面系统不同。
观察而不是伪造 NDP
学习阶段优先观察操作系统生成的包,不要在真实局域网中用 Scapy 伪造 RA/NA。错误或恶意 RA 可能改变同链路主机的默认路由和 DNS。
# 地址、路由与邻居状态
ip -6 address show
ip -6 route show
ip -6 neigh show
# 只观察当前接口上的 NDP
sudo tcpdump -i eth0 -nn 'icmp6 && ip6[40] >= 133 && ip6[40] <= 137'固定用 ip6[40] 读取类型只适合“ICMPv6 紧跟基本首部、没有扩展首部”的包。更稳妥的离线分析应让协议解析器遍历 Next Header 链,或使用 Wireshark 的 icmpv6.type display filter。
安全边界
NDP 默认不认证,面临伪造 RA、NA 欺骗和邻居缓存耗尽等同链路攻击。SEND 定义了密码学保护机制,但现实部署并不普遍,不能写成“NDP 天生安全”。
常见防护包括:
- 交换网络中的 RA Guard 与可信端口策略;
- DHCPv6 Guard、控制平面限速和邻居表容量保护;
- 无线接入隔离、802.1X 与二层安全控制;
- 监控异常 RA、前缀、默认路由与邻居状态变化。
RA Guard 自身也需要支持扩展首部感知等正确实现,不能只配置一个开关就宣称攻击面消失。
排障清单
当“有 IPv6 地址但访问失败”时,按证据检查:
- 地址是否仍是
tentative或已dadfailed; - 是否存在 link-local 地址与有效 default route;
- 默认路由对应的 RA lifetime 是否过期;
- 目标是 on-link 还是经路由器,neighbor entry 状态如何;
- 防火墙是否允许必要 ICMPv6,尤其 Packet Too Big 与 NDP;
- 源地址选择是否选中了不合适或已 deprecated 的地址;
- 容器/namespace 是否收到 RA,或是否由平台静态配置路由。
本课小结
NDP 把地址解析、路由器发现、DAD 和邻居可达性确认放进 ICMPv6。SLAAC 负责根据通告生成和维护地址,RA 仍是默认路由的核心来源;DHCPv6 可以补充或接管部分配置,但不能简单替代 RA。
下一课讨论这些机制进入真实应用后的问题:DNS、地址选择、Happy Eyeballs、IPv6-only 与 NAT64。
规范入口
- RFC 4861:Neighbor Discovery for IPv6;
- RFC 4862:IPv6 Stateless Address Autoconfiguration;
- RFC 7217:Stable and Opaque Interface Identifiers;
- RFC 8981:Temporary Address Extensions;
- RFC 8106:IPv6 Router Advertisement Options for DNS Configuration;
- RFC 8415:DHCP for IPv6。