PHASE 0 · 加餐 · IPv6

IPv6:另一套地址世界

地址结构、SLAAC,以及为什么 NAT 几乎消失了

前面整个 Phase 0,讲的都是 IPv4 的世界。但你研究 CGNAT 时其实已经撞到这套体系的天花板了——IPv4 地址不够用,正是 NAT、CGNAT 存在的根本原因。IPv6 是绕开这一切的另一条路。这一章是 0.5 与 0.6 之间的加餐,不求全(IPv6 细节足够写一整本书),只讲三件能让你"换一套世界观"的事:地址长什么样、怎么自己配地址、以及为什么到了 IPv6,"NAT"这个词几乎就消失了——最后这点,正好和紧接着的 0.6 NAT 形成对照。

一句话定义

IPv6:IPv4 的继任者,把地址从 32 位扩到 128 位,并重新设计了地址自动配置和邻居发现。核心目的——地址多到永远用不完,从而让 NAT 不再必要。

1为什么需要 IPv6

IPv4 是 32 位,总共 2³²43 亿个地址。听着多,可全球几十亿人、上百亿设备,早就分完了(IANA 顶级地址池 2011 年就已耗尽)。面对地址枯竭,有两条路:

  • 续命:NAT——让一大片内网设备共用一个公网 IP(这正是 0.6 的主题)。CGNAT 更进一步,让一大批用户共用运营商的公网 IP——这就是你研究 CGNAT 撞到的那个根:你家的"公网 IP"可能根本不是真公网,而是运营商 NAT 后面的私网地址,于是端口映射、P2P 直连处处别扭。
  • 换路:IPv6——128 位,2¹²⁸3.4×10³⁸ 个地址。多到给地球上每一粒沙子都分一大把还用不完。地址管够,就不必再让设备挤在一个公网 IP 后面。
数量级直觉

32 位到 128 位,不是"多了 4 倍",是多了 2⁹⁶ 倍——指数级,不是线性。IPv4 的全部 43 亿地址,在 IPv6 里还塞不满一个 /96 子网。

2地址结构:128 位长什么样

IPv6 地址 128 位,写成 8 组、每组 4 位十六进制,冒号分隔,形如:

完整写法
2001:0db8:0000:0000:0000:ff00:0042:8329

这么长当然没人手写。两条缩写规则让它没那么吓人:

  • 每组的前导 0 可省:2001:db8:0:0:0:ff00:42:8329;
  • 一段连续的全 0 组,可用一次 :: 折叠(整个地址只能用一次,否则就还原不出每段有几个 0 了):
缩写后(已验证)
2001:db8::ff00:42:8329          # 上面那个地址的最终缩写
2001:db8::1                     # 2001:0db8:0000:...:0001
::1                             # loopback,相当于 IPv4 的 127.0.0.1

典型的 IPv6 地址在结构上分两半:前 64 位是网络前缀(prefix),后 64 位是接口标识(interface ID)。家用通常分到一个 /64,后 64 位留给本网段的设备自己填。

网络前缀 prefix前 64 位 · 路由器宣告
接口标识 interface ID后 64 位 · 设备自己定

几类你会反复见到的地址:全局单播(公网可路由,常见 2xxx / 3xxx 开头)、链路本地(link-local)(fe80:: 开头,只在本网段有效)、唯一本地(ULA)(fd00:: 一类,相当于 IPv6 版的私网地址)。

你机器上其实早就有 IPv6 了

ip -6 addr(Linux)或 ifconfiginet6(macOS),你几乎一定能看到一个 fe80::… 的链路本地地址——哪怕你从没主动配过 IPv6。它是接口一启用就自动生成的,而它正是下一节 SLAAC / NDP 工作的起点。

3SLAAC 与 NDP:自己配地址,不靠 DHCP

回忆 0.5:IPv4 靠 DHCP(DORA 四步)从服务器领地址。IPv6 有个更去中心化的办法:SLAAC(Stateless Address Autoconfiguration,无状态地址自动配置)——主机听路由器广播的前缀,自己拼出全局地址。流程:

  1. 主机一上线,先有了链路本地地址 fe80::…(基于接口自动生成);
  2. 它发一个路由器请求(Router Solicitation, RS):"本网段的路由器在吗?给我前缀";
  3. 路由器回路由器通告(Router Advertisement, RA):"本网段前缀是 2001:db8:abcd:1234::/64";
  4. 主机把这个 /64 前缀 + 自己的接口 ID,拼成一个完整全局地址,自己配上。

全程没有"服务器分配地址、记录租约"这回事——主机自给自足,所以叫"无状态"。

对照 0.5 的 DORA

DHCP 是"问服务器要一个地址,服务器记账"(有状态);SLAAC 是"问路由器要前缀,自己拼地址"(无状态)。IPv6 也有 DHCPv6,用在需要集中管理、下发 DNS、登记地址的场景;而 RA 本身也能携带 DNS 信息(RDNSS)。日常很多情况,SLAAC 就够了。

上面 RS / RA 用的协议叫 NDP(Neighbor Discovery Protocol,邻居发现),基于 ICMPv6。NDP 不只做路由器发现,还接管了 0.2 里 ARP 的活:IPv4 用 ARP 广播 "who-has 这个 IP",IPv6 改用 NDP 的邻居请求(Neighbor Solicitation, NS)做同一件事——把 IPv6 地址解析成 MAC。所以 0.2 那套 who-has / is-at,在 IPv6 世界换了名字、并从广播改成了多播,继续在跑。

路由器关联 router-link

IPv6 下,你家路由器要发 RA(向内网宣告前缀),还要做 DHCPv6-PD(Prefix Delegation,前缀委派)——向上游 ISP 要来一整个前缀(比如一个 /56/60),再切成若干 /64 分给内网各网段。OpenWRT 里这活儿由 odhcpd 干(0.5 提过它和 dnsmasq 的分工)。没有这一章的地址结构 + SLAAC 底子,到 Phase 2 看 odhcpd 的 prefix delegation 会直接卡壳——这正是当初要给 IPv6 单独留一章的原因。

4观念转变:为什么 IPv6 不需要 NAT

这是这一章真正想让你记住的一点。NAT(0.6 马上讲)的根本动机是:IPv4 地址不够,让一群内网设备共用一个公网 IP。可 IPv6 地址管够——每台设备都能直接拥有一个全局可路由地址。"共享地址"的需求没了,NAT 最主要的存在理由也就没了。这带来两个实质变化:

  • 端到端可达(end-to-end)重新成为可能:两台 IPv6 设备理论上能直接互连,不必打洞、不必端口映射——这恰恰是 IPv4 + NAT(尤其 CGNAT)下 P2P、自建服务那么痛苦的根源。
  • 安全要靠显式防火墙,而不是 NAT:见下面的警告。
别把 NAT 当防火墙

一个常见误解:IPv4 时"外面访问不到内网设备"靠的是 NAT。其实那只是 NAT 的副作用,不是安全设计。到了 IPv6,设备有公网地址、外面理论上可直达,所以必须靠防火墙显式拦截(默认放行出站、限制入站)。这是从 IPv4 迁到 IPv6 时最容易踩的安全坑——0.6 讲完 NAT,你会更清楚"地址转换"和"访问控制"本是两件事。

现实:双栈并存

现实里我们长期处在 IPv4 / IPv6 双栈(dual-stack)并存:你的设备同时持有 IPv4 和 IPv6 地址,优先走 IPv6、回退 IPv4。所以这一章不是要你抛弃前面的 IPv4 知识,而是在它旁边并排放一套新世界观——两套地址体系,会在你的机器里同时活着。

本章小结

  • IPv4(32 位 / 约 43 亿)早已耗尽;续命靠 NAT/CGNAT,换路靠 IPv6(128 位,近乎无限)。
  • IPv6 地址 = 8 组十六进制,:: 折叠一段连续 0(只能用一次);典型结构 = /64 前缀 + 64 位接口 ID;fe80:: 是每个接口自带的链路本地地址。
  • SLAAC:听路由器的 RA 拿前缀、自己拼地址(无状态),对照 IPv4 的 DHCP(有状态)。
  • NDP(ICMPv6)接管了 ARP:who-has → Neighbor Solicitation。
  • 地址管够 → NAT 失去主要理由 → 端到端可达回归;但安全要靠显式防火墙,别再拿 NAT 当防火墙。

动手练习

  1. ip -6 addr(或 ifconfiginet6),找出你接口上的 fe80:: 链路本地地址;它是不是"你从没配过却已经存在"?
  2. 手动缩写一个地址:2001:0db8:0000:0000:0000:0000:0000:0001 → ?(对照本章规则,答案在文中能找到)
  3. 思考题:为什么 :: 在一个地址里只能用一次?(提示:如果出现两次,你还能唯一还原出每一段各有几个 0 吗?)
  4. 进阶:测一下你现在有没有 IPv6 出口——访问 test-ipv6.com,或跑 curl -6 https://ifconfig.co(若超时,说明你的网络 / ISP 暂时只给了你 IPv4)。结合本章想想:这种情况下,你大概率正待在 IPv4 +(CG)NAT 的后面。