3. IPv6基础协议与双栈主机配置

IPv6 主机要真正“上网”,第一步不是配路由协议,而是把地址、前缀、网关和 DNS 这些基础参数拿到手。与 IPv4 依赖 ARP、手工地址和 DHCP 不同,IPv6 把地址解析、邻居发现、路由器发现、地址自动配置整合进了一套 ICMPv6 报文体系,这就是 NDP(Neighbor Discovery Protocol,邻居发现协议)。理解 NDP、SLAAC 与 DHCPv6 三者的分工,是双栈主机配置的核心。

一、NDP:IPv6 的“控制面底座”

NDP 定义在 RFC 4861,运行在 ICMPv6 之上,使用五类关键报文:

  • RS(Router Solicitation,类型 133):主机启动或链路变化时,向 ff02::2(所有路由器)组播,请求路由器立即通告前缀信息。
  • RA(Router Advertisement,类型 134):路由器周期性或响应 RS 时,向 ff02::1(所有节点)组播,携带前缀、前缀长度、默认网关、M/O 标志、跳数限制、MTU 等。
  • NS(Neighbor Solicitation,类型 135):用于地址解析(替代 ARP)和重复地址检测(DAD),目的地址为被请求节点的 solicited-node 组播地址 ff02::1:ffXX:XXXX。
  • NA(Neighbor Advertisement,类型 136):对 NS 的应答,携带目标链路层地址和 R/S/O 标志。
  • Redirect(类型 137):路由器告知主机存在更优的下一跳。

其中 RA 报文中的两个标志位决定了主机如何获取地址:M 位(Managed Address Configuration)置 1 表示地址通过 DHCPv6 获取;O 位(Other Configuration)置 1 表示 DNS、域名等其他参数通过 DHCPv6 获取。这两个标志的组合,直接决定了 SLAAC 与 DHCPv6 的协作方式。

NDP / SLAAC / DHCPv6 协作关系 双栈主机 IPv6 接口 fe80::/10 链路本地 DAD 检测中… 等待 RA / DHCPv6 IPv6 路由器 2001:db8:1::1/64 周期 RA 发送 M 位 / O 位控制 默认网关 DHCPv6 服务器 地址池 / DNS / 域名 UDP 546 ↔ 547 RS (ff02::2) RA (ff02::1) 前缀+M/O标志 Solicit/Advertise Request/Reply RA 标志组合: M=0, O=0 → 纯 SLAAC(地址+其他参数均自动生成) M=0, O=1 → SLAAC 地址 + DHCPv6 获取 DNS M=1, O=1 → DHCPv6 分配地址 + 其他参数 M=1, O=0 → 仅 DHCPv6 分配地址

二、SLAAC:无状态地址自动配置

SLAAC(Stateless Address Autoconfiguration,RFC 4862)让主机无需服务器即可生成全球单播地址。流程分三步:

  1. 生成链路本地地址:接口启用 IPv6 后,主机用 fe80::/64 前缀加上接口标识(EUI-64 或稳定隐私地址 RFC 7217)生成链路本地地址。
  2. DAD 重复地址检测:主机向该地址对应的 solicited-node 组播地址发送 NS,若在约 1 秒内未收到 NA,则认为地址唯一,可以启用。
  3. 接收 RA 生成全球地址:主机收到 RA 后,取 RA 中的前缀(如 2001:db8:1::/64)与接口标识拼接,再次 DAD 后启用。默认网关即 RA 的源地址(链路本地地址)。

以 EUI-64 为例,MAC 地址 00:1A:2B:3C:4D:5E 先插入 FF:FE 变为 00:1A:2B:FF:FE:3C:4D:5E,再将第一字节的 U/L 位取反(00 → 02),得到接口标识 021A:2BFF:FE3C:4D5E,最终地址为 2001:db8:1::021a:2bff:fe3c:4d5e/64。实际工程中更推荐启用稳定隐私地址,避免暴露 MAC 信息。

三、DHCPv6:有状态配置

当 RA 中 M 位置 1 时,主机通过 DHCPv6 获取地址。DHCPv6 使用 UDP:客户端 546,服务器 547,通过组播 ff02::1:2 发现服务器。典型四步交互为 Solicit → Advertise → Request → Reply;若客户端已有服务器信息,可简化为 Request → Reply 两步。DHCPv6 还支持前缀委派(PD),用于给下游路由器分配 /56 或 /60 前缀。

需要区分两种模式:有状态 DHCPv6 分配地址和参数;无状态 DHCPv6 只分配 DNS、域名等参数,地址仍由 SLAAC 生成。工程中常见组合是“SLAAC 地址 + 无状态 DHCPv6 下发 DNS”,即 M=0、O=1。

四、双栈主机配置实战

下面以 Linux 主机为例,演示自动配置与手工配置两种方式。假设路由器接口为 2001:db8:1::1/64,DNS 为 2001:db8:1::53。

自动配置(SLAAC + 无状态 DHCPv6):

# 启用 IPv6 并接受 RA
sysctl -w net.ipv6.conf.eth0.accept_ra=1
sysctl -w net.ipv6.conf.eth0.autoconf=1

# 查看自动生成的地址
ip -6 addr show dev eth0
# inet6 2001:db8:1::021a:2bff:fe3c:4d5e/64 scope global dynamic
# inet6 fe80::21a:2bff:fe3c:4d5e/64 scope link

# 查看默认路由(来自 RA)
ip -6 route show default
# default via fe80::1 dev eth0 proto ra metric 1024

# 若 O=1,用 dhclient 获取 DNS
dhclient -6 -S eth0
cat /etc/resolv.conf
# nameserver 2001:db8:1::53

手工配置(静态地址):

ip -6 addr add 2001:db8:1::100/64 dev eth0
ip -6 route add default via 2001:db8:1::1 dev eth0
echo "nameserver 2001:db8:1::53" >> /etc/resolv.conf

# 验证连通性
ping6 -c 3 2001:db8:1::1
ping6 -c 3 2001:db8:1::53

配置完成后,用 ip -6 neigh show 查看邻居缓存,用 ping6 验证网关和 DNS 可达性。若地址显示 tentative,说明 DAD 未完成或检测到冲突;若 dadfailed,则地址重复,需要更换接口标识或排查是否有其他主机占用。

排障提示:主机拿不到 IPv6 地址时,按顺序检查:① 接口是否启用 IPv6(sysctl net.ipv6.conf.eth0.disable_ipv6 应为 0);② 是否收到 RA(tcpdump -i eth0 icmp6 and ip6[40]==134);③ RA 的 M/O 标志是否符合预期;④ DHCPv6 服务器是否可达(ff02::1:2 组播是否被阻断);⑤ 防火墙是否放行 ICMPv6 类型 133-137 和 UDP 546/547。
注意:手工配置静态地址时,必须确保该地址不在 DHCPv6 地址池或 SLAAC 前缀范围内,否则可能引发地址冲突。生产环境建议优先使用 SLAAC + 无状态 DHCPv6,既保留即插即用能力,又能集中管理 DNS 等参数。

总结来看,NDP 提供邻居发现和路由器发现能力,SLAAC 负责无状态地址生成,DHCPv6 负责有状态地址或参数下发。双栈主机配置时,先确认 RA 的 M/O 标志,再选择自动或手工方式,最后通过 ip -6 addr、ip -6 route 和 ping6 验证地址、网关与 DNS 是否全部就绪,才算完成一个可用的 IPv6 主机接入。