Implement working DHCPv6 DDNS (Dynamic DNS)

Follows PR #3909 and fixes #3908
This commit is contained in:
Wagner Sartori Junior 2020-02-03 16:56:22 +01:00
parent ff290c95ec
commit 8eedfcdb5e
No known key found for this signature in database
GPG Key ID: D9B1C1E4503E6F95
2 changed files with 65 additions and 19 deletions

View File

@ -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";
}

View File

@ -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'])) {
<input name="ddnsdomainkeyname" type="text" id="ddnsdomainkeyname" size="20" value="<?=$pconfig['ddnsdomainkeyname'];?>" />
<?=gettext("Enter the dynamic DNS domain key secret which will be used to register client names in the DNS server.");?>
<input name="ddnsdomainkey" type="text" id="ddnsdomainkey" size="20" value="<?=$pconfig['ddnsdomainkey'];?>" />
<?=gettext("Choose the dynamic DNS domain key algorithm.");?><br />
<select name='ddnsdomainalgorithm' id="ddnsdomainalgorithm" class="selectpicker">
<?php
foreach (array("hmac-md5", "hmac-sha512") as $algorithm) :
$selected = "";
if (! empty($pconfig['ddnsdomainalgorithm'])) {
if ($pconfig['ddnsdomainalgorithm'] == $algorithm) {
$selected = "selected=\"selected\"";
}
}?>
<option value="<?=$algorithm;?>" <?=$selected;?>><?=$algorithm;?></option>
<?php
endforeach; ?>
</select>
</div>
</td>
</tr>