IPv6
的全称是”Internet Protocol Version 6”,它不是在IPv4
做了小的修改,而是彻底改变了协议框架,应该被当成新的协议来学习。最近看到一篇很好的文章IPv6 Cheat Sheet,其中还包含了说明视频,这里做下笔记。
为什么要从 IPv4 到 IPv6?
-
IPv4 的长度为 32 位,网络地址资源严重不足,限制了互联网发展。
- IPv6 的长度为 128 位,“可以为每一粒沙子设置一个 ip 地址”
- IPv6 使用更小的路由表,地址分配一开始就遵循聚原则,大大减小了路由器中路由表的长度,提高了路由器转发数据包的速度
- IPv6 增加了增强的组播(Multicast)支持以及对流的控制(Flow Control),对多媒体应用更友好
- IPv6 加入了对自动配置(Auto Configuration)的支持,使局域网配置管理更加方便
地址长度和格式
IPv6 地址有 128 位(16 字节),将其分为 8 组、每组 2 字节,这 2 字节由四个十六进制表示,组被:
分割:
1 |
|
过多的0
不利于阅读,可以用0
表示0000
的组,同时省略组内的左边的先导0
:
1 |
|
如果有多个组为0
,则可以用::
直接省略中间的0
组:
1 |
|
但是,上面的这种省略只能用一次,否则可能造成歧义:
1 |
|
- 根据
RFC 5952
协议,ff:0:0:0:1::1
也是错的。利用::
进行省略时,应省略最长的连续0
组。而这里省略了后边较短的组。
协议类型
协议号 | 协议类型 | 用途 |
---|---|---|
6 | TCP(v6) | 有状态——确认数据包是否送达,用于可靠通信 |
17 | UDP(v6) | 无状态——不保证包是否送达,适用于流媒体、VoIP 拨号等 |
58 | IPv6-ICMP | 网络本身的控制消息传输,错误报告、网络诊断等 |
- UDP(User Datagram Protocol)
- TCP(Transmission Control Protocol)
-
ICMP(Internet Control Message Protocol)
- 协议类型写在 IPv6 数据包头中
设置 IPv6 地址的方法
- Static(静态设置),直接设置给网卡
- SLAAC(Stateless Address Auto-Configuration),主机自动生成(从无到有,所以是”无状态”)
- IPv4 没有这个功能
- DHCPv6(Dynamic Host Configuration Protocol),从 DHCP 服务器取得设置
作用域和特殊地址
在世界网络中,我们的地址根据作用域而不同。
- GLOBAL 整个 internet
- UNIQUE LOCAL 局域网(LAN,在网关之下)
- LINK LOCAL 无需路由可直连(在同一交换机下)
-
LOCALHOST 主机自己
- ISP(Internet Service Provider) 网络服务商提供最前面的一段 IPv6 前缀,标记一个子网
- 由 IANA(Internet Assigned Number Authority) 将管理这些前缀
- CIDR(Classless Inter-Domain Routine)标记
fc00::/7
表示前面 7 位是最重要的,是本子网的前缀 - CIDR 后面的数字越大,代表当前子网是越下级的子网
特殊地址(单播): | range | Purpose | | ——- | —————————- | | ::1/128 | Loopback Address (localhost) | | ::/128 |Unspecified Address| | 2000::/3| GLOBAL Unicast (Internet)| |fc00::7| Unique-Local (LAN) | |fe80::/10| Link-Local Unicast (Same switch)|
- 通信时应尽量用最小范围的地址进行通信,避免复杂路由
- 一个网卡可以根据不同作用域设置不同地址,最终可以绑定多个地址,这是正常的
子网分配
以上面这个 IPv6 地址为例,前面 64 位是网络分区
部分,后面 64 位是主机地址
部分。在网络分区部分中,前面 48 位是路由前缀
,后面 16 位是子网ID
或子网地址
。
Network+Subnet = Prefix
以2003:1000:1000:1600:1234::1
为例,其完整格式是2003:1000:1000:1600:1234:0000:0000:0001
,由下面几段组成:
-
2003:1000:1000:1600
前缀(由路由前缀 + 子网 ID 组成) -
2003:1000:1000
Routing Prefix(路由前缀),也可以叫路由网络地址 -
1600
子网 ID,也可以叫子网地址
如果我的 ISP(网络服务提供商)提供给我一个前缀
(例如2003:1000:1000:1600/56
),那么它授权给我们的子网段1600~16FF
(包含 256 个子网)就可以我自己分配了。
在 URL 中使用 IPv6
- 在浏览器地址中 IPv6 地址要放在
[...]
中,如http://[2a00:1450:4001:82a::2004]:80
相关工具
-
ping6
ping 联通检查 -
traceroute6
路由信息查看 -
ping -6
在原有工具加上-6
flag,也可以实现相同功能 -
scp
注意在 scp 中加入[]
时,由于在 bash 中是特殊字符,要加\[
转义
Multicast(多播)
前面我们已经学习了如何让两个主机之间通信,这种通信叫做Unicast(单播)。从一个节点向多个节点发出消息叫做Multicast(多播)。
- 使用 Multicast 的场景:
- 一个节点想要和外网相连,这是进行一下广播寻找路由器,路由器会返回结果,告诉它网络前缀和 DNS 服务器地址。
- 当前主机已经通过 SLAAC 设置一个自己的 IPv6 地址,想要在当前子网广播确认一下自己的地址是否重复,这种广播叫DAD(Duplicate Address Detection),如果没有收到别人的响应,则表示没有重复。
link-local 范围内的多播地址:
Range | Purpose |
---|---|
ff02::1 | 同网段下的所有节点 |
ff02::2 | 同网段下的所有路由器 |
ff02::fb | mDNSv6 |
ff02::1:2 | 所有 DHCP 服务器和代理 |
ff02::101 | 所有 NTP 服务器 |
完整的多播地址可参考:IANA
你可以试着 ping 一下上面这些地址,如ping6 ff02::1
ICMP(Internet Control Messages Protocol) 消息类型
ICMP 通过消息类型区分,而不是像通常的协议那样通过端口号区分。致命/重要的类型数值为[1, 127]
,而[128, ...)
是普通消息类型。每个类型都可以有多个子类型,以code
注明。
常用 IPv6 ICMP 类型:
Type | Code | Purpose |
---|---|---|
0 | 保留 | |
1 | 目标不可达 | |
1 | 0 | 到目标无路由 |
1 | 2 | 超出要求的地址范围 |
3 | 次数超限 | |
3 | 0 | 中转跳跃次数超限 |
Type | Code | Purpose |
---|---|---|
128 | 0 | 回复请求(“ping”) |
129 | 0 | 回复 |
133 | 0 | 路由征集 |
134 | 0 | 路由通告 |
135 | 0 | 邻居征集 |
136 | 0 | 邻居通告 |
更完整的信息参考:IANA-ICMPv6 Parameters
DHCPv6(Dynamic Host Configuration Protocol)
IPv6 地址可以被 DHCP 服务器分发。如果一个主机想通过 DHCP 服务器获得 IP 地址,可以向多播地址ff02::1:2
(DHCP 服务器和代理)发出DHCP 征集,发送时用 UDP 协议 546->547 端口。
然后 DHCP 服务器会反向(UDP 547->546 端口)发出DHCP 通告,通告中包含了是否允许主机保留 SLAAC 地址等信息。
最终客户端向 DHCP 服务器发出DHCP 请求,而服务器响应DHCP 响应,结束申请过程。
更多细节请查看:DHCPv6-wiki
DHCPv6 vs. SLAAC
根据不同的路由和客户端配置,客户端可能最终设置多个地址,包括 SLAAC 和 DHCP 获得的。下面显示了可能组合:
使用 WireShark
为了更好地理解 IPv6,可以用抓包工具 WireShark 打印出 IP 数据包。下面是一些抓取 ICMP 和 DHCP 过滤条件:
-
icmpv6 and (icmpv6.type==128) or (icmpv6.type==129)
过滤出 ping 和 ping 的回复 -
icmpv6 and (icmpv6.type==133) or (icmpv6.type==134)
过滤出路由征集和路由通告 -
dhcpv6
过滤出 DHCPv6 的相关通信 -
dhcpv6 or (icmpv6 and (icmpv6.type==134) or (icmpv6.type==133))
综合上面的过滤结果
Unicast(单播) vs. Multicast(多播) vs. Broadcast(广播) vs. Anycast(任意播)
上面这些都是消息发送类型,可以有一个节点发到交换机或路由器处理。
- Unicast(单播),一对一发送,需要发送者指定目标 ip
- Broadcast(广播),对全部发送,在一个广播范围内的全部节点都会收到
- Multicast(多播),要先有特定一些节点订阅了一个多播组,单个节点再在发送时指定组号,只有组内节点会收到消息
- Anycast(任意播),更像是”应急号”,就近(较快)的单个订阅者收到后就不再传播,如果就近没有收到,更远一点的就近接收者才可能收到