0x01 前言

上个月底,广东电信全面启用家庭宽带的IPv6,分配的子网掩码为64,还支持获取多个前缀。我们可以自建DHCPv6服务器,也可以通过SLAAC从电信获取IP地址,但无论如何,获取到的所有IP都是公网IP,所有数据都可以从公网主动传入。

在实际的使用中,绝大部分用户都是无感的,也不需要记录IP地址或者配置防火墙,我相信大部分路由器都会有一条默认的规则:禁止数据主动传入。但对于我这种喜欢折腾的用户来说,安全还是第一位,其次是可管理性。

为了实现对IPv6的地址的管理,就务必要使用DHCPv6服务,通过设定的固定IP,才能通过防火墙进行流量管理和黑白名单的配置。

0x02 DUID

在配置之前先了解pfsense DHCPv6的一些信息。以下是pfsense DHCPv6 Leases的页面截图:

所有通过DHCPv6服务获取到IPv6地址的机器信息都会在这里显示,其中包含IPv6地址,MAC地址等信息,而配置固定IPv6地址需要用到的是DUID信息。

这个DUID信息有固定的生成模式,而且是通过DHCPv6服务获取IPv6地址必不可少的信息。DUID的全称为:DHCP Unique Identifier,每个支持IPv6的网卡都应该会生成DUID并包含在DHCPv6数据中一并发送到服务器。在我测试环境中发现每个设备都会遵循相关标准生成该DUID,并且不会随意变动,但在虚拟机中修改网卡的某些信息可能会导致DUID产生变化。

DHCPv6服务器会根据DUID确认客户机的配置信息,而DUID最长可达64字节,根据RFC 8415的说明,DUID有以下类型:

  1. Link-layer address plus time (DUID-LLT,链路层地址加时间)
  2. Vendor-assigned unique ID based on Enterprise Number (DUID-EN,由硬件供应商分配)
  3. Link-layer address (DUID-LL,仅链路层地址)
  4. UUID-Based DUID (DUID-UUID,基于UUID)

Link-layer address plus time (DUID-LLT,链路层地址加时间),前2字节为固定值1;紧接着2字节的硬件类型;然后是DUID生成时的秒数,这个秒数须从UTC 2000年1月1日的0点算起;最后跟着链路层地址,这一般是MAC地址:

Link-layer address plus time (DUID-LLT,链路层地址加时间)
Link-layer address plus time (DUID-LLT,链路层地址加时间)

Vendor-assigned unique ID based on Enterprise Number (DUID-EN,由硬件供应商分配),前2字节为固定值2,紧接着企业注册编码和唯一识别码,最后的identifier由厂商自行定义,这个值必须是唯一的:

Vendor-assigned unique ID based on Enterprise Number (DUID-EN,由硬件供应商分配)
Vendor-assigned unique ID based on Enterprise Number (DUID-EN,由硬件供应商分配)

Link-layer address (DUID-LL,仅链路层地址),这种算法较为简单,与Link-layer address plus time (DUID-LLT,链路层地址加时间)类似,其中前2字节为固定值3且少了时间的部分内容:

Link-layer address (DUID-LL,仅链路层地址)
Link-layer address (DUID-LL,仅链路层地址)

UUID-Based DUID (DUID-UUID,基于UUID),前2字节为固定值4,后续的内容为UUID:

UUID-Based DUID (DUID-UUID,基于UUID)
UUID-Based DUID (DUID-UUID,基于UUID)

现在在回头看上面的pfsense截图,图中的DUID如下:

00:04:96:86:ea:61:20:2b:a9:b7:4c:8c:65:94:fa:a3:14:4c

可以发现默认情况下,centos使用UUID-Based DUID (DUID-UUID,基于UUID)生成DUID。所以从第五字节开始,后面的所有内容为UUID:

9686ea61-202b-a9b7-4c8c-6594faa3144c

下面是我某台windows server 2019虚拟机的DUID:

00:01:00:01:24:dd:88:c8:00:50:56:b6:1e:84

可以发现它使用Link-layer address plus time (DUID-LLT,链路层地址加时间)的方式生成DUID,我们根据上图可以将该DUID拆分如下:

DUID-Type:0x0001
hardware type:0x0001
time:24dd88c8
MAC:00:50:56:b6:1e:84

而DUID生成模式的选用也是有要求的,其中第二种建议硬件厂商使用;第一种建议将DUID长久保存,哪怕硬件已经从设备中移除,因为它包含唯一性的MAC地址与DUID生成时间;而第三和第四种则可以按需选择,第四种生成模式一般为最后的选项。

0x03 准备

配置固定IPv6地址,DUID是必须的,各个系统获取DUID的方式各不相同,下面是我常接触到的系统的获取方式。

0x03.1 Centos7

通过以下命令可以找到所有网卡的lease文件:

[[email protected] ~]# ll /var/lib/NetworkManager/ | grep dhclient6 | grep lease
-rw-r--r-- 1 root root 4071 Aug 11 23:45 dhclient6-0bc0b661-8385-42c4-a5a7-07045d498860-ens192.lease

执行以下命令可以找到该网卡二进制的DUID:

[[email protected] ~]# cat /var/lib/NetworkManager/\
> dhclient6-0bc0b661-8385-42c4-a5a7-07045d498860-ens192.lease \
>  | grep default-duid

default-duid "\000\004/A7%\206\335\231\265n7\035\372\003\346\001\376";

但这个二进制的DUID用不上,这时候可以执行以下命令获取DUID:

[[email protected] ~]# cat /var/lib/NetworkManager/\
> dhclient6-0bc0b661-8385-42c4-a5a7-07045d498860-ens192.lease\
>  | grep dhcp6.client-id
  option dhcp6.client-id 0:4:2f:41:37:25:86:dd:99:b5:6e:37:1d:fa:3:e6:1:fe;

dhcp6.client-id即为本机的DUID,如果打开该文件,还可以发现服务器的DUID等信息。在这里需要将获取到的DUID记录下来备用。

0x03.2 Windows

windows系统只需要打开CMD或者power shell窗口并执行以下命令即可找到所有网卡的DUID:

ipconfig /all

0x03.3 MacOS

MacOS需要打开终端并执行以下命令:

sudo plutil -p /var/db/dhcpclient/DUID_IA.plist

输入用户密码后即可得出类似下面的信息:

terence-mbp:~ terencechuen$ sudo plutil -p /var/db/dhcpclient/DUID_IA.plist
Password:
{
  "DUID" => <00010001 00000000 00000000 0000>
  "HostUUID" => <00000000 00000000 00000000 00000000>
  "IAIDList" => [
    0 => "en0"
  ]
}

0x04 DHCPv6 Static Mappings

首先来到DHCPv6 Server & RA的设置界面,然后选中设备所连接的pfsense接口:

然后滚动到页面底部,点击Add打开映射设置界面:

将设备的DUID填写到输入框中,请注意格式,用冒号分隔;Hostname和Description可自定义,建议为设备添加Hostname,后续的防火墙配置可能需要该值。

在配置IPv6地址前请先做好规划,广东电信分配的子网掩码为64,所以IPv6地址中的后8段均由我们自行分配,也就是:

展开地址:xxxx:xxxx:xxxx:xxxx:0000:0000:0000:0000/64

除了以字母x代表的前缀,后面的0都是我们自行控制。在我的环境中,因为都是家庭成员使用,因此设备较少,只需要30到60个可用IP即可。因此,我只启用最后的一段,并且将其可用的DHCP范围控制在00-2f。

固定IP的映射不能与DHCPv6设定的范围重合,所以建议大家先行规划。而我的IPv4网络有三个网段,分别如下:

虚拟机:10.1.1.0/24
家庭成员:10.1.2.0/24
测试与游戏:10.1.3.0/24

相对应的,我的IPv6规划为:

虚拟机:1000-1255
家庭成员:2000-2255
测试与游戏:3000-3255

因为我只启用最后一段,所以第5、第6和第7段都是0,缩写为[::]。另因为DHCPv6服务器中的前缀为PD模式:

所以前缀可以忽略不写,最终填写到IPv6 address框中的内容为:

::1031

以下为我虚拟机网段的IPv6信息:

完成配置后即可重启客户机的网卡并且进行测试,最终的效果如:

240e:fe:2d1d:6802::2081

0x05 结语

电信分配的电子掩码较小,可用的地址非常多,如果需要针对性地配置固定IP,务必要提前做好规划。