From 8eedfcdb5ed7378915ff05eda1263d079ba33f7d Mon Sep 17 00:00:00 2001 From: Wagner Sartori Junior Date: Mon, 3 Feb 2020 16:56:22 +0100 Subject: [PATCH 1/2] Implement working DHCPv6 DDNS (Dynamic DNS) Follows PR #3909 and fixes #3908 --- src/etc/inc/plugins.inc.d/dhcpd.inc | 66 +++++++++++++++++++++-------- src/www/services_dhcpv6.php | 18 +++++++- 2 files changed, 65 insertions(+), 19 deletions(-) diff --git a/src/etc/inc/plugins.inc.d/dhcpd.inc b/src/etc/inc/plugins.inc.d/dhcpd.inc index 628ae0088..0257ce8fa 100644 --- a/src/etc/inc/plugins.inc.d/dhcpd.inc +++ b/src/etc/inc/plugins.inc.d/dhcpd.inc @@ -1174,7 +1174,7 @@ EOD; } } -function dhcpd_zones($ddns_zones) +function dhcpd_zones($ddns_zones, $ipv6 = false) { $dhcpdconf = ''; @@ -1189,13 +1189,24 @@ function dhcpd_zones($ddns_zones) $primary = $zone['dns-servers'][0]; $secondary = empty($zone['dns-servers'][1]) ? "" : $zone['dns-servers'][1]; - // Make sure we aren't using any invalid or IPv6 DNS servers. - if (!is_ipaddrv4($primary)) { - if (is_ipaddrv4($secondary)) { - $primary = $secondary; - $secondary = ""; - } else { - continue; + // Make sure we aren't using any invalid DNS servers. + if ($ipv6) { + if (!is_ipaddrv6($primary)) { + if (is_ipaddrv6($secondary)) { + $primary = $secondary; + $secondary = ""; + } else { + continue; + } + } + } else { + if (!is_ipaddrv4($primary)) { + if (is_ipaddrv4($secondary)) { + $primary = $secondary; + $secondary = ""; + } else { + continue; + } } } @@ -1204,9 +1215,16 @@ function dhcpd_zones($ddns_zones) if (!empty($domain) && !in_array($domain, $added_zones)) { /* dhcpdconf2 is injected *after* the key */ $dhcpdconf2 = "zone {$domain}. {\n"; - $dhcpdconf2 .= " primary {$primary};\n"; - if (is_ipaddrv4($secondary)) { - $dhcpdconf2 .= " secondary {$secondary};\n"; + if ($ipv6) { + $dhcpdconf2 .= " primary6 {$primary};\n"; + if (is_ipaddrv6($secondary)) { + $dhcpdconf2 .= " secondary6 {$secondary};\n"; + } + } else { + $dhcpdconf2 .= " primary {$primary};\n"; + if (is_ipaddrv4($secondary)) { + $dhcpdconf2 .= " secondary {$secondary};\n"; + } } if (!empty($zone['ddnsdomainkeyname']) && !empty($zone['ddnsdomainkey'])) { if (!in_array($zone['ddnsdomainkeyname'], $added_keys)) { @@ -1407,7 +1425,7 @@ EOD; $dhcpdv6ifs = array(); $ddns_zones = array(); - $nsupdate = false; + $need_ddns_updates = false; foreach ($dhcpdv6cfg as $dhcpv6if => $dhcpv6ifconf) { if (!isset($dhcpv6ifconf['enable']) || !isset($iflist[$dhcpv6if])) { @@ -1435,6 +1453,7 @@ EOD; $newzone = array(); if (isset($dhcpv6ifconf['ddnsupdate'])) { + $need_ddns_updates = true; if (!empty($dhcpv6ifconf['ddnsdomain'])) { $dnscfgv6 .= " ddns-domainname \"{$dhcpv6ifconf['ddnsdomain']}\";\n"; $newzone['domain-name'] = $dhcpv6ifconf['ddnsdomain']; @@ -1442,7 +1461,20 @@ EOD; $newzone['domain-name'] = $config['system']['domain']; } - $nsupdate = true; + $subnetv6 = explode("/", $networkv6)[0]; + $addr = inet_pton($subnetv6); + $addr_unpack = unpack('H*hex', $addr); + $addr_hex = $addr_unpack['hex']; + $revsubnet = array_reverse(str_split($addr_hex)); + foreach ($revsubnet as $octet) { + if ($octet == "0") { + array_shift($revsubnet); + } else { + break; + } + } + + $newzone['ptr-domain'] = implode(".", $revsubnet) . ".ip6.arpa"; } if (isset($dhcpv6ifconf['dnsserver'][0])) { @@ -1550,8 +1582,7 @@ EOD; $newzone['dns-servers'] = array($dhcpv6ifconf['ddnsdomainprimary']); $newzone['ddnsdomainkeyname'] = $dhcpv6ifconf['ddnsdomainkeyname']; $newzone['ddnsdomainkey'] = $dhcpv6ifconf['ddnsdomainkey']; - /* XXX not implemented for IPv6 */ - $newzone['ddnsdomainalgorithm'] = 'hmac-md5'; + $newzone['ddnsdomainalgorithm'] = !empty($dhcpv6ifconf['ddnsdomainalgorithm']) ? $dhcpv6ifconf['ddnsdomainalgorithm'] : "hmac-md5"; $ddns_zones[] = $newzone; } } @@ -1572,9 +1603,10 @@ EOD; } } - if ($nsupdate) { + if ($need_ddns_updates) { $dhcpdv6conf .= "\nddns-update-style interim;\n"; - $dhcpdv6conf .= dhcpd_zones($ddns_zones); + $dhcpdv6conf .= "update-static-leases on;\n"; + $dhcpdv6conf .= dhcpd_zones($ddns_zones, $ipv6 = true); } else { $dhcpdv6conf .= "\nddns-update-style none;\n"; } diff --git a/src/www/services_dhcpv6.php b/src/www/services_dhcpv6.php index 89d433aa3..ee3c664fb 100644 --- a/src/www/services_dhcpv6.php +++ b/src/www/services_dhcpv6.php @@ -64,7 +64,7 @@ if ($_SERVER['REQUEST_METHOD'] === 'GET') { $pconfig['prefixrange_length'] = $config['dhcpdv6'][$if]['prefixrange']['prefixlength']; } $config_copy_fieldsnames = array('defaultleasetime', 'maxleasetime', 'domainsearchlist', 'ddnsdomain', - 'ddnsdomainprimary', 'ddnsdomainkeyname', 'ddnsdomainkey', 'bootfile_url', 'netmask', + 'ddnsdomainprimary', 'ddnsdomainkeyname', 'ddnsdomainkey', 'ddnsdomainalgorithm', 'bootfile_url', 'netmask', 'numberoptions', 'dhcpv6leaseinlocaltime', 'staticmap'); foreach ($config_copy_fieldsnames as $fieldname) { if (isset($config['dhcpdv6'][$if][$fieldname])) { @@ -235,7 +235,7 @@ if ($_SERVER['REQUEST_METHOD'] === 'GET') { // simple 1-on-1 copy $config_copy_fieldsnames = array('defaultleasetime', 'maxleasetime', 'netmask', 'domainsearchlist', - 'ddnsdomain', 'ddnsdomainprimary', 'ddnsdomainkeyname', 'ddnsdomainkey', 'bootfile_url', + 'ddnsdomain', 'ddnsdomainprimary', 'ddnsdomainkeyname', 'ddnsdomainkey', 'ddnsdomainalgorithm', 'bootfile_url', 'dhcpv6leaseinlocaltime'); foreach ($config_copy_fieldsnames as $fieldname) { if (!empty($pconfig[$fieldname])) { @@ -612,6 +612,20 @@ if (isset($config['interfaces'][$if]['dhcpd6track6allowoverride'])) { +
+ From e4db773f14e0c04df90ff79b3a77b1930f34bbde Mon Sep 17 00:00:00 2001 From: Ad Schellevis Date: Fri, 7 Feb 2020 12:15:22 +0100 Subject: [PATCH 2/2] dhcpd: cleanup code related to https://github.com/opnsense/core/pull/3910 --- src/etc/inc/plugins.inc.d/dhcpd.inc | 75 +++++++---------------------- src/www/services_dhcpv6.php | 12 ++--- 2 files changed, 21 insertions(+), 66 deletions(-) diff --git a/src/etc/inc/plugins.inc.d/dhcpd.inc b/src/etc/inc/plugins.inc.d/dhcpd.inc index cd0c4525a..a0bea2b65 100644 --- a/src/etc/inc/plugins.inc.d/dhcpd.inc +++ b/src/etc/inc/plugins.inc.d/dhcpd.inc @@ -1129,14 +1129,12 @@ EOD; } $dhcpdifs[] = get_real_interface($dhcpif); - if (!empty($newzone['domain-name'])) { - if (isset($dhcpifconf['ddnsupdate'])) { - $newzone['dns-servers'] = array($dhcpifconf['ddnsdomainprimary']); - $newzone['ddnsdomainkeyname'] = $dhcpifconf['ddnsdomainkeyname']; - $newzone['ddnsdomainkey'] = $dhcpifconf['ddnsdomainkey']; - $newzone['ddnsdomainalgorithm'] = !empty($dhcpifconf['ddnsdomainalgorithm']) ? $dhcpifconf['ddnsdomainalgorithm'] : "hmac-md5"; - $ddns_zones[] = $newzone; - } + if (!empty($newzone['domain-name']) && isset($dhcpifconf['ddnsupdate']) && is_ipaddrv4($dhcpifconf['ddnsdomainprimary'])) { + $newzone['dns-servers'] = array($dhcpifconf['ddnsdomainprimary']); + $newzone['ddnsdomainkeyname'] = $dhcpifconf['ddnsdomainkeyname']; + $newzone['ddnsdomainkey'] = $dhcpifconf['ddnsdomainkey']; + $newzone['ddnsdomainalgorithm'] = !empty($dhcpifconf['ddnsdomainalgorithm']) ? $dhcpifconf['ddnsdomainalgorithm'] : "hmac-md5"; + $ddns_zones[] = $newzone; } if ($dhcpifconf['omapi'] && !$omapi_added) { @@ -1173,58 +1171,21 @@ EOD; } } -function dhcpd_zones($ddns_zones, $ipv6 = false) +function dhcpd_zones($ddns_zones, $ipproto = 'inet') { $dhcpdconf = ''; - if (is_array($ddns_zones)) { $added_zones = array(); $added_keys = array(); foreach ($ddns_zones as $zone) { - if (!is_array($zone) || empty($zone) || !is_array($zone['dns-servers'])) { - continue; - } - - $primary = $zone['dns-servers'][0]; - $secondary = empty($zone['dns-servers'][1]) ? "" : $zone['dns-servers'][1]; - - // Make sure we aren't using any invalid DNS servers. - if ($ipv6) { - if (!is_ipaddrv6($primary)) { - if (is_ipaddrv6($secondary)) { - $primary = $secondary; - $secondary = ""; - } else { - continue; - } - } - } else { - if (!is_ipaddrv4($primary)) { - if (is_ipaddrv4($secondary)) { - $primary = $secondary; - $secondary = ""; - } else { - continue; - } - } - } - + $versionsuffix = $ipproto == "inet6" ? "6" : ""; // We don't need to add zones multiple times. foreach (array($zone['domain-name'], $zone['ptr-domain']) as $domain) { if (!empty($domain) && !in_array($domain, $added_zones)) { /* dhcpdconf2 is injected *after* the key */ $dhcpdconf2 = "zone {$domain}. {\n"; - if ($ipv6) { - $dhcpdconf2 .= " primary6 {$primary};\n"; - if (is_ipaddrv6($secondary)) { - $dhcpdconf2 .= " secondary6 {$secondary};\n"; - } - } else { - $dhcpdconf2 .= " primary {$primary};\n"; - if (is_ipaddrv4($secondary)) { - $dhcpdconf2 .= " secondary {$secondary};\n"; - } - } + // XXX: $zone['dns-servers'] only contains one item, ref $newzone['dns-servers'] + $dhcpdconf2 .= " primary{$versionsuffix} {$zone['dns-servers'][0]};\n"; if (!empty($zone['ddnsdomainkeyname']) && !empty($zone['ddnsdomainkey'])) { if (!in_array($zone['ddnsdomainkeyname'], $added_keys)) { $dhcpdconf .= "key {$zone['ddnsdomainkeyname']} {\n"; @@ -1576,14 +1537,12 @@ EOD; } } - if (!empty($newzone['domain-name'])) { - if (isset($dhcpv6ifconf['ddnsupdate'])) { - $newzone['dns-servers'] = array($dhcpv6ifconf['ddnsdomainprimary']); - $newzone['ddnsdomainkeyname'] = $dhcpv6ifconf['ddnsdomainkeyname']; - $newzone['ddnsdomainkey'] = $dhcpv6ifconf['ddnsdomainkey']; - $newzone['ddnsdomainalgorithm'] = !empty($dhcpv6ifconf['ddnsdomainalgorithm']) ? $dhcpv6ifconf['ddnsdomainalgorithm'] : "hmac-md5"; - $ddns_zones[] = $newzone; - } + if (!empty($newzone['domain-name']) && isset($dhcpv6ifconf['ddnsupdate']) && is_ipaddrv6($dhcpv6ifconf['ddnsdomainprimary'])) { + $newzone['dns-servers'] = array($dhcpv6ifconf['ddnsdomainprimary']); + $newzone['ddnsdomainkeyname'] = $dhcpv6ifconf['ddnsdomainkeyname']; + $newzone['ddnsdomainkey'] = $dhcpv6ifconf['ddnsdomainkey']; + $newzone['ddnsdomainalgorithm'] = !empty($dhcpv6ifconf['ddnsdomainalgorithm']) ? $dhcpv6ifconf['ddnsdomainalgorithm'] : "hmac-md5"; + $ddns_zones[] = $newzone; } if (preg_match("/poes/si", $dhcpv6if)) { @@ -1605,7 +1564,7 @@ EOD; if ($need_ddns_updates) { $dhcpdv6conf .= "\nddns-update-style interim;\n"; $dhcpdv6conf .= "update-static-leases on;\n"; - $dhcpdv6conf .= dhcpd_zones($ddns_zones, $ipv6 = true); + $dhcpdv6conf .= dhcpd_zones($ddns_zones, "inet6"); } else { $dhcpdv6conf .= "\nddns-update-style none;\n"; } diff --git a/src/www/services_dhcpv6.php b/src/www/services_dhcpv6.php index d66241a28..b637c5b91 100644 --- a/src/www/services_dhcpv6.php +++ b/src/www/services_dhcpv6.php @@ -615,14 +615,10 @@ if (isset($config['interfaces'][$if]['dhcpd6track6allowoverride'])) {