[LEDE-DEV] [PATCH odhcpd] dhcpv6-ia: add option for dhcpv6 privacy address

Eric Luehrsen ericluehrsen at hotmail.com
Thu Mar 9 22:31:33 PST 2017


IP6 SLAAC plus privacy is common. DHCPv6 should be able to provide
the same funciton. This way central IT can maintain integrity and
traceability. However, individual machines will not be easily
placed into a pattern over time by external snooping.

'option dhcpv6_privacy (bool)' is added per interface to switch
from reasonablely consistent 16 bit HOSTID to a random rolling
32 bit HOSTID. See FS#403.

Signed-off-by: Eric Luehrsen <ericluehrsen at hotmail.com>
---
  README          |  2 ++
  src/config.c    |  7 +++++++
  src/dhcpv6-ia.c | 27 ++++++++++++++++++++++++---
  src/odhcpd.h    |  1 +
  4 files changed, 34 insertions(+), 3 deletions(-)

diff --git a/README b/README
index ebb2d99..c382852 100644
--- a/README
+++ b/README
@@ -86,6 +86,8 @@ dhcpv4        string    disabled        DHCPv4 service
  ndp        string    disabled        Neighbor Discovery Proxy
          [disabled|relay|hybrid]

+dhcpv6_privacy    bool    0            32-bit random HOSTID
+                        for DHCPv6
  dynamicdhcp    bool    1            dynamically create leases
                          for DHCPv4 and DHCPv6
  router          list    <local address>         Routers to announce
diff --git a/src/config.c b/src/config.c
index 689d4ce..6c196e0 100644
--- a/src/config.c
+++ b/src/config.c
@@ -40,6 +40,7 @@ enum {
      IFACE_ATTR_DOMAIN,
      IFACE_ATTR_FILTER_CLASS,
      IFACE_ATTR_DHCPV6_RAW,
+    IFACE_ATTR_DHCPV6_PRIVACY,
      IFACE_ATTR_RA_DEFAULT,
      IFACE_ATTR_RA_MANAGEMENT,
      IFACE_ATTR_RA_OFFLINK,
@@ -76,6 +77,7 @@ static const struct blobmsg_policy 
iface_attrs[IFACE_ATTR_MAX] = {
      [IFACE_ATTR_DOMAIN] = { .name = "domain", .type = 
BLOBMSG_TYPE_ARRAY },
      [IFACE_ATTR_FILTER_CLASS] = { .name = "filter_class", .type = 
BLOBMSG_TYPE_STRING },
      [IFACE_ATTR_DHCPV6_RAW] = { .name = "dhcpv6_raw", .type = 
BLOBMSG_TYPE_STRING },
+    [IFACE_ATTR_DHCPV6_PRIVACY] = { .name = "dhcpv6_privacy", .type = 
BLOBMSG_TYPE_BOOL },
      [IFACE_ATTR_PD_MANAGER] = { .name = "pd_manager", .type = 
BLOBMSG_TYPE_STRING },
      [IFACE_ATTR_PD_CER] = { .name = "pd_cer", .type = 
BLOBMSG_TYPE_STRING },
      [IFACE_ATTR_RA_DEFAULT] = { .name = "ra_default", .type = 
BLOBMSG_TYPE_INT32 },
@@ -195,6 +197,7 @@ static void set_interface_defaults(struct interface 
*iface)
      iface->managed = 1;
      iface->learn_routes = 1;
      iface->dhcpv4_leasetime = 43200;
+    iface->dhcpv6_privacy = 0;
      iface->ra_maxinterval = 600;
      iface->ra_mininterval = iface->ra_maxinterval/3;
      iface->ra_lifetime = -1;
@@ -441,6 +444,10 @@ int config_parse_interface(void *data, size_t len, 
const char *name, bool overwr
          iface->dhcpv4_end.s_addr = htonl(
                  ntohl(iface->dhcpv4_start.s_addr) + blobmsg_get_u32(c));

+    if ((c = tb[IFACE_ATTR_DHCPV6_PRIVACY])) {
+        iface->dhcpv6_privacy = blobmsg_get_bool(c);
+    }
+
      if ((c = tb[IFACE_ATTR_MASTER]))
          iface->master = blobmsg_get_bool(c);

diff --git a/src/dhcpv6-ia.c b/src/dhcpv6-ia.c
index fb50448..e9438f6 100644
--- a/src/dhcpv6-ia.c
+++ b/src/dhcpv6-ia.c
@@ -572,16 +572,37 @@ static bool assign_pd(struct interface *iface, 
struct dhcpv6_assignment *assign)

  static bool assign_na(struct interface *iface, struct 
dhcpv6_assignment *assign)
  {
-    /* Seed RNG with checksum of DUID */
      uint32_t seed = 0;
-    for (size_t i = 0; i < assign->clid_len; ++i)
+
+    for (size_t i = 0; i < assign->clid_len; ++i) {
+        /* Seed RNG with simple sum of DUID */
          seed += assign->clid_data[i];
+    }
+
+
+    if (iface->dhcpv6_privacy) {
+        /* Little less predictable */
+        seed += ((uint32_t)time(NULL));
+    }
+
      srand(seed);

+
      /* Try to assign up to 100x */
      for (size_t i = 0; i < 100; ++i) {
          uint32_t try;
-        do try = ((uint32_t)rand()) % 0x0fff; while (try < 0x100);
+
+        if (iface->dhcpv6_privacy) {
+            /* DHCPv6+Privacy similar to SLAAC+Privacy */
+            do try = (((uint32_t)rand()) * ((uint32_t)rand())) % 
0xffffffff;
+            while (try < 0x10000000);
+        }
+
+        else {
+            /* reasonably constant address */
+            do try = ((uint32_t)rand()) % 0xffff;
+            while (try < 0x1000);
+        }

          struct dhcpv6_assignment *c;
          list_for_each_entry(c, &iface->ia_assignments, head) {
diff --git a/src/odhcpd.h b/src/odhcpd.h
index 538a7e5..d28184d 100644
--- a/src/odhcpd.h
+++ b/src/odhcpd.h
@@ -152,6 +152,7 @@ struct interface {
      bool ra_advrouter;
      bool ra_useleasetime;
      bool no_dynamic_dhcp;
+    bool dhcpv6_privacy;

      // RA
      int learn_routes;
-- 
2.7.4



More information about the Lede-dev mailing list