IPv6中的地址配置

2020-07-03 10:10:08 浏览数 (1)

赵大宝

别信广告,看疗效呗~

导 言

网络上的一台主机想和其他设备通信,首先要拥有一个IP地址,除此之外还需要网关、路由、DNS server等,只有正确的配置了这些信息,它才能和网络上的其他设备正常通信。在IPv4中,这些信息通常是通过DHCP(Dynamic Host Configuration Protocol)配置到主机上的。

但是在IPv6中,事情要更复杂一些……

1

DHCP协议

DHCP是C/S结构,每一个局域网都会部署本子网的DHCP server,监听并响应本地链路上的DHCP请求,主机在接入网络之后主动发送DHCP请求消息,由于此时主机还没有IP地址,也不知道DHCP server的IP地址,所以DHCP请求的源IP地址是0.0.0.0,目的IP地址是255.255.255.255(广播地址),这个报文在本地链路上广播。

DHCP server在收到DHCP请求之后,会为当前的client分配IP地址,并且将client和IP地址的映射关系记录在其数据库中,最后发送DHCP应答消息给client。DHCP协议完整的交互过程如下:

DHCP除了分配IP地址之外,还定义了丰富的可选字段(Options),通过这些可选字段为主机提供丰富的配置信息。常用的配置信息包括:

- IP地址

- 前缀信息

- 网关地址

- 路由信息

- MTU

- DNSserver、domain等

与IPv4类似,IPv6也需要某种动态的地址配置协议,来实现主机IPv6地址的动态配置,不过在IPv6中,这件事情要更复杂一些。

2

IPv6地址自动配置

IPv6中相关的协议有两个,NDP和DHCPv6,通常情况下需要两个协议的配合才能完成IPv6主机地址的自动配置。

- NDP:全称邻居发现协议(Neighbor Discovery Protocol),是IPv6协议体系中最重要的一个基础协议,它实现了地址解析、验证邻居是否可达、重复地址检测、路由器发现/前缀发现、地址自动配置和重定向等功能。

- DHCPv6:DHCP协议的IPv6版本,类似于IPv4的DHCP协议。

因为存在以上两个协议,所以IPv6地址的配置分为三种模式:

- SLAAC:全称无状态地址自动配置(Stateless Auto Address Configuration),利用NDP下发网关和子网前缀等信息,主机根据子网前缀自动生成IPv6地址;没有DHCPv6。

- DHCPv6Stateless:利用NDP下发网关和子网前缀等信息,主机根据子网前缀自动生成IPv6地址;利用DHCPv6配置DNSserver和域名等其他信息。

- DHCPv6Stateful:利用NDP下发网关和子网前缀等信息;利用DHCPv6配置IPv6地址、DNS server和域名等其他信息。

三种模式的对比如下表所示:

3

为什么IPv6的主机网络配置如此复杂呢?

IPv6工作委员会认为IP地址、网关、地址前缀和MTU属于网络层信息(MTU虽然是链路层的大小,但是它决定了网络层分片的大小),IPv6作为网络层协议,这些信息的配置在其邻居发现协议中实现,承载在网络层协议ICMPv6报文中下发。

但是DNS server和域名等被认为是应用层信息,没有在最初的邻居发现协议中实现。

后来又有了DHCPv6协议,除了下发IPv6地址外,也支持下发DNS等应用层信息。但是DHCPv6属于应用层协议,所以它不支持下发网关、子网前缀、主机路由、MTU等网络层信息,这些信息还需要通过NDP来获取。

IETF委员会的成员在此问题上分为两派,一派认为应该在NDP中增加DNS等应用层信息,以简化IPv6主机的网络配置,另一派认为应该保持设计的“纯粹”,不应该在网络层协议中下发应用层信息,这样的争论一直持续到了今天。同样的争论也发生在DHCPv6协议的标准制定过程中,所以导致了如今复杂的局面。

其实在RFC6106中,已经为NDP增加一个option字段RDNSS(Recursive DNS Server),用来设置DNS server地址,但是因为以上争议的存在,各操作系统对此支持不太一致,Linux各发行版都已经支持,Windows目前只有Windows 10 1703 Creators Update支持;

详细的支持情况请参考:

Comparison of IPv6 support in operating systems

(https://en.wikipedia.org/wiki/Comparison_of_IPv6_support_in_operating_systems)

4

邻居发现协议

邻居发现协议是IPv6协议体系中最重要的一个基础协议,它实现的功能很多,这里只介绍与主机配置相关的功能,也就是路由器发现与前缀发现。

路由器发现/前缀发现通过路由器请求消息(Router Solicitation,RS)和路由器通告消息(Router Advertisement,RA)来实现,具体过程如下:

- 主机启动时,通过RS消息向路由器发出请求,源地址是Link local地址,目的地址是FF02::2(所有路由器组播地址),请求地址前缀和其他配置信息,以便用于主机的配置。

- 路由器返回RA消息,其中包括前缀信息选项(路由器也会周期性地发布RA消息)。

- 节点利用路由器返回的RA消息中的地址前缀及其他配置参数,自动配置接口的IPv6地址及其他信息,接口地址可以使用按照IEEE EUI-64的定义构造,其他信息包括了网关地址、其他明细路由、DNS等。

协议的交互过程如下图所示:

5

IEEEEUI-64

路由器下发的RA报文只携带子网前缀,没有具体的IP地址。在Stateless和SLAAC模式下,主机需要根据前缀信息自动构造IPv6地址,一种常见的构造方式成为EUI-64。

EUI-64格式地址由地址前缀和接口标识两部分组成,前缀固定为64位,接口标识符64位。IEEEEUI-64规定了这种情况下64位接口标识符的构造方式。

IEEE EUI-64规定接口标识符由MAC地址构造,而MAC地址只有48位,因此在MAC地址的中间位置(从高位开始的第24位后)插入十六进制数FFFE,二进制表示为1111111111111110。

为了确保从MAC地址得到的接口标识符是唯一的,还要将MAC地址的Universal/Local 位(从高位开始的第7位)设置为“1”,最后得到的这组数就作为EUI-64格式的接口标识符。

IEEE EUI-64只是接口标识符构造的方式之一,Linux系统默认使用该标准。不过还有其他的构造方式,比如Windows默认就采用随机生成方式产生接口标志符。

6

Linux主机的配置

前面介绍的三种配置方式各有优缺点,比如SLAAC虽然最简单,但是要求掩码长度必须为64,地址浪费严重,另外也不支持下发DNS sever和域名等应用层信息;DHCPv6 Stateful最灵活,可以对IP地址精确控制,但是需要部署DHCPv6 server,比较复杂。

用户在将自己的主机接入IPv6网络的时候,需要根据当前网络使用的地址配置模式来配置操作系统,才能正确的获取IPv6地址,这里以CentOS7为例介绍主机操作系统的配置。

配置的关键有两点,一是是否接受RA报文,二是DHCP client的配置。

是否接收RA通过sysctl的accept_ra参数配置,其中0表示不接受RA;1表示如果forwarding是关闭的就接受RA,如果forwarding是打开的则不接受RA(代表主机可能作为一个路由器);2表示不论forwarding是打开还是关闭,都接受RA。

在上面的介绍中,无论是stateful、stateless还是slaac,都需要通过RA配置网关和MTU等,accept_ra需要配置为1或者2。

编辑文件/etc/sysctl.conf,添加如下内容:

 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

DHCP client可以通过sysconfig脚本配置。比如要配置DHCPv6 Stateful时编辑配置文件/etc/sysconfig/network-scripts/ifcfg-eth0,内容如下:

BOOTPROTO=dhcp

DEVICE=eth0

IPV6INIT=yes

IPV6_AUTOCONF=yes

DHCPV6C=yes

DHCPV6C_OPTIONS=-nw   # 支持dhclient立即(nowait)变为daemon,而不是等待直到获取一个IPv6地址

ONBOOT=yes

TYPE=Ethernet

USERCTL=no

如果要配置DHCPv6 stateless模式,只需要将上面配置文件中的DHCPV6C_OPTIONS设置为"-S",指示dhclient只获取IPv6地址之外的其他信息。

如果要配置SLAAC模式,只需要将上面配置文件中的DHCPV6C设置为"no",表示关闭DHCPv6 client。

另外目前CentOS 7发行版的dhclient有BUG,它将掩码长度固定为64,导致实际子网掩码长度不等于64的时候路由会出问题。DHCPv6下发的地址信息中只包含了IPv6地址,没有提供子网的掩码信息,实际的掩码/邻居信息是通过路由器的RA报文下发的,dhclient正确的做法是设置IPv6地址的掩码为128,然后由路由器通过RA报文配置路由信息。

往期精彩内容回顾

1

S3请求来了,该怎么处理?

2

初探Docker的网络模式

3

OpenStack Policy鉴权大解密!

听说长得好看的人都点了赞和在看!

0 人点赞