]> git.ipfire.org Git - thirdparty/openwrt.git/commitdiff
base-files: generate a global DHCP DUID
authorDavid Härdeman <david@hardeman.nu>
Thu, 9 Oct 2025 14:16:53 +0000 (16:16 +0200)
committerRobert Marko <robimarko@gmail.com>
Sun, 19 Oct 2025 17:46:22 +0000 (19:46 +0200)
odhcp6c and odhcpd currently generate custom DUIDS on a per-interface basis
using the MAC address of the given interface.

This is contrary to how DUIDs are meant to be used, as the client identifier
will vary from interface to interface, while it is meant to remain stable for a
given host, no matter how the network hardware changes (see RFC8415, §11).

The same problem exists in odhcpd, which also generates server-side DUIDs on a
per-interface basis.

In order to support a stable per-device DUID, generate one on first boot and
store it via uci.

Currently, a DUID-UUID style clientid is generated. This is mostly meant as an
RFC, and we might consider using a different kind of DUID instead (DUID-LLT,
DUID-EN).

One drawback is that this will typically change the DUID used on existing
OpenWrt devices when upgrading to a new release. However, that seems
unavoidable and is a one-time pain in order to have stable DUIDs (and in many
cases, it shouldn't cause any issues).

v2: move the uci cfg generation outside of an IPv6-only block since this
is relevant to the DHCPv4 client as well

Signed-off-by: David Härdeman <david@hardeman.nu>
Link: https://github.com/openwrt/openwrt/pull/20359
Signed-off-by: Robert Marko <robimarko@gmail.com>
package/base-files/files/bin/config_generate
package/base-files/files/etc/uci-defaults/14_network-generate-clientid [new file with mode: 0644]

index 7507aa612c0dd8bc522a74c3d5cd9a625a6f9dae..18fae054d4d9390914c5f1b2bab065c2cd2e8b7a 100755 (executable)
@@ -44,14 +44,15 @@ generate_static_network() {
                set network.loopback.device='lo'
                set network.loopback.proto='static'
                add_list network.loopback.ipaddr='127.0.0.1/8'
+               delete network.globals
+               set network.globals='globals'
+               set network.globals.dhcp_default_duid='auto'
        EOF
-               [ -e /proc/sys/net/ipv6 ] && {
-                       uci -q batch <<-EOF
-                               delete network.globals
-                               set network.globals='globals'
-                               set network.globals.ula_prefix='auto'
-                       EOF
-               }
+       [ -e /proc/sys/net/ipv6 ] && {
+               uci -q batch <<-EOF
+                       set network.globals.ula_prefix='auto'
+               EOF
+       }
 
        if json_is_a dsl object; then
                json_select dsl
diff --git a/package/base-files/files/etc/uci-defaults/14_network-generate-clientid b/package/base-files/files/etc/uci-defaults/14_network-generate-clientid
new file mode 100644 (file)
index 0000000..70da185
--- /dev/null
@@ -0,0 +1,9 @@
+[ "$(uci -q get network.globals.dhcp_default_duid)" != "auto" ] && exit 0
+
+uci -q batch <<-EOF >/dev/null
+       # DUID-UUID - RFC6355
+       set network.globals.dhcp_default_duid="$(hexdump -vn 16 -e '"0004" 2/2 "%x"' /dev/urandom)"
+       commit network
+EOF
+
+exit 0