[转载]小慢哥IPv6系列

原文:https://www.zhihu.com/column/fzxiaomange

IPv6系列-入门指南

本文是《IPv6系列》文章的第一篇《入门指南》,用于快速了解并上手IPv6。

小慢哥的原创文章,欢迎转载

一. 为什么要了解IPv6

你以为我会讲些“正确的废话”,比如IPv6地址空间巨大,可以让地球上的每一粒沙子拥有一个IP地址?比如IPv6更加安全?

错!我才不在意这些,这跟我们有什么关系。

我要讲的,是不上IPv6,会有哪些后果。

1️⃣ 势不可挡:各大运营商已经在全面铺设IPv6,包括手机、家庭宽带,比如笔者所在地福州的移动4G手机,已经获得IPv6地址。

2️⃣ 坐以待毙:当IPv6占用率达到一定比例的时候,我相信已有的网站、新申请备案的网站,会被强制要求上IPv6,如果不配置,已有网站停止运营、申请备案不予通过。甚至,到那时,手机、家庭宽带,会仅获得IPv6地址,无法获得IPv4地址。最后,IPv4从中国互联网中废除。

通过上述2点,可以知道,作为服务端(如WEB服务提供方)是必须要上IPv6的,否则不仅无法运营、连用户也都无法访问。

那么,内网需要IPv6吗

▪ 家庭内网,比如连着wifi的手机、电脑

▪ 企业内网,比如办公室内每个工位上的电脑

▪ 数据中心内网,比如机房内的服务器、公有云主机

这些内网环境,是否也需要配置ipv6地址?

答:只要你想访问IPv6互联网,就必须要在终端上配置IPv6地址。原因在于“IPv6优先原则”,越来越多的程序,比如各大编程语言的许多主流模块/框架,在进行域名解析时,会通过dns优先查询AAAA记录(对应IPv4的A记录) ,若该域名有提供IPv6访问,就必然会解析出AAAA记录。接着,就会优先通过IPv6来访问(即使本机没有配置IPv6,甚至没有启用IPv6),如果IPv6网络不通,则该访问直接失败,即便有的模块/框架在失败后会尝试IPv4,但已经增加了许多的延时

综上所述,IPv6已经来临,而不是还在讨论中,现在没有任何理由继续固守IPv4了。与其坐以待毙,不如主动学习


二. 顾虑:IPv6地址太复杂了,记不住啊

说的好像IPv4地址你能背下来似的,其实IPv6地址只是长度增加,并且展示方式从十进制改为十六进制,具体的计算方式是一样的。而且有dns在,没必要去背IP地址,就算是内网的IPv6地址,也可以通过DHCPv6或者路由器发送RA包来自动生成IPv6地址。


三. 顾虑:每台服务器都有IPv6地址,会暴露整个内网,不安全

担心是对的,但解决方案也和IPv4一样,有2种:

▷ 可以在内网服务器上配置“IPv6私网地址”,这样公网就访问不到了。在IPv6中,私网地址是fd00::/8,这相当于IPv4的10.0.0.0/8、172.16.0.0/12、192.168.0.0/16。然后在网关上配置NAT

▷ 依然用“IPv6公网地址”(即全球单播地址),但在网关上配置“有状态防火墙”

无论是哪种方案,最终都实现了“只出不进”,即服务器可以主动访问IPv6公网,但公网无法主动访问进来,保证了内网的安全。


四. 顾虑:IPv6地址有好几种类型,很难区分和记忆

什么全球单播、唯一本地、链路本地,类型太多了吧?其实,常用的IPv6地址,在IPv4中都能一一对应找到。

全球单播:对应IPv4的公网

唯一本地:对应IPv4的私网

链路本地:在IPv4中也有对应,就是169.254.x.x(这在IPv4中也叫链路本地)

至于其他类型的地址,要不然是被废弃的,要不然就是很少用到的,除非工作所需碰到,否则完全不用理会,上面这3种类型已经足够用了。除了这3种,下面这2个特殊地址一定很常见

::1,表示环回地址,对应IPv4中的127.0.0.1

::,表示未指定地址,对应IPv4中的0.0.0.0


五. 需要学哪些知识

▷ 开发、测试、DBA:只需简单了解IPv6即可,也就是本文看明白后基本就够了

▷ 运维人员:除了需要了解IPv6,还需要掌握IPv6通讯的工作原理、防火墙的配置等等,详见《IPv6系列》后续文章

▷ 网工:需要深入了解IPv6,包括IPv6的各类数据包格式、各种架构、多播路由通讯等等


六. IPv6基础知识

关于IPv6的教程,网络上已经有非常多写的很棒的教程了,笔者没有把握能写出更好的,因此《IPv6系列》文章,将把重点放在一些概念、解决方案、很多人没注意到的坑、工作原理等等

IPv6地址长度

▷ IPv4:32 bit

▷ IPv6:128 bit

可以这么记忆,IPv6比IPv4多了一倍的段落,并且每个段落里增加了一倍的长度,所以IPv6比IPv4长了2x2=4倍

IPv6地址组成

▷ IPv4:网络号+主机号/子网掩码,如192.168.1.2/24

▷ IPv6:前缀ID+接口ID/前缀长度,如2001:0000:0000:0000:0011:0000:0000:0010/64

地址简写

▷ IPv4:不支持

▷ IPv6:压缩0

注意:IPv6单个段落内可重复压缩,比如上述可压缩为2001:0:0:0:11:0:0:10/64;若多个段落连续为0,可压缩,但只能压缩一次,比如上述可进一步压缩为2001::11:0:0:10/64,或者2001:0:0:0:11::10/64,通常为前者

检验方法

找一台linux服务器,比如centos7系统,执行ip addr add ${IPv6地址} dev eth0,然后ip addr show dev eth0看一下会如何压缩

IPv6地址分类

注意:表格列出的是比较常见的地址,并非全部地址

另外,除了单播、多播,IPv6相比IPv4新增了一种任播(anycast),任播是属于单播范畴内的,无法单纯从地址识别出任播

术语

▪ 节点:任何运行IPv6的设备

▪ 路由器:转发不是发给自己的IPv6报文的节点

▪ 主机:非路由器的节点

▪ 接口:节点和链路相连的物理或逻辑配件

▪ 链路:由路由器分割的网络接口集合

▪ 邻居:同一链路上的节点

▪ 链路MTU:链路能传输的最大单位,即最大的IPv6报文字节数

▪ 路径MTU:IPv6源端和目的端之间能传输的最大的IPv6报文字节数,通常是路径中所有链路的最小链路MTU


七. IPv6地址生成

▷ IPv4:手工指定、dhcp分配

▷ IPv6:手工指定、dhcp分配、自动生成

在IPv6里,主流方案就是自动生成IP,而不是手工指定或dhcp分配。当然,作为服务端是需要手工指定的,但对于更广阔的客户端来说,基本都是自动生成。这种自动生成的,叫做“无状态”,相对于“无状态”,通过dhcp获取到的固定IP,就叫做“有状态”(dhcp也支持“无状态”,这里不做详解)

除了协议规定的特殊地址,其他可自行分配的地址,都是可以在具体范围内自动生成的,包括链路本地、全球单播、唯一本地。其中全球单播、唯一本地,是在接收到路由器发送的RA包后自动生成,具体生成的是全球单播还是唯一本地,是根据RA包内容中的前缀而定

如何自动生成的

无需关心,只要记住一点,能用即可。因为有多种自动生成的方法,有通过mac地址换算而来,有通过某种算法获得,也可能是完全随机而来,而且有的自动生成的地址还会每隔一段时间自动更换,不同的操作系统实现方法不一样,无法统一

为什么会出现这种无法统一的情况

原因在于IPv6协议一直在发展,新协议推翻老协议,每个实现者(也就是不同的操作系统)的诞生时间不同,所参考的协议就有可能不同,而且有的协议还支持不只一种方式,不同实现者出于不同的考量就会采用不同的方式。怎么办?没办法,要不然不理会,要不然投入精力去研究其不同之处,没有一劳永逸的方法。(这段话不仅适用IPv6地址,还适用其他方面,比如DHCPv6等等)


八. 常用命令

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
# 查看ip
ip -6 addr

# 查看路由
ip -6 route

# 查看多播地址
ip -6 maddr
netstat -gn

# 查dns AAAA记录(走ipv4线路)
dig -t AAAA fzxiaomange.com
nslookup -query=AAAA fzxiaomange.com

# 查dns AAAA记录(走ipv6线路)
dig @2620:0:ccc::2 -6 -t AAAA fzxiaomange.com
nslookup -query=AAAA fzxiaomange.com 2620:0:ccc::2

# 查dns AAAA记录(走ipv6线路的最纯粹、最完整、最靠谱方法)
dig @2620:0:ccc::2 -t AAAA -6 fzxiaomange.com +trace

# curl
curl -6 https://fzxiaomange.com

# ping
ping6 fzxiaomange.com

# trace route
mtr -6 fzxiaomange.com
traceroute6 fzxiaomange.com
tracert6 fzxiaomange.com
tracepath6 fzxiaomange.com

# 邻居地址解析,类似ipv4的arping
ndisc6 -n 2002::102 eth0

# iptables查看
ip6tables-save

# tcpdump
tcpdump -nnn -i eth0 ip6

九. 在线测试工具

公共dns列表

1
https://dns.icoa.cn/ipv6/

查询网站是否提供IPv6

1
2
https://ready.chair6.net/
http://ip6tools.com/#checkWebServer

查询我自己是否拥有公网IPv6地址

1
2
http://www.test-ipv6.com
http://ip6tools.com/#WhatisMyIPv6Address

十. 开启与关闭IPv6

1
2
3
4
5
6
7
8
9
10
11
12
# 检查ipv6是否开启
sysctl -a | grep ipv6 | grep disable # 如果输出的值是一堆0则表示ipv6是开启的
ip -6 addr | grep inet6,如果有看到fe80则表示ipv6是开启的

# 临时禁用ipv6
sysctl -w net.ipv6.conf.all.disable_ipv6=1

# 临时开启ipv6
sysctl -w net.ipv6.conf.all.disable_ipv6=0

# 彻底禁用ipv6
在grub里添加ipv6.disable=1,然后重启操作系统

十一. 在CentOS7上配置静态IPv6地址

1️⃣ 内核参数

1
2
3
4
5
6
7
# /etc/sysctl.conf里增加
net.ipv6.conf.all.disable_ipv6=0
net.ipv6.conf.default.disable_ipv6=0
net.ipv6.conf.lo.disable_ipv6=0

# 立即生效
sysctl -p

2️⃣ /etc/sysconfig/network里增加一行

1
NETWORKING_IPV6=yes

3️⃣ /etc/sysconfig/network-scripts/ifcfg-eth0

1
2
3
4
5
6
DEVICE=eth0
BOOTPROTO=none
ONBOOT=yes
IPV6INIT=yes
IPV6ADDR=2002::102/64
IPV6_DEFAULTGW=2002::1

4️⃣ 重启网络

1
systemctl restart network

十二. 如何让我的网站对外提供IPv6服务

1️⃣ 找你的运营商要IPv6地址

▷ 如果你的服务器是托管在电信机房里,那么就找电信运营商要,通常会给你一个/48或/56的地址段 ▷ 如果你的服务器用的是公有云,比如阿里云、腾讯云,就找他们要,只不过由于IPv6还未全面普及,因此有的地域有提供IPv6,有的没有。另外,提供IPv6的方案也不完全一样,有的是以双栈方式,就是你的云主机里可以直接看到IPv6地址,而有的是负载均衡或者弹性IP方式提供。笔者的网站是放在腾讯云上,用的就是IPv6的L4负载均衡

2️⃣ 接下来,在dns里为自己的网站域名增加AAAA记录。(其实现在很多大厂dns服务器,即NS,还未提供纯IPv6线路的解析,比如笔者的个人网站域名解析商当前不支持ipv6-only,这点会在后续文章里进行详细说明)

3️⃣ 最后一步,测试IPv6,可通过https://ready.chair6.net/进行查询

这里展示下笔者个人网站支持IPv6后的效果

IPv6系列-初学者的10个常见困扰

本文是《IPv6系列》文章的第二篇《常见困扰》,紧接《入门指南》,用于解答IPv6的10个常见困扰。

小慢哥的原创文章,欢迎转载

本文缘由

在笔者的上一篇文章《IPv6系列-入门指南》里,简要阐述了以下内容:

▷ 掌握IPv6的必要性

▷ IPv6的3个常见顾虑

▷ IPv6基础知识

▷ 常用测试方法

而在进一步的实践学习中,会遇到很多的困扰。笔者结合自己以及身边的同行兄弟们遇到的困扰,精心挑选出10个困扰在本文中进行解答。

如果没有阅读过《IPv6系列-入门指南》,敬请劳神垂阅,以便知识的连贯。


困扰1. IPv4和IPv6只有地址格式不同吗

除了地址格式不同,IPv4与IPv6协议栈也不同,他们在逻辑上是完全不同的2个世界

以下实践中经常会遇到的4个不同之处:

基本通讯过程:ND替代ARP、多播替代广播、fe80地址成为标配、ICMP成为通讯核心

IP配置方式:客户端以无状态自动配置IP成为主流,弱化DHCP

DNS域名解析:AAAA记录替代IPv4的A记录、对应用存在优先级问题(优先解析AAAA还是A)

应用层适应性:socket编程中AF_INET仅支持IPv4,AF_INET6仅支持IPv6


困扰2. IPv4到IPv6对应用程序是透明无感知的吗

错,是有感知的,上层应用程序需要进行改造。

举个例子,当访问http://fzxiaomange.com时候,是要优先解析IPv6地址(AAAA)还是IPv4地址(A),因为总得选一条线路来发送请求。现在许多框架会优先选择IPv6。

注意:如果解析出AAAA记录,即使本机没有可路由IPv6地址,也有可能依然尝试通过IPv6进行请求,导致请求失败

还有一个典型的例子,是程序会在应用层里交互底层IP地址,比如FTP主动模式会在应用层里交互IPv4地址,而如果实际可用的是IPv6地址,就可能导致后续连接的异常。

无法做到透明无感知,是导致产生IPv4到IPv6的部分过渡方案的原因之一。


困扰3. 提供WEB服务,需要每台服务器都配置IPv6地址吗

现在有一种言论,说“IPv6地址无限多,每台服务器都可以配一个IP地址,不用做NAT”。

这很容易误导人,具体如何使用IPv6,还得根据场景而定。比如笔者的个人博客http://fzxiaomange.com,由nginx->php->mysql组成,分别位于3台服务器上,那只需要在nginx上配置IPv6地址,并在DNS上添加一条AAAA记录指向L7的IPv6地址即可。完全没必要在php、mysql服务器上配置IPv6地址,而且一旦配置了,就直接暴露内网了。

每个设备都配置IPv6,主要适用于偏客户端以及地址需求量大的场景,诸如物联网设备、手机4G、家庭宽带等。

另外,IPv6有NAT,适用于办公PC、机房服务器等需要访问IPv6网络,而不想被别人主动访问的场景。


困扰4. IPv4和IPv6要配在同一张网卡上吗

都可以,首先需要先了解2个词“单栈”“双栈”

以节点为角度(通用的解释):

▷ 单栈:表示一个IPv6节点,也就是一台服务器,或一部手机,仅有IPv6地址,或仅有IPv4地址,前者叫做“IPv6单栈”“IPv6-Only”,后者叫“IPv4单栈”“IPv4-Only”

▷ 双栈:表示一个IPv6节点,同时拥有IPv6地址和IPv4地址

以网卡为角度

▷ 单栈:表示一张网卡仅有IPv6地址,或仅有IPv4地址,示意图如下

▷ 双栈:表示一张网卡同时拥有IPv6地址和IPv4地址

IPv4和IPv6在逻辑上是两个完全不相交的世界。如果终端处位于同一个物理层,比如同一个VLAN,那么网卡就只能同时配置IPv6地址和IPv4地址;反之,就必须一张网卡配置IPv6,另一张网卡配置IPv4。所以,关键看网络架构是如何设计,各有利弊。比如放同一张网卡上,就可以做到带宽共享,而放不同网卡,可以做到带宽分别限制与计费。


困扰5. 我的网卡有fe80开头的地址,可以用来上公网吗

当网卡启动的时候,会自动生成“链路本地地址”(Link-Local Address),这是一个fe80::/10的单播地址。“链路本地地址”用于IP自动配置邻居发现等。

注意事项

▷ 核心:每张网卡都会存在“链路本地地址”,这是IPv6协议通讯的核心,不应当删掉

▷ 范围:仅在同一个二层范围内进行传播,不会被路由器做转发

▷ 地址:“链路本地地址”的算法不统一,有的操作系统会根据mac地址计算而来(EUI-64),而有的则是随机或其他某种算法计算而来

▷ 服务:“链路本地地址”虽然可以在二层内互通,但主要用于核心通讯以及某些网络高级协议。不适用于上层应用业务之间的通讯。因此不能用来上公网,也不能用于对外提供服务


困扰6. IPv6地址如何配置

公网地址和私网地址

▷ 公网地址:“全球单播地址”(Global Unicast Address,2000::/3)

▷ 私网地址:“唯一本地地址”(Unique-Local Address,fc00::/7)

细心的人可能会发现,为什么这里叫做“全球单播地址”,而“唯一本地地址”却不叫做“唯一本地单播地址”,好吧,其实都是简称,在RFC里是这么定义的:“Global Unicast Addresses”、“Link-Local IPv6 Unicast Addresses”。其实“全球单播地址”是可以叫做“全球地址”的,只是这样显得有点别扭。

自动生成还是固定IP

在IPv6里,任何单播地址都可以自动生成,也可以手工配置固定IP,具体看应用场景:

▷ 客户端:如果我想访问ipv6互联网,而不对外提供服务,那么使用自动生成即可,无需使用固定的ip地址

▷ 服务端:如果需要对外提供服务,那么ip地址就需要固定了,不能使用自动生成

自动配置IP

在ipv6里还分为2种方法:“有状态”与“无状态”

▷ 有状态(Stateful):地址由DHCPv6 Server统一管理,DHCPv6 Client从中获得一个可用的IP地址

▷ 无状态(Stateless,简称SLAAC):路由器发出“路由通告”报文(Router Advertisement,简称RA),报文内包含了IPv6地址的前缀信息。当收到RA包后,就会根据其中前缀信息,自动生成一个或多个IP地址


困扰7. 没有了ARP,如何解析MAC地址

ARP协议是IPv4用于解析目标MAC地址的协议,而在IPv6里,解析地址采用的是邻居发现(Neighbor Discovery Protocol,简称NDP或ND)

ND不是一个具体协议,而是用来描述多个相关功能的协议的抽象集合,所涵盖的所有协议均是基于ICMPv6。其中有2种报文与解析MAC地址有关:

邻居请求报文NS(Neighbor Solicitation):请求解析

邻居通告报文NA(Neighbor Advertisement):响应解析

这与ping是非常类似的:

▷ ping:发送icmp的echo request报文,对端响应icmp的echo reply报文

▷ 地址解析:发送icmp的ns报文,对端响应icmp的na报文


困扰8. IPv6使用多播替代广播,需要做哪些改造

IPv6使用多播替代了广播,多播的特点是不会像广播那样完全泛洪,而是数据包只发送给加入了多播组的机器。

但是,这有个前提,就是交换机要能识别并维护多播组的信息,主流交换机都具备此功能,然而并不都是默认开启的。对于二层交换机来说,需要开启MLDv2 Snooping

顾名思义,就是交换机会识别“MLDv2成员报告”报文从哪个端口发来的,并记录下来,之后当交换机收到多播包后,会先查找其多播地址是否能在缓存里匹配上

▷ 匹配成功:仅会将数据包从相应的端口发出

▷ 匹配失败:就会泛洪,此时和广播毫无差异


困扰9. IPv6真的安全吗

理想很美好,IPv6从设计之初,就进行了大量的安全方面的设计,“完整的”IPv6在安全方面有至少以下3个优势:

▷ 原生支持的端到端加密

▷ 安全的邻居发现(Secure Neighbor Discovery,简称SEND

▷ 更大的地址空间

现实很残酷,只有第3点发挥了作用,更大的地址空间,减少了被非法扫描到的概率。而第1、2点并没真正普及起来,因为协议本身就很复杂、学习难度很大、实现起来也很不容易。因此IETF为了加速IPv6的普及,对安全性不再强制要求。这也导致了IPv6实际上并没有预期中的那么安全,在IPv4里存在的地址欺骗、虚假网关等情况,在IPv6里依然存在。


困扰10. 如何学习IPv6

网上能找到非常多的IPv6教程,其中有很多教程都是通篇讲IPv6地址、IP包格式、ICMP包格式,这很容易让初学者打退堂鼓。笔者虽然不是专业的网工,但愿能抛砖引玉,推荐的学习步骤如下:

1️⃣ IPv6的历史、设计理念

2️⃣ IPv6的地址格式、分类、前缀计算,以及与IPv4的对比

3️⃣ IP地址、网关路由的配置与查看

4️⃣ 服务端实践,尝试给自己的网站增加IPv6

5️⃣ 客户端实践,让自己的PC访问IPv6互联网

6️⃣ 应用层实践,自己写一对C/S程序,能同时支持IPv4与IPv6

7️⃣ IPv6通讯原理,抓包分析每个包,熟悉ND、DHCPv6等

8️⃣ IPv4与IPv6的互访、过渡

9️⃣ IPv6安全

具体领域的IPv6,例如移动IPv6

后续说明

在《IPv6系列》后续文章中,笔者会有选择性地对“困扰10”中提到的部分内容整理成文。为什么是有选择性,因为笔者并非网工出身,没有把握写出更好的文章,不能误人子弟。

IPv6通讯原理-不能忽略的网卡启动过程

本文主题:通过抓包分析,深入观察网卡启动过程的每个步骤,从而逐步掌握通讯原理。

小慢哥的原创文章,欢迎转载

一. 为什么不能忽略网卡启动过程

掌握网络技术,除了看RFC协议外,最直接高效的方法就是“亲眼所见”

其中抓包分析是最为关键的方法,能了解到:

▷ What:对应哪个协议

▷ Why:协议用途

▷ When:协议之间的关联

▷ How:报文地址和内容

网卡启动是网络通讯的第一步,只有夯实基础方能展翅高飞。


二. 实验环境

本文以CentOS 7为实验环境,创建两个network namespace(名字分别为ns1和ns2),并通过veth网卡桥接到同一个linux bridge(名字为br0),来模拟最简单的环境,即两台同二层服务器。

先贴出mac地址:

▷ ns1内的mac:52:54:00:00:00:01

▷ ns2内的mac:52:54:00:00:00:02

实验步骤:

1️⃣ 在ns1里启动网卡,但不抓包查看

2️⃣ 在ns2里启动网卡,同时在br0上进行抓包分析

观察:

▷ ns2会产生哪些包

▷ ns1是否会对ns2进行响应

本文最后会附上实验脚本和抓包文件的下载地址。


三. 网卡启动前/后的样子

网卡启动前的样子

在ns2里启动网卡之前,先对ns2里的网络环境进行查看,命令如下

1
2
3
4
5
6
7
8
9
10
11
# 查看网卡状态
ip netns exec ns2 ip link

# 查看ipv6地址
ip netns exec ns2 ip -6 addr

# 查看ipv6路由
ip netns exec ns2 ip -6 route

# 查看ipv6多播地址
ip netns exec ns2 ip -6 maddr

可以看到此时eth0处于DOWN的状态,接下去,对eth0进行UP。

网卡启动后的样子

1
2
# 启动网卡
ip netns exec ns2 ip link set eth0 up

进入ns2里查看

可以看到,此时网卡已启动,并获得了一个链路本地地址(图中fe80开头的)

抓到了哪些包呢

这些包都是什么意思,如何产生,为何产生,请接着往下看。


四. 结论写在前

网卡启动过程一共有5步,详见示意图(右边的数字,表示对应抓包图中的第几个包):

接下来,将对这5步进行逐步讲解。


Step1. 生成“链路本地地址”

(本步骤尚未产生数据包)

“链路本地地址”是什么

▷ 当网卡启动时会根据某种算法自动生成链路本地地址(Link-Local Address)。

▷ 具体生成的地址,与操作系统有关,有的根据MAC地址换算而来(EUI-64),有的则是随机生成,并不统一。

▷ “链路本地地址”是范围为fe80::/10的单播地址。

▷ “链路本地”顾名思义,只在同一个二层内传播,不会被路由器转发。

“链路本地地址”有什么作用

▷ 地址自动配置

▷ 邻居发现协议

▷ 路由转发(可以作为下一跳地址)


Step2. 生成“被请求节点多播地址”

(本步骤尚未产生数据包)

“被请求节点多播地址”是什么

在IPv6的世界中,每生成一个ip地址(准确说是单播地址),无论什么类型,都会对应生成一个“被请求节点多播地址”(Solicited-Node multicast address)。

组成方式:FF02::1:FF00:0/104 + 单播地址的最后24bit。可以看到,该地址是通过单播地址推导而成,不是随机的。上图中红框里的地址就是“链路本地地址”对应的“被请求节点多播地址”。

为什么需要“被请求节点多播地址”

就4个字:“地址解析”

▷ IPv4中用ARP做地址解析,ARP是基于广播的。

▷ IPv6没有广播,只有多播。既然是多播,就总得有一个多播地址才行,于是应运而生。

“被请求节点多播地址”工作原理

当他人想解析我的MAC地址时,发送一个“地址解析请求包”到这个多播地址,然后属于该多播地址的成员(也就是“我”)就会收到该数据包,最后“我”返回MAC地址给对方。这样就完成了“地址解析”的流程。

“被请求节点”这5个字到底是什么意思

别人请求解析我的地址,那么我就是被请求的节点。我生成“被请求节点多播地址”的目的,就是让别人能够请求到我。


Step3. “多播成员报告”

(对应抓包图中的No. 1/2/4/6)

什么是“多播成员报告”

▷ MLDv2协议(多播控制协议)中的一种报文类型(Membership Report)。

▷ 通俗理解就是对外宣称“我要加入某某多播组”。

▷ 成员报告是单向的,不会收到回应包。

为什么要进行“多播成员报告”

▷ 只要生成多播地址,就要进行成员报告,这是多播的工作机制。

▷ 成员报告的目的是为了减少网络中的多播流量。

要报告的是哪个成员

▷ 要报告的成员不是单播地址,而是多播地址。

▷ 这里指的就是“被请求节点多播地址”。即“我要加入ff02::1:ff00:2多播组”


Step4. “重复地址检测”

(对应抓包图中的No. 3)

什么是“重复地址检测”

▷ 为了防止IP地址冲突,每生成一个单播地址,都会进行一次“重复地址检测”(Duplicate Address Detection,简称DAD)。

▷ 此刻,就是对Step1生成的“链路本地地址”进行检测。

何时进行“重复地址检测”

▷ 在生成单播地址并完成发送一次“MLDv2成员报告”后,就会随机延时一小段时间进行检测。

▷ 在centos7里检测次数可通过内核参数net.ipv6.conf.eth0.dad_transmits进行修改,若设置为0表示不进行检测。

“重复地址检测”的工作原理

▷ 举个例子:我想给我家小狗取名,叫“球球”,但不想和邻居家的小狗重名,于是我大声喊:“球球”。如果没有任何狗狗看过来,那就可以认定此名字没有冲突。

▷ 专业解释:发送一个地址解析包(Neighbor Solicitation,简称NS),请求解析的地址就是自己的地址,并等待回应,若超时仍未得到回应(Neighbor Advertisement,简称NA),即可认为地址可用。


Step5. “无状态地址自动配置”

(对应抓包图中的No. 5/7/8)

什么是“无状态地址自动配置”

在IPv6中,有2种自动配置IP地址的方法:

▷ DHCPv6:也叫做“有状态分配”

▷ SLAAC:“无状态地址自动配置”(Stateless Address Autoconfiguration)

SLAAC的作用是什么

▷ 自动配置IP地址

▷ 自动配置网关

注:这里说的IP地址,是指“全球单播地址”或者“唯一本地地址”,也就是俗称的公网地址和私网地址。而不是“链路本地地址”。

工作原理

涉及到这2种报文:

▷ “路由器请求”(Router Solicitation,简称RS)

▷ “路由器通告”(Router Advertisement,简称RA)

当收到路由器回应的RA报文后,就会根据报文中的IP前缀信息,自动生成IP地址,并将网关指向该路由器的“链路本地地址”。

如何能够收到RA报文呢

有2种办法:

▷ 路由器定期发送RA报文

▷ 自己主动发送RS报文,路由器收到后就会立刻回应RA报文

由于本次实验中没有路由器,因此截图中仅能看到主动发送的RS报文,而没有得到回应。


思考题

1️⃣ 在生成“全球单播地址”或“唯一本地地址”之后,还会采用“链路本地地址”做基础通讯吗?

2️⃣ 为什么“多播成员报告”可以减少网络中不必要的多播流量,接入层交换机要进行额外配置吗?

3️⃣ “地址重复”时,是否会自动更换IP?

4️⃣ RA包只能包含一个IP前缀信息吗?一个前缀只能生成一个IP地址吗?生成的地址是什么样的?

5️⃣ 若存在多台路由器,网关会指向谁?

6️⃣ 如果不想自动配置IP,只想手工配置IP,可以忽视RA包吗?如何忽视?

上述问题,将在《IPv6系列》的下一篇文章中进行解答。


附. 实验脚本与抓包文件

1
2
3
4
5
# 实验脚本
https://fzxiaomange.com/attachment/ipv6-init.sh

# 抓包文件
https://fzxiaomange.com/attachment/ipv6-init.pcap

IPv6系列-详解自动分配IPv6地址

深入研究自动分配IPv6地址的Stateless(无状态)与Stateful(有状态)方式

小慢哥的原创文章,欢迎转载

生成“链路本地地址”,有2种方式

▷ 手动配置

▷ 自动配置

其中“自动配置”根据算法,又分为

▷ eui64:根据mac地址换算而来

▷ stable_secret:跟随网络环境的变化而变化,处于固定网络环境时其值将固定

▷ random:随机生成


二. Global Address的生成方式

生成“全球单播地址”(或者“唯一本地地址”),有2种方式

▷ 手动配置

▷ 自动配置

其中“自动配置”根据获取方式,又分为

▷ 无状态(Stateless):根据路由通告报文RA(Router Advertisement)包含的prefix前缀信息自动配置IPv6地址,组成方式是Prefix + (EUI64 or 随机)。Stateless也可以称为SLAAC(Stateless address autoconfiguration)

▷ 有状态(Stateful):通过DHCPv6方式获得IPv6地址

其中“有状态”又分为2种

▷ 有状态DHCPv6(Stateful DHCPv6):IPv6地址、其他参数(如DNS)均通过DHCPv6获取

▷ 无状态DHCPv6(Stateless DHCPv6):IPv6地址依然通过路由通告RA方式生成,其他参数(如DNS)通过DHCPv6获取

为了避免混淆,在此解释下有状态、无状态到底是什么意思:首先,请明确一点,有状态、无状态仅针对于IPv6地址分配方式,并不包含其他参数

▷ 有状态:可控、可管理。在网络中存在一个IP地址管理者,它能够识别客户端,根据不同的客户端,分配对应的IPv6地址,客户端与服务端之间需要维护IP地址的租期及续约。目前实现这种效果的,就是DHCPv6协议,IP地址管理者就是DHCPv6 Server

▷ 无状态:不可控、难管理。在网络中只有网关,没有IP地址管理者。因此无人去识别客户端,每个客户端根据网关发送的相同的RA报文内容,自行配置IPv6地址


三. RA报文中3个关键的Flag

RA报文中存在3个关键的flag bit:

Autonomous flag(简称A flag):表示是否配置无状态IP。在一个RA报文中,可存在多个prefix,比如2401::/64、2402::/64、2403::/64,每个prefix都可以独立配置A flag

▪ 为on时(对应bit位为1):表示客户端应当在该prefix范围内自动生成IPv6地址(客户端通过DAD自行保证地址可用),并配置子网路由条目、网关

▪ 为off时(对应bit位为0):表示客户端不应当在该prefix范围内自动生成IPv6地址,但是可以配置子网路由条目、网关

Managed flag(简称M flag):表示是否配置有状态IP。M flag是RA报文的全局参数,一个RA报文只有一个M flag

▪ 为on时(对应bit位为1):表示在stateless流程结束后开始stateful流程,也就是告诉客户端可以通过DHCPv6来获得IPv6地址和其他参数(如DNS列表)

▪ 为off时(对应bit位为0):表示不通过DHCPv6来获得IPv6地址。

Other flag(简称O flag):表示是否通过DHCPv6获得除IP以外的其他参数(如DNS列表)。O flag也是RA报文中的全局参数,一个RA报文只有一个O flag。注意:仅当M flag为off时,该参数才会被读取。

▪ 为on时(对应bit位为1):当M flag为on,或者M flag为off且至少有一个A flag为on时,将通过DHCPv6获得其他参数

▪ 为off时(对应bit位为0):当M flag为on时,依然将通过DHCPv6获得其他参数;当M flag也为off时,将不通过DHCPv6获得其他参数


四. 流程示意图

无状态和有状态并不是相互对立的,他们可以同时存在,也就是一张网卡上可以同时出现通过RA生成的IP以及通过DHCPv6获得的IP。通过下面这张笔者绘制的流程图可知晓其中奥秘。

从图中可以看到,顺序为:

1️⃣ Stateless自动配置“链路本地地址”

2️⃣ Stateless自动配置“全球地址”(或“唯一本地地址”)

3️⃣ Stateful自动配置“全球地址”(或“唯一本地地址”)和其他参数,其中Stateful阶段中存在Stateful DHCPv6或Stateless DHCPv6

注意:部分客户端操作系统或网络管理器当Stateless阶段没有收到RA报文后,就到此结束,不会走Stateful阶段,比如CentOS 7、Ubuntu 17的默认逻辑都是这样,而windows server 2012就会继续走Stateful阶段。


五. 测试获得IP效果

测试环境:客户端基于CentOS 7+NetworkManager(即系统默认的网络管理方式)进行测试

▪ 网关会发送RA报文,包含一个prefix

▪ DHCPv6 Server会分配IP、DNS

测试内容:测试M、O、A flag在所有排列组合的情况下

▪ 客户端是否会通过RA报文配置无状态IP

▪ 客户端是否会通过RA报文配置prefix子网路由

▪ 客户端是否会通过RA报文配置gateway

▪ 客户端是否会通过DHCPv6获得有状态IP

▪ 客户端是否会通过DHCPv6获得DNS

测试结果


六. 应用场景(选择无状态还是有状态)

何时采用无状态、何时采用有状态,关键看应用场景。核心在于是否需要控制IP地址,比如保持IP不变,如果需要控制,就采用有状态;如果无需控制,就采用无状态。

▷ 服务端领域:如对外提供服务,通常需要采用有状态IP。因为业务IP的突然变化容易导致业务中断(除非做好服务发现)

▷ 客户端领域:如移动设备、办公室内PC机,只需要上IPv6互联网,并不需要对外提供服务,可以采用无状态IP


七. 后续内容

由于篇幅有限,本文尚未贴出实验的详细配置。将会在《IPv6系列》后续文章里,贴出实验的完整信息,包括RA、DHCPv6的配置,以及客户端的配置,敬请关注。


附. 参考文档

1
2
http://www.6deploy.eu/tutorials/080-6deploy_ipv6_autoconfiguration_mechs_v0_4.pdf
https://cshihong.github.io/2018/02/01/DHCPv6基础/