三亩地 三亩地SAN MU DI · CODE DIARY
ARTICLE DETAIL

日记详情

真实记录编程学习的某一天,欢迎挑你感兴趣的翻一翻。

用Wireshark抓包,一步步拆解IPv6 SLAAC自动配置的完整流程(附报文详解)

用Wireshark抓包,一步步拆解IPv6 SLAAC自动配置的完整流程(附报文详解)

用Wireshark实战解析IPv6 SLAAC自动配置全流程

第一次在Wireshark中看到IPv6的SLAAC过程时,那些看似杂乱的十六进制数字让我完全摸不着头脑。直到某次故障排查中,我不得不硬着头皮逐字节分析RA报文,才发现这些数字背后隐藏着一套精妙的地址自组织逻辑。本文将带你用侦探式抓包分析法,从零还原IPv6主机如何"无中生有"地获得全球单播地址的全过程。

1. 实验环境搭建与抓包准备

在开始抓包前,我们需要一个干净的实验环境。推荐使用VirtualBox创建两台虚拟机(一台Linux主机+一台路由器),这样能避免生产环境中的流量干扰。关键配置点:

# 在Linux主机上启用IPv6并关闭无关服务 sudo sysctl -w net.ipv6.conf.all.disable_ipv6=0 sudo systemctl stop radvd

必备工具清单

  • Wireshark 3.6+(支持最新的IPv6扩展头解析)
  • tcpdump(用于后台长时间抓包)
  • ndisc6工具包(手动发送RS/RA报文)

提示:在虚拟网络配置中,务必关闭DHCPv6服务,否则会干扰纯SLAAC过程

启动Wireshark时,选择正确的网卡并设置过滤条件:

icmpv6.type == 133 || icmpv6.type == 134 || icmpv6.type == 135 || icmpv6.type == 136

这个过滤器会只显示SLAAC相关的四种ICMPv6报文,避免其他流量干扰分析。

2. 触发SLAAC流程的三种方式

不同于DHCP的请求-响应模式,IPv6 SLAAC的触发更加灵活。在实际抓包中,我总结出三种常见触发场景:

场景对比表

触发方式典型报文序列适用场景抓包特征
周期性RARA -> NS -> NA常规网络环境固定间隔(默认200秒)
主动RS请求RS -> RA -> NS -> NA新接入设备主机先发送RS
重启接口NS -> NA(DAD)接口重置后源地址::

最值得分析的是第二种场景。当主机刚接入网络时,会主动发送RS报文(ICMPv6 Type=133)加速地址获取。以下是手动触发命令:

# 在Linux主机上发送RS报文 rdisc6 -1 eth0

此时Wireshark会捕获到类似这样的帧:

Frame 123: 70 bytes on wire Destination: ff02::2 (All-Routers) Source: fe80::1a2b:3c4d ICMPv6 Router Solicitation Type=133, Code=0 Option: Source link-layer address

3. 深度解码RA报文的关键字段

路由器的RA报文(ICMPv6 Type=134)是SLAAC的核心。在一次实际抓包中,我捕获到这样一个典型的RA报文:

Internet Protocol Version 6 Source: fe80::1 Destination: ff02::1 Hop Limit: 255 ICMPv6 Router Advertisement Type: 134 Cur hop limit: 64 Flags: 0xc0 (Managed, Other) Router lifetime: 1800s Reachable time: 30000ms Retrans timer: 1000ms ICMPv6 Option - Prefix Information Prefix: 2001:db8:acad::/64 Valid Lifetime: 2592000s Preferred Lifetime: 604800s Flags: 0xc0 (On-link, Autonomous)

关键字段解析

  1. Flags字段(0xc0):

    • 最高位1表示"Managed":建议主机使用DHCPv6获取其他配置
    • 次高位1表示"Other":DNS等信息需要通过DHCPv6获取
  2. Prefix Information选项

    • Valid Lifetime:该前缀的有效期(秒)
    • Preferred Lifetime:推荐使用期限
    • 自治标志(A)决定是否用于SLAAC

注意:Windows和Linux对RA标志位的处理存在差异。Windows会严格遵循Managed标志,而Linux通常忽略该标志继续使用SLAAC

4. 地址生成与DAD检测全流程

收到RA后,主机会执行以下动作:

  1. 生成临时地址

    # 伪代码展示EUI-64生成过程 def generate_eui64(mac): mac[0] ^= 0x02 # 反转U/L位 return mac[:3] + [0xff, 0xfe] + mac[3:] prefix = "2001:db8:acad::/64" interface_id = generate_eui64([0x00,0x1c,0x42,0x5f,0x01,0x0a]) global_address = prefix[:-3] + interface_id
  2. 重复地址检测(DAD)

    • 主机发送NS报文(Type=135)询问目标地址是否被占用
    • 源地址为::,目标地址为请求节点组播地址
    • 若收到NA回复(Type=136),则放弃使用该地址

典型DAD抓包示例

Neighbor Solicitation Source: :: Target: 2001:db8:acad::1a2b:3c4d Option: Source link-layer address
  1. 地址生效: 成功通过DAD后,主机会在RA的Preferred Lifetime内优先使用该地址。可以通过ip -6 addr show验证:
2: eth0: <BROADCAST> inet6 2001:db8:acad::1a2b:3c4d/64 scope global valid_lft 2592000 preferred_lft 604800 inet6 fe80::1a2b:3c4d/64 scope link valid_lft forever preferred_lft forever

5. 实战排错:常见问题与报文分析

在真实网络中,SLAAC可能因各种原因失效。以下是三个典型案例:

案例1:RA未携带A标志

  • 症状:主机只有link-local地址
  • 抓包特征:RA中Prefix Information的Flags字段A位为0
  • 解决方案:检查路由器配置,确保ipv6 nd prefix 2001:db8::/64 autonomous

案例2:DAD失败

  • 症状:地址停留在tentative状态
  • 抓包分析:发现冲突的NA报文
  • 解决方法:检查网络是否存在IP冲突,或临时禁用DAD:
    sudo sysctl -w net.ipv6.conf.eth0.accept_dad=0

案例3:前缀过期

  • 抓包关键点
    - Valid Lifetime: 2592000 + Valid Lifetime: 0
  • 应急处理:手动添加临时地址:
    sudo ip -6 addr add 2001:db8::123/64 dev eth0

6. 高级技巧:定制化SLAAC实验

对于想深入研究的读者,可以尝试这些实验:

  1. 修改RA时间参数

    interface GigabitEthernet0/0 ipv6 nd ra interval 10 30 ipv6 nd ra lifetime 900
  2. 捕获不同优先级的RA

    • 在RA的Flags字段中,Prf位表示路由器优先级
    • 00=Medium, 01=High, 11=Low
  3. 分析多前缀场景

    ICMPv6 Option - Prefix Information (1) Prefix: 2001:db8:100::/64 ICMPv6 Option - Prefix Information (2) Prefix: 2001:db8:200::/64

    主机会为每个A标志置位的前缀生成地址

通过反复修改这些参数并观察报文变化,你会对IPv6的地址自动配置机制产生更直观的理解。记得每次实验前清除主机的IPv6地址缓存:

sudo ip -6 addr flush dev eth0
← 返回列表