目录
文章目录
- 目录
- IPv6
- IPv6 数据包格式
- 固定报头
- 扩展头部
- IPv6 地址格式
- IPv6 网络的基本组成元素
- IPv6 的地址分类和寻址模式
- 单播地址
- 全球唯一地址(Global Unique Address)
- 唯一本地地址(Unique Local Unicast Address)
- 链路本地地址(Link-Local Address)
- 组播地址
- 任播地址
- 特殊的地址
- IPv6 地址的配置方式
- NDP 协议
- NDP 协议的消息类型
- NDP 协议的地址自动配置流程
- 1、路由器发现
- 2、自动生成 Global Unique Address
- 3、重复地址检测
- 4、MAC 地址解析
- IPv4v6 综合组网方案
- 双栈策略
- 隧道策略
- Linux 中的 IPv6 实践
- 开启/关闭 IPv6 支持
- 自动配置 Link-Local Address
- 手动配置 Local Unique Address
- DHCPv6 自动配置 Local Unique Address
- 配置临时 IPv6 地址
- 添加 IPv6 默认路由网关
- 常用命令
- IPv4 与 IPv6 的比较总结
IPv6
我们知道,理论上全球最多可以拥有 42.9 亿个公网 IPv4 地址(2 ** 32 = 4,294,967,296),而截止至 2018 年 1 月,全球上网人数已达 40.21 亿。虽然依靠 NAT 和 CIDR 等网络技术可以延缓 IP 地址匮乏的现象,但为了从解决上根本问题,在 1990 年 IETF(Internet Engineering Task Force,互联网工程任务组)就开始了 IPv6(Internet Protocol version 6,互联网协议第 6 版)协议的规划和设计。
可以说 IPv6 最核心的目的就是为了解决 IPv4 地址枯竭的问题。
IPv6 数据包格式
首先还是从 IPv6 数据包的格式看起,IPv6 Packet 同样由 Header(首部)和 Payload(负载)这 2 部分组成,而 Header 又被细分为 Fixed Header(固定头部)和 Extension Header(扩展头部)。
固定报头
在 IPv6 Header 的设计中,考虑到由于 IPv6 Address 的长度要比 IPv4 Address 大得多,使得常规的 IPv6 Packet 大小已经是 IPv4 Packet 的 4 倍。为了一方面能够尽量减少 Router 处理 IPv6 Header 的开销;另一方面能够提高 Router 处理 IPv6 Header 的性能。所以 IPv6 Header 采用了 Fixed Header + Extension Header 的灵活组成方式。
Fixed Header 中只包含了最低程度所需的信息,避免出现那些不需要的或者很少使用的信息,如下所示。而另外的高级功能以及扩展功能信息,则则以 Extension Header 的形式被插放到 Fixed Header 和上层 PDU Header 之间。并且每个 Extension Header 都由不同的 Next Header 字段值来标识。
同时,IPv6 Fixed Header 的长度是固定的(320bits),相较于 IPv4 Header 的长度是可变的(IPv4 Options 40Bytes),前者在 Router 种具有更高的处理效率。
Fixed Header 包括了以下字段:
- Version(协议版本):第六版。
- Traffic Class(流量类型):被分为了 2 个部分,前 6bits 为 DSCP(差分服务代码点)域,用于标识 Service Type(服务类型),以便让 Router 知道应该向该 Packet 提供什么服务和优先级。后 2bits 则用于 ECN(显式拥塞通知)协议。
- Flow Label(流标记):用于标识一个 Flow,让 Router 能够识别特定的 Flow Type(流类型),有助于避免数据包的重新排序,是为了流媒体和实时媒体等常见而设计的。IPv6 通过 Traffic Class 和 Flow Label 字段的结合使用,可以支持功能更加强大的 QoS 特性。
- Payload Length(有效负载长度):字长为 16bits,最大可以表示 65535Bytes 的 Payload 长度。另外,当 Extension Header 中设置了 Jumbo Payload 时,此字段值应该被置为 0,此时可以传输超过 65535Bytes 的巨型 Payload。
- Next Header(下一个首部):如果 Extension Header 存在时,用于标识 Extension Header(扩展报头)。如果不存在,则用于标识上层 PDU。
- Hop Limit(跳跃限制):相当于 IPv4 中的 TTL(生存时间)。
- Source Address(源 IPv6 地址)
- Destination Address(目的 IPv6 地址)
扩展头部
IPv4 Header 通过可变长的 Options 字段(40Bytes)来携带扩展信息,而 IPv6 Header 则使用了更加固定的若干个 Extension Headers 来携带。只需要保证 IPv6 Header 的总大小不超过 IPv6 Packet 的总大小即可。拥有了更加强大的扩展能力以及处理效率。
当使用 Extension Header 时,Fixed Header 中的 Next Header 字段指向了下一个 Extension Header,然后再由 Extension Header 中的 Next Header 指向下一个,依此类推,直到最后一个 Extension Header 的 Next Header 指向上层 PDU Header。或者当 Next Header 的值为 59,则表示在此 Header 之后就再没有 Header 了。
根据 RFC 2460 要求 Router 必须支持以下 IPv6 Extension Headers 类型:
并且这些 Extension Headers 的插入顺序应该是:
IPv6 地址格式
IPv6 将地址长度从 IPv4 的 32bits 扩展到 128bits,使得 IPv6 公网地址数量大幅增加,达到了 340,282,366,920,938,463,463,374,607,431,768,211,456(2 ** 128)个 IPv6 地址,就以地球人口 70 亿人计算,每人平均可分得约 4.86×1028(486117667 * 1020)个 IPv6 地址,被戏称为可以给地球上的每一粒沙子分配一个 IPv6 地址。
如下所示,128bits 的 IPv6 地址被分成了 8 段,每段 16bits:
0010000000000001 0000000000000000 0011001000111000 1101111111100001 0000000001100011 0000000000000000 0000000000000000 1111111011111011
通常使用 8 段 4 位十六进制数(共 32 位)表示,不同段之间以符号 :
分隔:
2001:0db8:3c4d:0015:0000:0000:1a2f:1a2b
从上面的地址示例可以看出,即便使用了十六进制格式,但 Pv6 的地址仍然很长。所以 IPv6 还提供了一些缩短地址规则:
- 规则 1:丢弃前导零,高位的连 0 可省略不写,而低位的 0 不可省略,上述地址可简化记为 2001:db8:3c4d:15:0:0:1a2f:1a2b。
- 规则 2:连续多段全 0 可用符号
::
替代且仅替代一次(只能出现一次),上述地址可进一步简化记为 2001:db8:3c4d:15::1a2f:1a2b。
此外,还 IPv6 还支持不那么常见的点分十六进制格式,例如:2001:0db8:85a3:08d3:1319:8a2e:0370:7344 可以记为 2.0.0.1.0.d.b.8.8.5.a.3.0.8.d.3.1.3.1.9.8.a.2.e.0.3.7.0.7.3.4.4,其倒序写法用于在 ip6.arpa 子域名中记录 IPv6 地址与 Domain 之间的映射关系。
IPv6 网络的基本组成元素
对于全球 IPv6 网络而言,其采用了分层分域寻址结构设计,IP 寻址范围由大到小依次为:
- Global 寻址:在全球范围进行路由寻址,定位到具体的 Site。每个 Site 都具有一个全球唯一的 Global Routing Prefix(Site Prefix),由 ISP 或 RIR(Regional Internet Registry,区域 Internet 注册机构)统一分配。
- Site 寻址:在单一 Site 内进行路由寻址,定位到具体的 Subnet。每个 Subnet 都具有本地唯一的 ID。
- Subnet 寻址:在 Site 内的子网的 Link-Local 中进行路由寻址,最终定位到目的主机的网卡接口。
- Host Interface 目标:类似于 IPv4 的主机号,而 IPv6 可以使用的是 MAC 地址进行唯一标识。
如下图,描述了一个最基本的 IPv6 企业网络的基本组成元素,包括:
- Node(节点):具有 IPv6 地址的一个节点,通常是 Router 或 Host。其中 Router Node 又分为 Router 和 Edge Router,后者注册了 Site 的 Global Routing Prefix,并接入到 ISP PoP 点,继而访问 Internet。
- Adjacent Nodes(邻居节点):处于同一个 Link-Local 的若干个 Router Nodes,它们互为邻居。
- Link(链路):由 Router Node 包围起来的一条 Link-Local,用于构成一个 Subnet,包括:Ethernet Link、PPP Link 等。
- Subnet(子网):不同的 IPv6 Subnets 之间同样需要通过 Router 完成 L3 路由。并且,IPv6 还支持 Multi-Links Subnet 类型,能够承载更大的规模,如上图中的子网 8a。
- Site(站点):由多个 Subnets 构成了一个 Site。
IPv6 的地址分类和寻址模式
单播地址
在单播路由寻址场景中,使用到的是单播地址(Unicast),用于定位到一个 Host Interface。同时为了支撑 IP 网络的分层分域架构设计,单播地址也被进一步区分为了 “全球路由地址” 和 “本地路由地址“ 这 2 大类型:
-
全球路由地址:
- 全球唯一地址(Global Unique Address):公网地址,全球可达。
-
本地路由地址:
- 唯一本地地址(Unique Local Unicast Address):私网地址,同 Subnet 可达。
- 链路本地地址(Link-Local Address):基于邻居发现协议的自动配置地址,同一个 Link 上的所有 Hosts 可达,不需要手动配置。
不同的单播地址类型由 IPv6 地址中最左边的连续位(其中可能包含了 Prefix)来确定:
单播地址的作用域,从大到小:
全球唯一地址(Global Unique Address)
全球唯一地址(Global Unique Address),是 IPv6 的公网地址,由 IANA(Internet 地址授权委员会)统一分配给 RIR(地区 Internet 注册机构),再由 RIR 分配给 ISP(Internet 服务提供商),最终再出售给终端用户。
如下图所示,Global Unique Address 由 4 部分组成:
- 地址类型标识:前 3 位固定为 001。
- Global Routing Prefix:用于唯一标识 1 个 Site。
- Subnet ID:用于唯一标识 Site 中的一个 Subnet。默认长度为 16bits,支持在一个 Site 中划分出 65535 个 Subnets。在特殊的场景中,还可以从 Interface ID 借位。
- Interface ID:用于唯一标识 Subnet 中的一个 Interface。
在 CIDR 场景中,NETMASK 所划分的网络号和主机号分别是:
- 网络号:Routing Prefix + Subnet ID
- 主机号:Interface ID
例如下图中:2001:BCFF:FEA6::/48 表示一个 IPv6 路由前缀,2001:BCFF:FEA6:6C01::/64 表示一个 IPv6 子网前缀(网络号)。
值得注意的是 Interface ID 处理支持手动生成之外,还支持使用 NDP(Neighbor Discovery Protocol,邻居发现协议)基于 Interface 的 MAC 地址自动生成,称之为 MAC-to-EUI64 转换法。由于 MAC 地址是在全球唯一的,所以 Interface ID 利用了 MAC 地址的唯一性。
- 将 48bits 的 IEEE 802 MAC 地址平分为 2 个部分,然后在中间插入 16bits 的 0xFFFE。
- 把 OUI 中第 7 位的 U/L (全局/本地)位设置为 1,这样就转换为一个 64bits 的 Interface ID。
唯一本地地址(Unique Local Unicast Address)
虽然 IPv6 地址非常充足,但是 IANA 还是分配了一段可以在企业的私有网络中使用的私有 IP 地址空间,叫做唯一本地地址(Unique Local Unicast Address),等同于 IPv4 的 192、172、10 等私有网络地址,只能在私有网络中进行单播路由寻址,不能全球路由,且不同的私网可以复用此类地址。
Unique Local Unicast Address 由以下部分组成:
- 类型表示:前 8 位固定为 11111101。
- Global ID:为 40 位的伪随机数,以减少地址重叠碰撞风险。
- Subnet ID:同上。
- Interface ID:同上。
链路本地地址(Link-Local Address)
前面介绍了单播场景中常规的公网 IP 地址和私网 IP 地址。而链路本地地址(Link-Local Address)则是 IPv4 中没有的,是 IPv6 中专门为了 Link-Local 概念而新定义的地址类型,所以也只在 Link-Local 内有效。其优势就是即使在同一个 Link 中没有 Router,单 Link 中的 Host Interfaces 依旧可以通信。
当一个 Interface 设备被使能时,IPv6 协议栈会为该 Interface 自动配置一个 IPv6 地址,随后该 Interface 就可以和 Link-Local 内的其他 Interfaces 进行通信了,并且 dstIP 为 Link-Local Address 类型的 IPv6 Packets 不会被 Routing 到其他的 Links 上。
Link-Local Address 由以下部分组成:
- 地址类型:前 10 位固定是 1111111010。
- 填充位:54 位固定为 0。
- Interface ID:同上。
也就是说,Link-Local Address 的 Prefix 固定为 FE80::/10,它全靠 Interface ID 的唯一性来进行定义,所以 Link-Local Address 不支持手动配置方式,只能从 MAC 地址自动生成。
组播地址
IPv6 中使用组播(Multicast)代替了广播(Broadcast),一个组播地址用于标识一个组播组(Multicast Group),包含了多个 Interfaces。
组播地址的格式如下图所示:前 8 位全是 1 ,后面跟着 4 位标记位,再后面就是 4 位表示地址范围,再后面就是 80 位 0,最后的 32 位作为 Group ID,用于标识不同的组播组。所以,普通的组播地址前缀为 FF00::/8。
4 位 Flags(标记位)中:
- 第 1 位是保留标记位,未使用,使用固定值 0。
- 第 2 位用于汇集点(Rendezvous Point),汇集点是组播的一个概念,叫做 R 位,通常取值为 0。
- 第 3 位表示组播地址是否带了前缀,叫做 P 位。组播地址没前缀,取值为 0。大多数情况是 0 。
- 最后一位是 T 位:值为 0 时表示是已定义的、永久的组播地址;值为 1 时是临时充当一些设备的组播组。因此,各个协议使用的组播组是以 FF0 开头的 IPv6 地址,而自定义的组播组是以 FF1 开头的。
标志位为 0000 表示是永久保留的组播地址,分配给各种技术使用;标志位为0001 表示是用户可使用的临时组播地址。范围段定义了组播地址的范围,其定义如下:
- 0001:本地接口范围。
- 0010:本地链路范围。
- 0011:本地子网范围。
- 0100:本地管理范围。
- 0101:本地站点范围,类似组播的私网地址。
- 1000:组织机构范围。
- 1110:全球范围,类似组播的公网地址。
下面是一些组播指定地址:
- FF02::1,在本地链路范围的所有节点。
- FF02::2,在本地链路范围的所有路由器。
- FF02::5,所有运行 OSPF 路由器。
- FF02::9,所有运行 RIP 的路由器。
- FF02::A,所有运行 EIFRP 的路由器。
- FF05::2,在一个站点范围内的所有路由器。
- 等
另外,4 位 Scop(范围位)定义了组播地址的使用范围。不同取值的范围表如下:
任播地址
上文中提到的单播是一对一通信,组播是一对多通信,广播是一对全体通信,而任意播则是 “一对最近的(代价最小的)” 通信方式。
任意播地址(Anycast Address),又称任意点传送地址。其根据具体的功能需求来进行定义,而不是根据 IPv6 报文格式。所以 IPv6 没有定义任意播的地址空间,而是与单播使用相同的地址空间。这意味着,无法根据单从地址信息来判断是单播地址还是任意播地址。
任意播地址和广播一样,会有一组接收节点的地址列表,但任意播只会发送给距离最近或发送成本最低(根据路由表来判断)的其中一个接收地址,此时和单播一样。当某个接收地址收到数据包并进行回应后,任意播的接收列表中的其他节点就会知道某个节点已经回应了,那么它们就不再加入到后续的传输作业中。
当前,任播地址只能分配给网络中间设备(e.g. 路由器、三层交换机等),不能分配给终端设备(e.g. 手机、电脑等),而且不能作为发送端的地址。
可见,一个任意播地址可以分配给多个 Interfaces,在 Router 中也会存在对应的多条 Routes 可以到达相同的目的地,在 Routing 时,则会选择代价最小的 Route 进行数据转发。使得在大型网络中,流量可以发送到最近的设备,数据传输效率更高。而且当最近的设备故障时,Router 可以把 Route 指向下一台最近的 Router。
特殊的地址
-
未指定地址:::/128,即 0:0:0:0:0:0:0:0。只能作为尚未获得正式地址的 Host 的源地址,不能作为目的地址,不能分配给真实的 Interface。
-
环回地址:::1/128,相当于 IPv4 中的回环地址 lo 127.0.0.1。
-
路由协议的保留组播地址:
-
保留路由器的多播地址:这些地址帮助路由器和主机与段上的可用路由器和主机通信,而无需配置 IPv6 地址。主机使用基于 EUI-64 的自动配置 IPv6 地址,然后通过这些地址与段上的可用主机/路由器通信。
-
ORCHID(Overlay Routable Cryptographic Hash Identifiers):2001:10::/28,这些是不可送达的 IPv6 地址,用于加密散列识别。
-
示例地址:2001:db8::/32,这些地址应用于 IPv6 地址的示例中,或用于描述网络架构,作为描述性地址。
-
IPv4 转译地址:IPv4 位址可以很容易的转化为 IPv6 格式。举例来说,如果 IPv4 的一个地址为 135.75.43.52(十六进制为 0x874B2B34),它可以被转化为 0000:0000:0000:0000:0000:FFFF:874B:2B34 或者 ::FFFF:874B:2B34。同时,还可以使用混合符号(IPv4-compatible address),则地址可以为 ::ffff:135.75.43.52。
- ::A.B.C.D,兼容 IPv4 的 IPv6 地址。其中 A.B.C.D 代表 IPv4 地址。即后 32 位可以用 10 进制数表示,因此 ::ffff:192.168.89.9 相等于 ::ffff:c0a8:5909,自动将 IPv6 包以隧道方式在 IPv4 网络中传送的 IPv4/IPv6 节点将使用这些地址。
- ::FFFF:A.B.C.D,是 IPv4 映射过来的 IPv6 地址,其中代表 IPv4 地址,e.g. ::ffff:202.120.2.30 ,它是在不支持 IPv6 的网上用于表示 IPv4 节点。
- 2001::/16,全球可聚合地址,用于 Teredo 隧道,由 IANA 按地域和 ISP 进行分配,是最常用的 IPv6 地址,属于单播地址。
- 2002::/16,6 to 4 地址,用于 6 to 4 自动构造隧道技术的地址,属于单播地址。
IPv6 地址的配置方式
IPv4 地址的配置方式主要有 2 种:
- 手动配置
- 基于 DHCP 协议的自动配置
IPv6 则支持 4 种地址配置方式:
- 手动配置
- 基于 DHCPv6 协议的自动配置
- 基于 NDP 协议的自动配置
- 基于 DHCPv6 和 NDP 协议混合部署的自动配置。
下文中主要讨论了最常见的 NDP 协议的自动配置原理。
NDP 协议
IPv4 网络中,主机之间的通信需要 IP 和 ARP 协议协同完成,主机通过 ARP 广播得知 IPv4 地址所对应的主机网卡的 MAC 地址,进而在子网中进行数据报文的传送。而在 IPv6 网络中,为了避免大规模组网场景中的广播流量,所以废弃了 ARP 协议,取而代之的就是 NDP(Neighbor Discovery Protocol,邻居发现协议)协议。
NDP 协议基于 ICMPv6(Internet Control Message Protocol Version 6,网络控制消息协议第六版)实现,属于纯粹的 L3 协议。NDP 在 L3 层实现所带来的优点是:
- 可利用 L3 安全特性;
- 可对不同介质的 L2 使用同一种地址解析协议;
- 可使用组播替代广播,减轻 L2 网络压力。
具体而言,运行了 NDP 协议的 Node 会在 IPv6 Link-Local 范围中自动完成以下关键动作:
- 邻居发现(Adjacent Discovery):Node 自动确定 Adjacent Nodes 的 Link-Local Addresses,继而实现 Link-Local 通信。
- 邻居不可达检测(Neighbor Unreachability Detection):Node 自动检测 Adjacent Nodes 何时不可达。
- 邻居状态跟踪:Node 自动跟踪 Adjacent Nodes 的健康状态。
- 前缀发现(Prefix Discovery):Node 自动确定 Link 上的 Subnet Prefix。
- 地址自动配置(Address Auto Configuration):Node 自动确定自己的 IPv6 地址。
- 重复地址检测(Duplicate Address Detection):Node 自动确定其想使用的 IPv6 地址是否尚未被使用。
- 地址解析(Address Resolution):Node 不需要通过 ARP 也能够获取 Link 上的 Adjacent Nodes 的 MAC 地址。
- 路由器发现(Router Discovery):Node 自动确定 Link 上的 Gateway,继而实现 Inter-Subnets 通信。
- 参数发现(Parameter Discovery):Node 自动确定 Link 上的 Gateway 的 L3 MTU、NH Limit 等参数。
- 确定下一跳(Next-Hop Determination):Node 自动确定到达目的节点的下一跳。
- 路由重定向(Redirect):Router 能够通知 Node 到达目的节点的更好的(优选)下一跳。
可见,NDP 协议具有非常强大的功能,所以又被称为 SLAAC(Stateless Auto Address Configuration,无状态自动地址配置)协议。其不依赖 DHCPv6 服务器、不需要手动配置,使得用户完全不需要关心具体的 IPv6 地址,只需要关心网络的连通性。
NDP 协议的消息类型
NDP 定义了 5 种 ICMPv6 Msg,并通过组播的方式在 Adjacent Nodes 之间传播。
-
NS Msg(Neighbor Solicitation,邻居请求):Node 在配置了 IPv6 地址之后,就会向该 IPv6 地址的 FF02 :: 1/16(组播地址)发送 NS Msg,以此来确定没有 IPv6 地址冲突。
-
NA Msg(Neighbor Advertisement,邻居通告):Node 在配置了 IPv6 地址并启动 Interface 之后,就会向该 IPv6 地址的 FF02 :: 1/16(组播地址)发送 NA Msg,通告其对该 IPv6 地址的占用。
-
RS Msg(Router Solicitation,路由器请求):Node 在 Subnet 中通过 FF02 :: 1/16(组播地址)发送 RS Msg,以了解该 Subnet 上所有存在的所有 Router Nodes。并帮助 Node 将 Router 配置为 Default Gateway。当 Default Gateway 下线时,Node 会切换到新的 Router。
-
RA Msg(Router Advertisement,路由器通告):当 Router Node 接收到 RS Msg 后,它回应 Node RA Msg,通告它在该 Subnet 中的存在。
-
Redirect Msg(重定向):Router Node 收到了 Node 发出的 RS Msg,但它知道自己并不是该 Node 的最佳网关。这种情况下,Router 就回应一个 Redirect Msg。
NDP 协议的地址自动配置流程
1、路由器发现
Host 启动后就会每个 Interface 创建 Link-Local Address,并检验其在 Link 上是否唯一,该操作与 Router 无关。在 Host 接入到了 Link 后,会在合适的时机主动发出一个 RS Msg 组播,用来发现 Router 及其配置参数。Router 收到 RS Msg 后进行回应:
- 如果 RS Msg 的 srcIP 是 Link-Local Address,那么 Router 回应 RA Msg 单播。
- 如果 RS Msg 的 srcIP 是未指定地址(e.g. ::),那么 Router 回应 RA Msg 组播。
Router 被动相应的 RA 称为 Solicited RA,此外,Router 还会在 Link 上周期性发出 RA Msg 组播,称为 Unsolicited RA。默认周期为 200s。
RA Msg 中包含了所有必要的 Router 配置参数,包括:Link-Local Address、Prefix、MTU、Hop Limit、Routes、Router Life Time(路由器生存期)、ReachableTime(可达性确认时间)和 RetrainsTime(NS 重发时间间隔)等。Router 还会告诉 Host 应该使用 NDP 还是 DHCPv6 来获得 Global Unique Address(全球唯一地址),以及如果使用 NDP,那么上述其他信息是否通过 DHCPv6 获得等等。
Host 收到 RA Msg 后,就把 Router Link-Local Address 作为自己的 Default Gateway,并添加到 Route Table 中。如果存在多条 Defaults,则需要额外的选择操作,或者按照列表依次轮询。
另外,为了避免造成网络拥塞,Host 不会在接入 Link 后就立即发送 RS Msg 组播,而是会延迟一段随机的时间后再发送。这是为了避免在大面积故障恢复后(如停电结束),Link 不会同时涌入大量的 RS Msg。同理,Router 发送 Unsolicited RA 的周期性也并不完全固定。
2、自动生成 Global Unique Address
Host 从 RA Msg 中获取到当前 Subnet 的 Prefix 之后,通过结合自身的 Interface ID 就可以自动生成 Global Unique Address 了。由于 Global Unique Address 是一个单播地址,所以 Host 在落实之前还需要先进行重复地址检测,再将这个地址配置到 Interface 上。
此后 Host 就可以使用 Link-Local Address 进行 Inner-Subnet 通信,并使用 Global Unique Address 进行 Inter-Subnets 通信了。
3、重复地址检测
NDP 在自动完成 Global Unique Address 的重复地址检测时,Host 应将其标记为 Tentative(临时)状态,重复地址检测通过后再标记为 Valid(合法)状态。
如果 Host 正在请求某个 IP(Tentative 状态),同时收到了其他 Hosts 对同一 IP 的 NS 请求,或已使用同一 IP 的 NA 通告,那么 Host 应放弃这个 IP。继而转为手工配置方式。
4、MAC 地址解析
当 Host 如果想与同一 Link 上的其他 Node 通信,则首先需要获得对方的 Link-Local Address,然后进行地址解析获得对应的 L2 MAC 地址。
MAC 地址解析的过程和重复地址检测过程类似,区别在于 NS 报文中询问的 dstIP 是对方的地址,而不是自己的地址。收到 NS 报文的 Node 会查看 NS Msg 的 dstIP,如果是自己,则回应 NA Msg 并通告自己的 L2 MAC 地址。
通过 NS 和 NA Msg 的交互,通信双方都得到了对应的 IPv6-MAC 映射记录,并存储在邻居缓存表中。同时会记录邻居的状态,包括:Empty、Incomplete、Reachable、Stale、Delay 和 Probe。
另外,如果目的节点是 Link-Local 之外的节点,那么 Host 就需要先通过 RA Msg 来获取到 Router 的 MAC 地址。
IPv4v6 综合组网方案
对于大多数企业而言,都会以循序渐进的方式来引入 IPv6。在 IPv6 和 IPv4 共存的情况下,实现 IPv4v6 互联互通的综合组网方案主要有 3 种思路:
- 双栈策略
- 隧道策略
- IPv4/IPv6 报头转换策略
双栈策略
双栈策略(Dual IP Stack Implementation)将 IPv6 视为 IPv4 的一种延伸,以共享代码或平台的方式去实现网络堆栈。
双栈策略下的网元同时支持 IPv4 和 IPv6 两个协议栈:
- 对于 Host 来说,双栈是指其可以根据需要来对业务产生的数据进行 IPv4 封装或者 IPv6 封装;
- 对于 Router 来讲,双栈是指在同一个设备中同时维护 IPv6 和 IPv4 两套路由协议栈,分别支持独立的 IPv6 和 IPv4 路由协议,维护不同的路由表。
隧道策略
所谓 “隧道” 就是利用一种协议来传输另一种协议的数据技术。这些隧道端点通常都是 IPv4v6 双栈的节点。
- 在隧道入口以一种协议的形式来对另外一种协议数据进行封装,并发送。通常要维护一些与隧道相关的信息,例如:记录隧道 MTU 等参数。
- 在隧道出口对接收到的协议数据解封装,并做相应的处理。通常出于安全性的考虑要对封装的数据进行过滤,以防止来自外部的恶意攻击。
隧道的配置方法分为手工配置隧道和自动配置隧道,而自动配置隧道又可以分为兼容地址自动隧道、 6to4、6over4、ISATAP、MPLS、GRE 等隧道类型。
值得注意的是,隧道策略实际并不完美,可能会增加延时以及引起路径最大传输单元发现(Path MTU Discovery)的问题。并且老旧的网络设备可能并不支持 IPv6。
Linux 中的 IPv6 实践
开启/关闭 IPv6 支持
- 内核参数
$ cat /etc/sysctl.conf
# 0:开启;
# 1:禁用。
net.ipv6.conf.all.autoconf=1
net.ipv6.conf.all.accept_ra=1
net.ipv6.conf.all.forwarding=0
net.ipv6.conf.default.autoconf=1
net.ipv6.conf.default.accept_ra=1
net.ipv6.conf.default.forwarding=0
net.ipv6.conf.eth0.autoconf=1
net.ipv6.conf.eth0.accept_ra=1
net.ipv6.conf.eth0.forwarding=0
net.ipv6.conf.lo.disable_ipv6=0
# 立即生效
$ sysctl -p
# 检查 IPv6 是否开启
$ sysctl -a | grep ipv6 | grep disable
$ ip -6 addr | grep inet6
如果想彻底禁用 IPv6,可以在 GRUB 里添加 ipv6.disable=1,然后重启操作系统。
自动配置 Link-Local Address
- /etc/sysconfig/network
NETWORKING_IPV6=yes
- /etc/sysconfig/network-scripts/ifcfg-ethX
IPV6INIT=yes
- 重启网络
$ systemctl restart network
- 检查:系统会自动为 interface 分配一个 fe80: 开头的 Link-Local Address。
手动配置 Local Unique Address
- /etc/sysconfig/network
NETWORKING_IPV6=yes
- /etc/sysconfig/network-scripts/ifcfg-eth0
DEVICE="ens6"
BOOTPROTO="static"
ONBOOT="yes"
TYPE="Ethernet"
# v4
DEFROUTE=yes
IPV4_FAILURE_FATAL=no
IPADDR=192.168.1.1
NETWORK=255.255.255.0
GATEWAY=192.168.1.2
DNS1=114.114.114.114
# v6
IPV6_DEFROUTE=yes
IPV6_FAILURE_FATAL=no
IPV6INIT=yes
IPV6_AUTOCONF=no
IPV6ADDR=fc00::1/8
IPV6_DEFAULTGW=fc00::2
# 多 IPv6 地址
IPV6ADDR_SECONDARIES="fc00::3/8 \
fc00::4/8"
- 重启网络
$ systemctl restart network
- 验证:系统不仅会自动分配一个 fe80: 开头的 Link-Local Address,还有一个手动配置的 Local Unique Address。
DHCPv6 自动配置 Local Unique Address
- /etc/sysconfig/network-scripts/ifcfg-eth0
BOOTPROTO=dhcp
DEVICE=eth0
IPV6INIT=yes
IPV6_AUTOCONF=yes
DHCPV6C=yes
ONBOOT=yes
TYPE=Ethernet
USERCTL=no
# 支持 dhclient 立即(nowait)变为 Daemon,而不是等待直到获取一个 IPv6 地址。
DHCPV6C_OPTIONS=-nw
NOTE:
- 如果要配置 DHCPv6 stateless 模式,只需要将上面配置文件中的 DHCPV6C_OPTIONS 设置为 “-S”,指示 dhclient 只获取 IPv6 地址之外的其他信息。
- 如果要配置 SLAAC 模式,只需要将上面配置文件中的 DHCPV6C 设置为 “no”,表示关闭 DHCPv6 client。
配置临时 IPv6 地址
- 配置临时 IPv6 地址
$ ifconfig eth1 inet6 add 2409:801e:5008:5110::179/124
$ ip -6 a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 state UNKNOWN qlen 1000
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 state UP qlen 1000
inet6 fe80::f816:3eff:fe1b:ec2e/64 scope link
valid_lft forever preferred_lft forever
3: eth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 state UP qlen 1000
inet6 fe80::f816:3eff:fedf:73a2/64 scope link
valid_lft forever preferred_lft forever
$ route -A inet6 add default gw 2409:801e:5008:5110::177 dev eth1
$ ip -6 r
2409:801e:5008:5110::170/124 dev eth1 proto kernel metric 256 pref medium
fe80::/64 dev eth0 proto kernel metric 256 pref medium
fe80::/64 dev eth1 proto kernel metric 256 pref medium
default via 2409:801e:5008:5110::177 dev eth1 metric 1 pref medium
$ ping6 2409:801e:5008:5110::177
添加 IPv6 默认路由网关
- 查看 IPv6 路由表
$ route -A inet6
- 添加默认网关
$ route -A inet6 add ::/0 gw 2001:da8:203:ec7::1
常用命令
查询自己是否拥有公网 IPv6 地址,访问:https://test-ipv6.com/
# 查看本机 IPv6 地址
$ ip -6 addr
# 查看 IPv6 路由
$ ip -6 route
# 查看 IPv6 组播地址
$ ip -6 maddr
# 查 DNS AAAA记录(走 IPv6 线路的最纯粹、最完整、最靠谱方法)
$ dig @2620:0:ccc::2 -t AAAA -6 ipv6.baidu.com +trace
# ping IPv6
$ ping -6 2400:da00:2::29
# curl IPv6
$ curl -6 http://[2400:da00:2::29]/
# traceroute
$ traceroute -6 ipv6.baidu.com
# mtr
$ mtr -6 ipv6.baidu.com
# 邻居地址解析
$ ndisc6 -n 2002::102 eth0
# iptables v6 查看
$ ip6tables-save
# tcpdump
$ tcpdump -nnn -i eth0 ip6
IPv4 与 IPv6 的比较总结
描述 | IPv4 | IPv6 |
---|---|---|
地址 | 长度为 32 位(4 个字节)。地址由网络和主机部分组成,这取决于地址类。根据地址的前几位,可定义各种地址类:A、B、C、D 或 E。IPv4 地址的总数为 4 294 967 296。IPv4 地址的文本格式为 nnn.nnn.nnn.nnn,其中 0<=nnn<=255,而每个 n 都是十进制数。可省略前导零。最大打印字符数为 15 个,不计掩码。 | 长度为 128 位(16 个字节)。基本体系结构的网络数字为 64 位,主机数字为 64 位。通常,IPv6 地址(或其部分)的主机部分将派生自 MAC 地址或其他接口标识。根据子网前缀,IPv6 的体系结构比 IPv4 的体系结构更复杂。IPv6 地址的数目比 IPv4 地址的数目大 1028(79 228 162 514 264 337 593 543 950 336)倍。IPv6 地址的文本格式为 xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx,其中每个 x 都是十六进制数,表示 4 位。可省略前导零。可在地址的文本格式中使用一次双冒号(::),用于指定任意数目的 0 位。例如,::ffff:10.120.78.40 表示 IPv4 映射的 IPv6 地址。 |
地址分配 | 最初,按网络类分配地址。随着地址空间的消耗,使用“无类域间路由”(CIDR)进行更小的分配。没有在机构和国家或地区之间平均分配地址。 | 分配尚处于早期阶段。“因特网工程任务组织”(IETF )和“因特网体系结构委员会”(IAB)建议基本上为每个组织、家庭或实体分配一个 /48 子网前缀长度。它将保留 16 位供组织进行子网划分。地址空间是足够大的,可为世界上每个人提供一个其自己的 /48 子网前缀长度。 |
地址掩码 | 用于从主机部分指定网络。 | 未使用 |
地址前缀 | 有时用于从主机部分指定网络。有时根据地址的表示格式写为 /nn 后缀。 | 用于指定地址的子网前缀。按照打印格式写为 /nnn(最多 3 位十进制数字,0 <= nnn <= 128)后缀。例如 fe80::982:2a5c/10,其中前 10 位组成子网前缀。 |
地址类型 | IPv4 地址分为三种基本类型:单点广播地址、多点广播地址和广播地址。 | IPv6 地址分为三种基本类型:单点广播地址、多点广播地址和任意广播地址。 |
专用地址和公用地址 | 除由 IETF RFC 1918 指定为专用的三个地址范围 10.X.X.X (10/8)、172.16.0.0 至 172.31.255.255 (172.16/12) 和 192.168.X.X (192.168/16) 之外,所有 IPv4 地址都是公用的。专用地址域通常在组织内部使用。专用地址不能通过因特网路由。 | IPv6 有类似的概念,但还有重要差别。地址是公用或临时的,先前称为匿名地址。 请参阅 RFC 3041。与 IPv4 专用地址不同,临时地址可进行全局路由。动机也不一样:IPv6 临时地址要在它开始通信时屏蔽其客户机的身份(涉及隐私)。临时地址的生存期有限,且不包含是链路(MAC)地址的接口标识。它们通常与公用地址没有区别。IPv6 具有受限地址作用域的概念,它使用其设计的作用域指定。 |
组播地址 | 224.0.0.0/4 | FF00::/8 |
广播地址 | 255.255.255.255 | 没有广播地址,只有任播地址 |
未指定地址 | 0.0.0.0 | :: |
回路地址 | 127.0.0.1 | ::1 |
ISP 地址 | 公用 IP 地址 | 可汇聚全球单播地址 |
私有地址 | 10.0.0.0/8、172.16.0.0/12、192.168.0.0/16 | FEC0::/48 |
Microsoft 自动专用 IP 寻址自动配置的地址 | 169.254.0.0/16 | FE80::/64 |
表达方式 | 点分十进制 | 冒号十六进制式(取消前置零、零压缩) |
子网掩码表示 | 以点阵十进制表示法或前缀长度表示法(CIDR) | 仅使用前缀长度表示法(CIDR) |
地址作用域 | 此概念不适用于单点广播地址。有指定的专用地址范围和回送地址。将该范围之外的地址假设为全局地址。 | 在 IPv6 中,地址作用域是该体系结构的一部分。单点广播地址有两个已定义的作用域,包括本地链路和全局链路;而多点广播地址有 14 个作用域。为源和目标选择缺省地址时要考虑作用域。作用域区域是特定网络中作用域的实例。因此,有时必须输入 IPv6 地址或使它与区域标识相关联。语法是 %zid,其中 zid 是一个数字(通常较小)或名称。区域标识写在地址之后前缀之前。 例如,2ba::1:2:14e:9a9b:c%3/48。 |
地址解析协议(ARP) | IPv4 使用 ARP 来查找与 IPv4 地址相关联的物理地址(如 MAC 或链路地址)。 | IPv6 使用因特网控制报文协议版本 6(ICMPv6)将这些功能嵌入到 IP 自身作为无状态自动配置和邻节点发现算法的一部分。因此,不存在类似于 ARP6 之类的东西。 |
地址生存期 | 通常,除使用 DHCP 分配的地址之外,此概念不适用于 IPv4 地址。 | IPv6 地址有两个生存期:首选生存期和有效生存期,而首选的生存期总是小于等于有效的生存期。首选生存期到期后,如果有同样好的首选地址可用,那么该地址便不再用作新连接的源 IP 地址。 有效生存期到期后,该地址不再用作入局信息包的有效目标 IP 地址或源 IP 地址。根据定义,某些 IPv6 地址有无限多个首选生存期和有效生存期,如本地链路。 |
IP 报头 | 根据提供的 IP 选项,有 20-60 个字节的可变长度。 | 40 个字节的固定长度。没有 IP 报头选项。通常,IPv6 报头比 IPv4 报头简单。 |
IP 报头选项 | IP 报头(在任何传输报头之前)可能附带各种选项。 | IPv6 报头没有选项。而 IPv6 添加了附加(可选)的扩展报头。扩展报头包括 AH 和 ESP(和 IPv4 的一样)、逐跳扩展、路由、分段和目标。目前,IPv6 支持一些扩展报头。 |
IP 报头协议字节 | 传输层或信息包有效负载的协议代码,例如,ICMP。 | 报头类型紧跟在 IPv6 报头后面。使用与 IPv4 协议字段相同的值。此结构的作用是允许以后的报头使用当前定义的范围并且易于扩展。下一个报头将是传输报头、扩展报头或 ICMPv6。 |
IP 报头“服务类型”字节 | 由 QoS 和差别服务用来指定通信类。 | 但使用不同的代码来指定 IPv6 流量类。目前,IPv6 不支持 TOS。 |
片段 | 如果一个信息包对于要传送它的下一链路来说太大,那么可由发送方(主机或路由器)对其分段。 | 对于 IPv6,只能在源节点进行分段,且只能在目标节点完成重新装配。使用分段扩展报头。 |
LAN 连接 | LAN 连接由 IP 接口用来到达物理网络。存在许多类型,例如,令牌环和以太网。有时,它称为物理接口、链路或线路。 | IPv6 可与任何以太网适配器配合使用并且可通过虚拟以太网在逻辑分区间使用。 |
最大传输单元(MTU) | 链路的最大传输单元是特定链路类型(如以太网或调制解调器)支持的最大字节数。对于 IPv4,最小值一般为 576。 | IPv6 的 MTU 下限为 1280 个字节。也就是说,IPv6 不会在低于此极限时对信息包分段。要通过字节数小于 1280 的 MTU 链路发送 IPv6,链路层必须以透明方式对 IPv6 信息包进行分段及合并。 |
配置 | 新安装的系统必须在进行配置之后才能与其他系统通信;即,必须分配 IP 地址和路由。 | 根据所需的功能,配置是可选的。IPv6 可与任何以太网适配器配合使用并且可通过回送接口运行。IPv6 接口是使用 IPv6 无状态自动配置进行自我配置的。还可手工配置 IPv6 接口。这样,根据网络的类型以及是否存在 IPv6 路由器,系统将能与其他本地和远程的 IPv6 系统通信。 |
重新编号 | 重新编号通过手工重新配置完成,可能存在 DHCP 的例外情况。通常,对于站点或组织,重新编号是应尽可能避免的复杂且烦琐的过程。 | 重新编号是 IPv6 的一个重要结构元素,特别是在 /48 前缀中已很大程度上实现自动化。 |
路由 | 从逻辑上讲,是一组 IP 地址(可能只包含 1 个)的映射,这些 IP 地址映射为物理接口和单个下一中继段 IP 地址。使用该线路将其目标地址定义为该组的一部分的 IP 信息包转发至下一中继段。IPv4 路由与 IPv4 接口关联,因此,它是一个 IPv4 地址。缺省路由为 *DFTROUTE。 | 从概念上讲,与 IPv4 类似。一个重要差别是:IPv6 路由与物理接口(链路,如 ETH03)而不是接口相关联(绑定)。路由与物理接口相关联的一个原因是 IPv6 与 IPv4 的源地址选择功能不同。 |
传输层 | TCP、UDP 和 RAW。 | IPv6 中存在相同的传输。 |
未指定地址 | 顾名思义,未定义的地址。套接字编程将 0.0.0.0 用作 INADDR_ANY。 | 定义为 ::/128(128 个 0 位)。 它在某些邻节点发现信息包和各种其他的上下文(如套接字)中用作源 IP。套接字编程将 ::/128 用作 in6addr_any。 |
虚拟专用网络(VPN) | 虚拟专用网络(使用 IPsec)允许在现有的公用网络上扩展安全的专用网络。 | 同样支持 IPv6。 |
因特网控制报文协议(ICMP) | 由 IPv4 用来进行网络信息通信。 | 因特网控制报文协议版本 6(ICMPv6)提供一些新的属性。保留了基本错误类型,如目标不可到达、回传请求和应答。 添加了新的类型和代码以支持邻节点发现和相关的功能。 |
因特网组管理协议(IGMP) | IGMP 由 IPv4 路由器用来查找需要特定多点广播组通信的主机,并由 IPv4 主机用来向 IPv4 路由器通告(主机上)现有的多点广播组侦听器。 | IGMP 在 IPv6 中由 MLD(多播侦听器发现)协议取代。MLD 执行 IGMP 对 IPv4 所执行的必要操作,但通过添加一些特定于 MLD 的 ICMPv6 类型值来使用 ICMPv6。 |
第 2 层隧道协议(L2TP) | 可将 L2TP 看作是虚拟 PPP,并通过任何支持的线路类型工作。 | 同样支持 IPv6。 |
回送地址 | 回送地址是地址为 127...*(通常是 127.0.0.1)的接口,只能由节点用来向自身发送信息包。该物理接口(线路描述)被命名为 *LOOPBACK。 | 与 IPv4 的概念相同。单个回送地址为 0000:0000:0000:0000:0000:0000:0000:0001 或 ::1(简短版本)。虚拟物理接口被命名为 *LOOPBACK。 |
点到点协议(PPP) | PPP 支持基于各种调制解调器和线路类型的拨号接口。 | 同样支持 IPv6。 |
端口 | TCP 和 UDP 有独立的端口空间,分别由范围为 1-65535 之间的端口号标识。 | 对于 IPv6,端口的工作与 IPv4 相同。因为它们处于新地址系列,现在有四个独立的端口空间。 例如,有应用程序可绑定的两个 TCP 端口 80 空间,一个在 AF_INET 中,一个在 AF_INET6 中。 |
简单网络管理协议(SNMP) | SNMP 是一个用于系统管理的协议。 | 同样支持 IPv6。 |
开放式最短路径优先协议(OSPF) | OSPF 是在优先于 RIP 的较大型自治系统网络中使用的路由器协议。 | 同样支持 IPv6。 |
路由信息协议(RIP) | RIP 是路由守护程序支持的路由协议。 | 目前,RIP 不支持 IPv6。 |
跟踪路由 | 跟踪路由是进行路径确定的基本 TCP/IP 工具。 | 同样支持 IPv6。 |
通信跟踪 | 通信跟踪是一个收集进入和离开系统的 TCP/IP(及其他)信息包的详细跟踪资料的工具。 | 同样支持 IPv6。 |
Netstat | Netstat 是一个用于查看 TCP/IP 连接、接口或路由状态的工具。在使用 IBM Navigator for i和字符界面时可用。 | 同样支持 IPv6。 |
PING | PING 是测试可达性的基本 TCP/IP 工具。 | 同样支持 IPv6。 |
节点信息查询 | 不存在。 | 一种简易的网络工具,其工作方式应类似于 ping,只是内容不同:IPv6 节点可查询目标 DNS 名称的另一个 IPv6 节点、IPv6 单点广播地址或 IPv4 地址。 目前不受支持。 |
Telnet | Telnet 允许登录并使用远程计算机,就好象直接与其连接一样。 | 同样支持 IPv6。 |
网络地址转换(NAT) | 集成到 TCP/IP 中的基本防火墙功能。 | 目前,NAT 不支持 IPv6。通常,IPv6 不需要 NAT。IPv6 扩展了地址空间,这样就解决了地址短缺问题并使重新编号变得更加容易。 |
源地址选择 | 应用程序可指定源 IP(通常,使用套接字 bind())。如果它绑定至 INADDR_ANY,那么根据路由来选择源 IP。 | 与 IPv4 一样,应用程序可使用 bind() 指定源 IPv6 地址。和 IPv4 类似,它可通过使用 in6addr_any 让系统选择 IPv6 源地址。但是,因为 IPv6 线路有许多 IPv6 地址,所以选择源 IP 的内部方法不同。 |
套接字 API | 应用程序通过使用这些 API 来使用 TCP/IP。不需要 IPv6 的应用程序不受为支持 IPv6 所做的套接字更改的影响。 | IPv6 使用新的地址系列:AF_INET6 增强了套接字以便应用程序现在可使用 IPv6。设计了这些增强以便现有的 IPv4 应用程序完全不受 IPv6 和 API 更改的影响。希望支持并发 IPv4 和 IPv6 通信或纯 IPv6 通信的应用程序可以容易地适应使用 IPv4 映射的 IPv6 地址格式 ::ffff:a.b.c.d,其中 a.b.c.d 是客户机的 IPv4 地址。新的 API 还支持从文本至二进制及从二进制至文本的 IPv6 地址转换。 |