业务需要搭建一个 DHCPv6 测试环境,因为手上资源有限,于是决定使用 OpenWrt 的路由器来操作。
测试环境的目标是针对 Android 设备连接 WiFi 的情况下,验证 DHCPv6 的工作情况。
本文提到的 OpenWrt 代指所有运行 OpenWrt 的 24.10.4 版本固件的路由器。
软件包准备
OpenWrt 默认情况下使用 odhcpd 作为 DHCP 服务器。
odhcpd 的功能满足 OpenWrt 的基本要求,但是不满足需要的测试场景,比如不能自定义控制 DHCPv6 的地址范围等参数。
所以需要搭配一个强劲的 DHCPv6 服务器软件。
在 OpenWrt 中安装以下软件包:
- openssl
- isc-dhcp-server-ipv6
- isc-dhcp-omshell-ipv6
界面配置
修改 lan 接口的 IPV4 地址
- 接口 -> lan -> 常规设置 -> IPv4 地址 -> 192.168.10.1
配置 lan 接口的 odhcpd 服务,禁用 DHCPv4、DHCPv6 以及 RA中关闭SLAAC并开启M+O
- 接口 -> lan -> DHCP服务器 -> 常规设置 -> 忽略此接口 -> 勾选
禁用 odhcpd 对 br-lan 开启的 DHCPv4 服务。 - 接口 -> lan -> DHCP服务器 -> IPv6设置 -> RA服务 -> 服务器模式
控制 RA 来源。 - 接口 -> lan -> DHCP服务器 -> IPv6设置 -> DHCPv6服务 -> 已禁用
禁用 odhcpd 对 br-lan 开启的 DHCPv6 服务。 - 接口 -> lan -> DHCP服务器 -> IPv6 RA 设置 -> 默认路由器 -> 强制通告
控制 Android 设备无线网卡是否具备默认路由。
Android 设备默认不会检查 M&O&P 的配置,而是根据是否具有默认路由来判断是否启动 DHCPv6 流程。 - 接口 -> lan -> DHCP服务器 -> IPv6 RA 设置 -> 启用SLAAC -> 取消勾选
模拟没有 SLAAC 或具有无效 SLAAC 的情况。 - 接口 -> lan -> DHCP服务器 -> IPv6 RA 设置 -> RA标记 -> MO
开启 MO 模式,告知客户端启动 DHCPv6 流程。
修改 lan 接口的 IPV6 地址
- 接口 -> 全局网络选项 -> IPv6 ULA 前缀 -> 2001:758:1:1::/64
配置 ULA 前缀,以一个公网前缀开头,模拟公网环境。
最终配置
root@OpenWrt-WDR4310:~# cat /etc/config/dhcp
...
config dhcp 'lan'
option interface 'lan'
option start '100'
option limit '150'
option leasetime '12h'
option dhcpv4 'server'
option ra 'server'
option ra_slaac '0'
list ra_flags 'managed-config'
list ra_flags 'other-config'
option ra_default '2'
...
root@OpenWrt-WDR4310:~# cat /etc/config/network
...
config interface 'lan'
option device 'br-lan'
option proto 'static'
option ipaddr '192.168.10.1'
option netmask '255.255.255.0'
option ip6assign '60'
...
config globals 'globals'
option ula_prefix '2001:758:1:1::/64'
option packet_steering '1'
...
终端配置
由于 isc-dhcp-server 没有前台界面,所以只能通过终端进行配置。
初始化 isc-dhcp-server 运行环境
mkdir -p /var/db/
touch /var/db/dhcpd.leases
touch /var/db/dhcpd6.leases
初始化配置文件
由于 isc-dhcp-server 会通过配置文件规划的网段自动匹配网卡,所以这里使用的是和 br-lan 相同的网段。这也是修改全局 IPV6 地址的原因。
创建 /etc/dhcpd.conf 文件并写入以下内容:
tee /etc/dhcpd.conf <<\EOF
# /etc/dhcpd.conf
subnet 192.168.10.0 netmask 255.255.255.0 {
# Range for clients
range 192.168.10.100 192.168.10.200;
# Additional options
option domain-name-servers 192.168.10.1;
option domain-name "domain.example";
option routers 192.168.10.1;
default-lease-time 600;
max-lease-time 7200;
}
EOF
创建 /etc/dhcpd6.conf 文件并写入以下内容:
tee /etc/dhcpd6.conf <<\EOF
# /etc/dhcpd6.conf
authoritative;
default-lease-time 3600;
max-lease-time 86400;
# Enable RFC 5007 support
#allow leasequery;
# Global definitions for name server address(es) and domain search list
#option dhcp6.name-servers 3ffe:501:ffff:100:200:ff:fe00:3f3e;
#option dhcp6.domain-search "test.example.com","example.com";
# Set preference to 255 (maximum) in order to avoid waiting for
# additional servers when there is only one
#option dhcp6.preference 255;
# Server side command to enable rapid-commit (2 packet exchange)
#option dhcp6.rapid-commit;
# The delay before information-request refresh
# (minimum is 10 minutes, maximum one day, default is to not refresh)
# (set to 6 hours)
#option dhcp6.info-refresh-time 3600;
subnet6 2001:758:1:1::/64 {
# Range for clients
range6 2001:758:1:1:1:: 2001:758:1:1:1::ffff;
# Range for clients requesting a temporary address
range6 2001:758:1:1:2:: /112 temporary;
# Prefix range for delegation to sub-routers pd
prefix6 2001:758:1:1:3:: 2001:758:1:1:4:: /80;
# Additional options
option dhcp6.name-servers 2001:758:1:1::1;
option dhcp6.domain-search "domain.example";
}
EOF
启动服务
将 isc-dhcp-server 服务设为开机自启动并启动服务:
/etc/init.d/dhcpd enabled
/etc/init.d/dhcpd6 enabled
/etc/init.d/dhcpd start
/etc/init.d/dhcpd6 start
通过以下命令查看 dhcpd 服务日志:
logread | grep dhcpd
Wed Dec 10 19:25:26 2025 daemon.info dhcpd: Bound to *:547
...
Wed Dec 10 19:25:26 2025 daemon.info dhcpd: Server starting service.
检查一下启动的服务:
netstat -tplnu
正常结果如下,dhcpd 绑定在 0.0.0.0:67 和 :::547。
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
udp 0 0 0.0.0.0:67 0.0.0.0:* 8087/dhcpd
udp 0 0 :::547 :::* 7582/dhcpd
结果验证
终端验证
- ifconfig
wlan0 Link encap:Ethernet HWaddr d0:a0:d6:1b:3a:e8 Driver wlan inet addr:192.168.10.100 Bcast:192.168.10.255 Mask:255.255.255.0 inet6 addr: fe80::2623:b587:4f56:e6a/64 Scope: Link inet6 addr: 2001:758:1:1:1::fda5/128 Scope: Global UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1 RX packets:19 errors:0 dropped:0 overruns:0 frame:0 TX packets:27 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:3000 RX bytes:2865 TX bytes:3163 - ip address show dev wlan0
36: wlan0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 3000 link/ether d0:a0:d6:1b:3a:e8 brd ff:ff:ff:ff:ff:ff inet 192.168.10.100/24 brd 192.168.10.255 scope global wlan0 valid_lft forever preferred_lft forever inet6 2001:758:1:1:1::fda5/128 scope global nodad dynamic noprefixroute valid_lft 3095sec preferred_lft 1745sec inet6 fe80::2623:b587:4f56:e6a/64 scope link stable-privacy valid_lft forever preferred_lft forever - ping6 -c 4 2001:758:1:1::1
PING 2001:758:1:1::1(2001:758:1:1::1) 56 data bytes 64 bytes from 2001:758:1:1::1: icmp_seq=1 ttl=64 time=7.94 ms 64 bytes from 2001:758:1:1::1: icmp_seq=2 ttl=64 time=7.89 ms 64 bytes from 2001:758:1:1::1: icmp_seq=3 ttl=64 time=10.2 ms 64 bytes from 2001:758:1:1::1: icmp_seq=4 ttl=64 time=8.42 ms --- 2001:758:1:1::1 ping statistics --- 4 packets transmitted, 4 received, 0% packet loss, time 3007ms rtt min/avg/max/mdev = 7.894/8.635/10.287/0.979 ms - ip -6 route show table 0
2001:758:1:1:1::fda5 dev wlan0 table wlan0 proto static metric 1024 pref medium 2001:758:1:1::/64 dev wlan0 table wlan0 proto kernel metric 256 expires 5270sec pref medium 2001:758:1:1::/64 dev wlan0 table wlan0 proto static metric 1024 pref medium fe80::/64 dev wlan0 table wlan0 proto kernel metric 256 pref medium fe80::/64 dev wlan0 table wlan0 proto static metric 1024 pref medium default via fe80::ee88:8fff:febb:9182 dev wlan0 table wlan0 proto ra metric 1024 expires 2570sec hoplimit 64 pref medium 2001:758:1:1:1::fda5 dev wlan0 table wlan0_local proto static metric 1024 pref medium 2001:758:1:1::/64 dev wlan0 table wlan0_local proto static metric 1024 pref medium fe80::/64 dev wlan0 table wlan0_local proto static metric 1024 pref medium fe80::/64 dev dummy0 table dummy0 proto kernel metric 256 pref medium default dev dummy0 table dummy0 proto static metric 1024 pref medium local ::1 dev lo table local proto kernel metric 0 pref medium local 2001:758:1:1:1::fda5 dev wlan0 table local proto kernel metric 0 pref medium local fe80::2623:b587:4f56:e6a dev wlan0 table local proto kernel metric 0 pref medium local fe80::d8b3:36ff:fe3a:3c4c dev dummy0 table local proto kernel metric 0 pref medium multicast ff00::/8 dev dummy0 table local proto kernel metric 256 pref medium multicast ff00::/8 dev wlan0 table local proto kernel metric 256 pref medium