0%

OpenWrt 启用 ISC-DHCP-Server 全功能 DHCPv6 服务器

业务需要搭建一个 DHCPv6 测试环境,因为手上资源有限,于是决定使用 OpenWrt 的路由器来操作。

测试环境的目标是针对 Android 设备连接 WiFi 的情况下,验证 DHCPv6 的工作情况。

本文提到的 OpenWrt 代指所有运行 OpenWrt24.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
    开启 M
    O 模式,告知客户端启动 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
    

抓包验证

android_dhcpv6_tcpdump.cap