IPv6 速成小记 & 与 IPv4 的区别

 

如题, 已有一些 IPv4 的基础知识, 来速成一下 IPv6…

一直没仔细研究过 IPv6 的具体规范, 属于是在使用过程中自行总结加搜索发现了一些规律… 直到遇到了南京大学的无力吐槽校园网配置, 正好来基于 IPv4 来速成 IPv6 (记录 v6 比 v4 新增/不同的部分).

为什么需要 IPv6 及 IPv6 现况

网际协议第6版(英语:Internet Protocol version 6,缩写:IPv6)是网际协议的最新版本,用作互联网的协议。用它来取代IPv4主要是为了解决IPv4地址枯竭问题,同时它也在其他方面对于IPv4有许多改进。

IPv6的设计目的是取代IPv4,然而长期以来IPv4在互联网流量中仍占据主要地位,IPv6的使用增长缓慢。在2022年4月,通过IPv6使用Google服务的用户百分率首次超过40%。

对于中国家庭宽带用户来说, 最直观的体验就是每个设备都能拥有自己的公网 IP 了, 不用和运营商扯皮也不用配置端口转发了! 原本的两层 NAT (运营商 + 路由器) 给互联互访带来了许多不便.

目前有了 v6 挂 BT/PT, 公网互访, P2P VPN 组网都会好一点. 对于部分网站可能 v6 访问的线路更加空闲, 当然也有部分网站会绕路导致体验变差.

虽然现在 IPv6 在全国范围的支持还不是非常完善, 属于是一种有地址但不完全能用的状态, 但总比完全没有公网 IP 强.

虽然 Wikipedia 说 IPv6 目标是取代 IPv4 网络, 但目前由于 v6 覆盖缓慢, 部分网站, 软件和旧设备仍不支持 v6, 如果只使用 v6 的话还是会导致许多兼容性问题.(比如 2023 年了 GitHub 还没支持 IPv6…) 所以现在主流还是 IPv4 和 IPv6 双栈共存.

地址格式

IPv4 地址通常表示为点分十进制, 如 1.1.1.1, 127.0.0.1

IPv6 地址通常表示为 2001:bc8:1d80:202f::1, fc00::1, 2409:8a20:5803:572f:ad64:b46f:d5a9:5bea

IPv6 地址是由 8 组 4 位十六进制表示的, 组间用冒号分隔, 每组的前导 0 可以忽略, 连续的若干组 0 可以用双冒号 :: 表示.

2001:0db8:02de:0000:0000:0000:0000:0e13 可表示为 2001:db8:2de:0:0:0:0:e13 可表示为 2001:db8:2de::e13

国内三大运营商移动分配的是 2409::/16, 电信分配的是 240e::/16, 联通是 2408::/16.

IPv6 的分配是分区的, 这里可以查到国内 IPv6 的分配情况. (类似于你可以用手机号查到归属地)

特殊地址

未指定地址

IPv4 下为 0.0.0.0/8, IPv6 下为 ::/128, 仅当来源 IP 不确定时使用.

专用地址 (私有地址)

IPv4 为 10.0.0.0/8 172.16.0.0/12192.168.0.0/16 三段, 也就是路由器内网 NAT 后分配的地址, 常常称作”内网 IP”.

IPv6 为 fd00::/8, 叫做 ULA, 实际使用时会在该前缀下再随机 40 位, 作为 48 位的前缀使用.

ULA 地址在 OpenWRT 系统下可以在网络-接口-全局网络选项下查看和设置ULA 地址在 OpenWRT 系统下可以在网络-接口-全局网络选项下查看和设置

虽然 IPv6 一般不使用 NAT 技术, 但也有少数情况不得不使用 NAT6, 这时候就会将这个 ULA 下的地址分配给局域网主机.

链路本地地址

IPv4 下为 169.254.0.0/16, 仅供广播域内的主机之间相互通讯使用. 实际上一般只在 Windows DHCP 无法获取 IP 的时候会自动配置这里的地址, 这个地址并不太常见.

IPv6 下为 fe80::/10, 与 IPv4 不同的是, IPv6 要求每一个启用了 v6 的接口都有 link-local 地址(NDP / DHCPv6 等协议需要用到), 所以只要操作系统启用了 IPv6 支持, 接口就会有一个自动生成的 fe80::/10 下的 link-local 地址.

在没有分配 IPv6 地址的 VPS 上, 接口也有自动生成的 link-local 地址在没有分配 IPv6 地址的 VPS 上, 接口也有自动生成的 link-local 地址

运营商级NAT (CGNAT, IPv4-only)

IPv4 下专有的一段保留地址, 用于运营商侧的 NAT. 也就是设备直接 PPPoE 拨号后路由器直接得到的 IPv4 地址, 使用 100.64.0.0/10 段.

多播地址

IPv4 下为 224.0.0.0/4, v6 下为 ff00::/8.

IPv6 中, ff02::1 是网络中所有节点的多播组, ff02::2 是所有路由的多播组, 详见 RFC 4291.

地址分配

IPv4 地址分配

除了手动静态配置外, IPv4 还能使用 DHCP 请求地址分配.

DHCPv4 分配的过程如下:

  1. 客户端在局域网内广播 DHCP Discover 消息, 寻找可用的 DHCP 服务器. (此时还没有地址, 使用 255.255.255.255 作为目标广播地址, 0.0.0.0 作为源地址, 使用 UDP 协议, 源端口 68 目标端口 67)
  2. 服务端选择一个没有使用的地址, 广播发送包含 IP 地址, 子网掩码, DNS 服务器等信息的 DHCP Offer 消息.
  3. 客户端收到第一个 Offer 后, 广播发送 DHCP Request 消息, 包含其选中的 IP 地址.
  4. 服务端收到客户端的 Request 后, 若无冲突则广播发送 DHCP ACK 消息进行确认, 客户端收到 ACK 后则使用选中的 IP 地址进行自动配置和通讯.

一次抓包到的 DHCP 地址分配过程, 所有包都使用广播发送, 有 Transaction ID 用于区分一次抓包到的 DHCP 地址分配过程, 所有包都使用广播发送, 有 Transaction ID 用于区分

IPv6 地址分配

v6 的地址分配与 v4 有许多不同, 容我慢慢道来…

IPv6 中 ARP 协议被 NDP 协议取代, 同时 NDP 也承载了 IPv6 地址动态分配的职责.

NDP 协议定义了几种新的 ICMPv6 报文, 其中就包括了用于地址动态分配的 Router SolicitationRouter Advertisement 两个包, 简称 RS 和 RA.

以下是 IPv6 动态地址分配的过程:

  1. 当主机试图使用动态地址分配时, 会先广播发送 路由器请求 (Router Solicitation) 包, 路由器收到 RS 包后会尽快回复 路由器通告 (Router Advertisement) 包, 路由器也会定期广播发送 RA 包.

    RS包内容RS包内容

    RA包内容以及开头的 FlagsRA包内容以及开头的 Flags

    RA 包的开头 Flags 中有 M 和 O 两个标识位:

    • M 为受监管的地址配置标志, 设为 1 时代表 IPv6 地址要从 DHCPv6 获取
    • O 为其他配置标志, 设为 1 时代表 其他配置信息要从 DHCPv6 获取

    RA 消息后还有一些 Options 选项部分, 其中包含 Prefix information, 该 Option 中含有前缀信息和另一个 Flag, 包含 L 和 A 两个标识位.

    • L 为”在链路”(on-link) 标志, 设为1时指示前缀可用于“在链路”判定
    • A 为自动地址配置标志, 设为 1 时指示前缀可用于 SLAAC

    RA包中的 Prefix informationRA包中的 Prefix information


    根据上面的 M/O/A 三个标志位, IPv6 的动态地址分配有两种不同的模式: SLAACDHCPv6

    M(Managed) 设置为 1 时, 使用有状态 DHCPv6

    O(Other) 设置为 1 且 A(Autonomous) 为 1 时, 使用 SLAAC + 无状态 DHCPv6

    当 M 和 O 都为 0 且 A(Autonomous) 为 1 时, 仅使用 SLAAC

  2. SLAAC 模式

    由于 IPv6 有巨大的地址空间, 所以相比 IPv4 多了一种”无状态”的地址分配方式.

    结合 64bit 的前缀和 64bit 的接口标识 (Interface ID), 直接拼接就可以得到本机的 IP 地址.

    接口标识有几种生成方式:

    1. 手工配置
    2. 使用 MAC 地址生成 EUI-64
    3. 使用临时生成的随机接口标识
    4. 使用隐私拓展生成稳定的接口标识

    总之就是每台机器可以自己生成 64bit 的一个接口标识, 与 RA 中的 Prefix 直接拼接成自己的地址, 无需向服务器请求固定的地址, 因此称为”无状态”. (同时 SLAAC 要求一个 64bit 的 Prefix 才能工作)

    同时上述 Interface ID 也用于和 fe80:: 拼接生成每个接口的 link-local 地址.

  3. DHCPv6 (有状态+无状态)

    当需要 DHCPv6 时, 主机会启动 DHCPv6 客户端, 无状态的 DHCPv6 只会用于获取除 IP 地址外的一些配置信息(如 DNS 服务器), 地址还是按照 SLAAC 分配, 有状态的 DHCPv6 会用于获取 IP 地址.

    DHCPv6 获取地址的大致思路与 v4 下类似, 分为 Solicit, Advertise, Request, Reply 四个步骤, 最终直接从 DHCPv6 服务端得到分配的 IP 地址. 在实现细节上略有不同, 不再赘述, 可以参考 Wiki 或相关 RFC.

有张相关的表格:

M-比特O-比特A-比特主机地址其他配置
000静态设置手工配置
001前缀由 RA 指定,自动生成手工配置
010静态设置DHCPv6
011前缀由 RA 指定,自动生成DHCPv6
100有状态 DHCPv6DHCPv6
101有状态 DHCPv6 和/或 自动生成DHCPv6
110有状态 DHCPv6DHCPv6
111有状态 DHCPv6 和/或 自动生成DHCPv6

IPv6 子网模型

与 IPv4 使用 IP 地址和子网掩码判断子网不同, IPv6 会通过独立的 on-link determination 过程判断目标主机是否 “on-link”, RFC 5942 详细的阐述了这个过程.

简而言之, 当接入网络的主机需要发送数据包时, 默认只有 link-local 地址是在链路上的. 对于非 link-local 地址, 它会遍历之前收到的 RA 包中的 Prefix information 来判断目标主机是否 on-link, 如果目标地址属于某个前缀, 该前缀 L 标志为 1, Lifetime 非 0, 则该目标在链路上.

在链路上的主机就可以直接通过 NDP 找到其 MAC 地址, 与其直接通讯, 否则需将数据包目标 MAC 地址设置为路由器的 MAC 进行转发.


研究完了文档和协议, 我们来看一些实际的…

IPv6 与国内运营商

先引入一个新概念叫 Prefix Delegation, 简称 PD, 常用于 ISP 给用户提供一段前缀, 用于让用户自己在内网分配 IPv6 地址, 前缀的长度一般在 48 - 64 之间, 各地运营商具体落实不一, 前缀不得 > 64 否则 SLAAC 无法正常工作.

在家庭宽带光猫改桥接, 并使用 OpenWRT 路由器拨号后, 可能会有几种情况:

  1. 没有 IPv6 地址…

    只能找运营商扯皮了… 不过绝大部分地区应该已经覆盖了, 你应该先检查自己的 OpenWRT 配置.

  2. 有 IPv6 地址但没有 PD 前缀

    这样的运营商比较少, 可我苏州移动偏偏就遇到了… 这种情况下也应该尝试找运营商扯皮.

    在 OpenWRT 拨号后, 只有 OpenWRT 本身可以拿到 IPv6 地址, 但无法继续给连接到它的设备分发地址.

    需要配置 IPv6 relay 将上级的地址传递下去.

  3. 有 IPv6 地址 和 PD 前缀

    拿到 PD 前缀就可以继续给路由器下面的设备分配地址了. 如果拿到的是 /64 前缀就只能分一个子网, /60 就能分 2^4=16 个, 以此类推.

    这种情况下 OpenWRT 默认配置就能使下面的设备正常拿到公网 IPv6 地址并上网. (ISP 本来就应该分发前缀.)

OpenWRT 拨号后截图, 图中没有 PD, 如果有会多一行 IPv6-PDOpenWRT 拨号后截图, 图中没有 PD, 如果有会多一行 IPv6-PD

IPv6 与 VPS

很多 VPS 厂商也支持 IPv6 地址, 也有些厂商为了降低成本会推出廉价的仅 IPv6 的 VPS, 或者对 IPv4 地址收费. (毕竟 IPv4 也算是珍贵稀缺资源… 这类 VPS 只有套 WARP 可以访问 IPv4 网络)

VPS 厂商分配 IPv6 前缀常常比较慷慨, 可以给 /56 甚至 /48 的前缀, 一般在公网上一个 /64 下的设备会被认为是同一来源, 那同一个 /56 就相当于你有了 2^8 个不同身份. (当然风控策略也很复杂, 具体情况具体分析.)

还有就是 IPv6 的墙普遍比较低.(这是能说的吗)

校园网 IPv6

校园网的 IPv6 坑多到无力吐槽, 由于每个学校的校园网配置可能各有各的离谱, 所以不再详说南京大学的校园网 IPv6 情况了… 可以参考 YDJSIR这篇茶栗这篇 博客.

我目前是直接在宿舍使用 OpenWRT 路由器, 默认配置下 WAN 口接宿舍网口是不能直接获取 IPv6 地址的, 日志中有 Server returned IA_NA status: No prefix available (NoPrefixAvail) 报错. 将 wan6 接口的设置 请求指定长度的 IPv6 前缀 改为 已禁用 可以获取一个 /128 的 IPv6 地址. 随后使用(十分丑陋的) NAT6 让局域网设备可以使用 IPv6 网络.

本文采用 CC BY-NC-SA 4.0 许可协议发布.

作者: lyc8503, 文章链接: https://blog.lyc8503.net/post/ipv6-differences/
如果本文给你带来了帮助或让你觉得有趣, 可以考虑赞助我¬_¬