IPv6 入门:地址空间与协议变化

几乎每个人对 IPv6 的第一印象都是同一句话:IPv4 地址不够用了,所以换了个更长的地址。这句话没错,但它会把你带偏——它让你以为 IPv6 只是把数字从 32 位换成 128 位的「同一套东西的加长版」,于是你背下「128 位」这个数字就觉得学完了。可真正用起来你会发现,IPv6 改的不只是地址长度:主机怎么拿到地址、怎么找到同一网段的邻居、首部里有哪些字段、谁负责分片,这些运转机制全都换了一遍。

所以这一篇我们不从「为什么要换」讲起,而是先把机制讲透:一个 IPv6 地址是怎么构成、怎么压缩书写的,一台主机插上网线后是怎么靠 SLAAC 自己算出地址的,它又是怎么用邻居发现协议找到网关 MAC 的,首部被简化成了什么样子。 把这些「它到底怎么转起来」看清楚之后,再回头解释每一处改动是为了清理 IPv4 的哪一个历史包袱。

学 IPv6 不要只盯着「位数更多」,要盯住它把哪些机制重新设计了——地址自动配置、邻居发现、首部结构,这些才是你日后真正会踩到的地方。

一、先看清一个 IPv6 地址长什么样

机制的起点是地址本身的结构。IPv6 地址是 128 位,按惯例写成 8 组、每组 4 位十六进制数,组间用冒号分隔:

1
2001:0db8:0000:0000:0000:ff00:0042:8329

直接这么写太长,于是 IPv6 定义了两条压缩规则,你必须能机械地套用它们,否则连地址都读不顺:

  • 规则一:每一组前导的 0 可以省略。 0db8 写成 db80042 写成 420000 写成 0
  • 规则二:一段或多段连续全 0 的组,可以用一个 :: 整体替换,但全地址只能用一次。 上面的地址里中间三组连续是 0000,于是可以压成 2001:db8::ff00:42:8329

为什么 :: 只能出现一次?因为它代表「这里补足够多的 0 把地址凑到 128 位」。如果出现两次,解析器就无法判断每个 :: 各自该补几组 0,地址就有歧义了。这是个纯粹的机制约束,记住它你就不会写出非法地址。

和 IPv4 一样,IPv6 地址也分网络部分接口部分,用前缀长度标记,比如 2001:db8::/32 表示前 32 位是网络前缀。绝大多数普通网段用 /64前 64 位是网络前缀,后 64 位是接口标识符。这个「64 位接口标识符」是后面 SLAAC 自动配置能成立的关键,先记住这个分界线。

二、地址不是只有一种:理解地址类型

IPv4 里你习惯了「一个网卡一个地址」。IPv6 彻底改了这个习惯——一个接口同时持有好几个地址是常态,而且每个地址有明确分工。这是机制层面最容易让人懵的一点,先把类型摆清楚:

  • 链路本地地址(Link-Local):以 fe80::/10 开头。任何 IPv6 接口一旦启用,必定会自动生成一个,只在本链路(同一网段)内有效,不可路由。它是邻居发现、自动配置这些机制能跑起来的「启动地址」。
  • 全局单播地址(GUA):类似 IPv4 的公网地址,全球可路由,通常以 2000::/3 开头。
  • 唯一本地地址(ULA)fc00::/7,类似 IPv4 的私有地址(10.x192.168.x),用于内网。
  • 多播地址(Multicast)ff00::/8 开头。IPv6 取消了广播,所有「发给一组人」的需求都用多播实现。

IPv6 没有广播。IPv4 里那种「向全网段吼一嗓子」的 ARP 广播,在 IPv6 里被「只发给特定多播组」取代了——这是它降低无谓打扰、清理广播风暴隐患的一个核心设计。

三、SLAAC:主机怎么自己算出地址

这是 IPv6 与 IPv4 差别最大、也最能体现「机制变了」的地方。IPv4 主机要么手工配地址,要么靠 DHCP 服务器分配。IPv6 提供了第三条路——无状态地址自动配置(SLAAC),主机不需要任何 DHCP 服务器,自己就能算出一个全局地址。我们一步步看它怎么转:

  1. 接口启动,自生成链路本地地址。 主机用 fe80::/10 前缀拼上自己的接口标识符,立刻得到一个链路本地地址,先具备了在本网段说话的能力。
  2. 重复地址检测(DAD)。 主机向那个候选地址发一个邻居请求(NS)多播,问「这个地址有人用了吗」。没人回应,才确认地址可用——这是 IPv6 自动配置里防地址冲突的机制。
  3. 发路由器请求(RS)。 主机向「所有路由器」多播地址发一个 Router Solicitation,喊一声「这网段的前缀是多少」。
  4. 路由器回路由器通告(RA)。 网关回一个 Router Advertisement,里面带着网络前缀(通常是个 /64)和默认网关信息。
  5. 拼接成全局地址。 主机拿到这个 /64 前缀,拼上自己的 64 位接口标识符,就得到了一个完整的全局单播地址。
sequenceDiagram participant H as 主机 participant R as 路由器(网关) Note over H: 接口启动,生成 fe80:: 链路本地地址 H->>H: DAD 重复地址检测(NS 多播) H->>R: Router Solicitation(我要前缀) R->>H: Router Advertisement(前缀=2001:db8:1::/64, 网关) Note over H: 前缀 + 接口标识符 = 全局地址 Note over H: 2001:db8:1::接口ID

看懂这张图,你就理解了 SLAAC 的精髓:前缀来自路由器,主机部分由自己生成,两者拼接成完整地址。 它和分页里「页框号 + 页内偏移拼成物理地址」是一个味道——高位由外部给定,低位自己负责,拼起来即可。那 64 位接口标识符早期常用 EUI-64(从网卡 MAC 推导),但因为 MAC 暴露隐私、还能被用来追踪设备,现代系统普遍改用随机生成的临时地址,定期轮换。

四、邻居发现协议(NDP):ARP 去哪了

IPv4 里,同网段两台主机互通要靠 ARP:广播「谁是 192.168.1.1,告诉我你的 MAC」。IPv6 把这件事交给了邻居发现协议(NDP),它跑在 ICMPv6 之上,机制上更干净。核心是两类报文:

  • 邻居请求(Neighbor Solicitation, NS):「IP 是 X 的那位,你的 MAC 是多少?」
  • 邻居通告(Neighbor Advertisement, NA):「是我,我的 MAC 是 YY。」

关键区别在于:ARP 用的是二层广播,全网段所有设备都被打扰、都得拆包看一眼;NDP 的 NS 发往一个叫「被请求节点多播地址」的特定多播组,只有 IP 末尾匹配的少数主机会收到。这样一来,查个邻居 MAC 不再惊动整个网段,二层的无谓流量大幅下降。

NDP 干的事不止解析 MAC,它把 IPv4 里散落在 ARP、ICMP 路由器发现、重定向里的功能整合到一起:邻居可达性检测、路由器发现(上一节的 RS/RA)、地址自动配置、重复地址检测,全在这一个协议族里。这就是 IPv6「架构清理」的一个典型样本——把零散的机制收拢成一套统一的邻居发现。

五、IPv6 首部:为什么字段反而变少了

你可能以为地址变长,首部一定更臃肿。恰恰相反,IPv6 的固定首部被简化到只有 8 个字段、固定 40 字节,比 IPv4 那个长度可变、字段繁多的首部清爽得多。看几处关键变化:

  • 去掉了首部校验和。 IPv4 每经过一跳路由器,TTL 减一就得重算一次校验和,开销不小。IPv6 认为传输层(TCP/UDP)和链路层已经有校验,网络层再算一遍是冗余,干脆删掉——每一跳都省下一次重算,转发更快
  • 去掉了路由器分片。 IPv4 路由器遇到过大的包会就地分片,逻辑复杂还伤性能。IPv6 规定路由器一律不分片,要分片由源主机借助「路径 MTU 发现」提前搞定。路由器只管转发,职责更单纯。
  • 可选项移到扩展首部。 IPv4 把可选功能塞在主首部里,导致首部长度可变、处理麻烦。IPv6 把这些挪到扩展首部,用链式结构挂在固定首部后面,需要才有。常规转发只看那 40 字节固定首部即可。

IPv6 首部的设计哲学是「把固定首部削到最小、让路由器转发路径最短」。地址变长了,但路由器每跳要做的活反而变少了——这是一次面向转发性能的重新分工。

六、看清机制后,再回答「为什么 IPv4 不够用」

现在你已经看清 IPv6 的运转方式,再回头看那个老问题就有了根基。IPv4 是 32 位,理论上约 43 亿个地址。听着不少,但:早期分配粗放(一整个 A 类段动辄给一家机构上千万地址)、利用率低、再加上移动设备和物联网爆发式增长,公网地址早就见底了。

NAT(下一篇会讲)确实把一个公网地址背后藏了成百上千台内网设备,硬是续了命。但 NAT 是补丁式扩展:它破坏了「每台设备都有全球唯一、可直接被访问的地址」这个端到端模型,让 P2P、实时通信都得绕着它做穿透。IPv6 的 128 位地址空间大到什么程度?约 3.4×10³⁸ 个——给地球上每一粒沙子都分配海量地址都用不完,它从根上让端到端寻址重新变得宽裕,不必再靠 NAT 续命。

七、双栈共存:为什么现实里推进没那么快

机制再好,现实网络也不可能一夜推倒重来。海量现有系统、设备、监控、安全策略全是围绕 IPv4 建起来的,迁移成本极高;而 NAT 又让 IPv4 还能继续撑着,缺乏「不换不行」的硬压力。

于是现实世界的主流方案是双栈(Dual Stack):一台主机同时拥有 IPv4 和 IPv6 地址,能用 v6 就用 v6,不行就回落到 v4。这带来一个你必须知道的工程现象——Happy Eyeballs:浏览器/客户端会同时发起 v4 和 v6 连接尝试,哪个先建成功用哪个,避免 v6 链路不通时干等超时。对工程师来说,这意味着相当长时间内两套体系都得看得懂

八、IPv6 给后端 / SRE 带来的实际变化

把机制落到日常工作,这些点会直接影响你:

  • 服务监听。 你的服务真的在监听 IPv6 吗?:: 表示监听所有 IPv6 地址,0.0.0.0 只是所有 IPv4。很多「v6 访问不通」的问题,根因就是服务只 bind 了 v4。注意 [::] 这种带方括号的写法——IPv6 地址里有冒号,会和「IP:端口」的冒号撞车,所以 URL 和配置里要用 [2001:db8::1]:443 把地址括起来。
  • ACL / 安全组。 配了 IPv4 的白名单,别忘了 IPv6 也得配一套,否则双栈下 v6 流量可能绕过你的 v4 规则。
  • 日志与限流。 客户端 IP 可能是一个 IPv6 地址,你的日志解析、按 IP 限流、地理定位逻辑要能正确处理 128 位地址;而且 SLAAC 临时地址会轮换,「按单个 IP 封禁」可能需要按 /64 前缀来做。
  • 不再依赖 ARP。 二层排障从「看 ARP 表」变成「看邻居表」(ip -6 neighbor)。

九、学习这一部分最容易踩的坑

1. 以为 IPv6 只是「地址更长」

这是被那句流行语带偏的最大误区。地址长度只是表象,SLAAC、NDP、首部简化、取消广播和路由器分片才是机制层面的真改动。只盯位数,你日后排障时会发现自己什么都对不上。

2. :: 用了两次

:: 在一个地址里只能出现一次,因为它代表「补足剩余的 0」。写两次会让地址长度无法确定,是非法地址。这是最常见的书写错误。

3. 忘了一个接口有多个地址

IPv6 接口同时有链路本地地址、可能多个全局地址、临时地址。你 ping 不通某个地址,未必是网不通,可能只是用错了地址类型——链路本地地址是不可跨网段路由的。

4. 配 ACL 只配了 v4

双栈环境下,IPv4 规则管不住 IPv6 流量。安全策略必须 v4/v6 各配一份,否则等于给 v6 开了后门。

总结

这一篇我们坚持先讲机制、再讲设计。IPv6 真正的变化,远不止地址从 32 位变成 128 位:

  • 地址按 8 组十六进制书写,靠「省前导 0」和「:: 压连续 0」两条规则压缩,:: 全地址只能用一次;
  • 一个接口同时持有链路本地、全局、临时等多个地址,且 IPv6 取消广播、改用多播;
  • SLAAC 让主机靠「路由器给前缀 + 自己生成接口 ID 拼接」就能自动配出全局地址,无需 DHCP;
  • 邻居发现协议(NDP)用多播的 NS/NA 取代了 ARP 广播,并整合了路由器发现、地址配置等功能;
  • 首部固定为 40 字节,去掉了校验和与路由器分片、把可选项移入扩展首部,换来更快的逐跳转发;
  • 现实里以双栈共存为常态,工程上要同时照顾 v4/v6 的监听、ACL、日志与限流。

当你能说清「一台 IPv6 主机从插上网线到拿到全局地址、找到网关 MAC,中间经历了 DAD、RS/RA、NS/NA 哪几步」,这一篇才算真正吃透。下一篇我们进入路由,看看包离开本网段后,是怎么一跳跳找到目标的。

参考资源