Skip to content

Commit acafd80

Browse files
author
Till Brehm
committed
Various fixes and improvements in multi algo DNSSEC implementation.
1 parent 68faf13 commit acafd80

File tree

2 files changed

+45
-24
lines changed

2 files changed

+45
-24
lines changed

interface/web/dns/templates/dns_soa_edit.htm

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -139,9 +139,7 @@
139139
</div>
140140
<div class="form-group">
141141
<label for="dnssec_algo" class="col-sm-3 control-label">{tmpl_var name='dnssec_algo_txt'}</label>
142-
<div class="col-sm-9"><select name="dnssec_algo" id="dnssec_algo" class="form-control">
143-
{tmpl_var name='dnssec_algo'}
144-
</select></div>
142+
<div class="col-sm-9">{tmpl_var name='dnssec_algo'}</div>
145143
</div>
146144
<div class="form-group">
147145
<label for="update_acl" class="col-sm-3 control-label">{tmpl_var name='dnssec_info_txt'}</label>

server/plugins-available/bind_plugin.inc.php

Lines changed: 44 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -97,27 +97,29 @@ function soa_dnssec_create(&$data) {
9797
}
9898

9999
//* Verify that we do not already have keys (overwriting-protection)
100-
if (file_exists($dns_config['bind_zonefiles_dir'].'/dsset-'.$domain.'.')) {
101-
return $this->soa_dnssec_update($data);
102-
} else if ($data['new']['dnssec_initialized'] == 'Y') { //In case that we generated keys but the dsset-file was not generated
103-
$keycount=0;
104-
foreach (glob($dns_config['bind_zonefiles_dir'].'/K'.$domain.'*.key') as $keyfile) {
105-
$keycount++;
106-
}
107-
if ($keycount > 0) {
108-
$this->soa_dnssec_sign($data);
109-
return true;
100+
if($data['old']['dnssec_algo'] == $data['new']['dnssec_algo']) {
101+
if (file_exists($dns_config['bind_zonefiles_dir'].'/dsset-'.$domain.'.')) {
102+
return $this->soa_dnssec_update($data);
103+
} else if ($data['new']['dnssec_initialized'] == 'Y') { //In case that we generated keys but the dsset-file was not generated
104+
$keycount=0;
105+
foreach (glob($dns_config['bind_zonefiles_dir'].'/K'.$domain.'*.key') as $keyfile) {
106+
$keycount++;
107+
}
108+
if ($keycount > 0) {
109+
$this->soa_dnssec_sign($data);
110+
return true;
111+
}
110112
}
111113
}
112114

113115
// Get DNSSEC Algorithms
114116
$dnssec_algo = explode(',',$data['new']['dnssec_algo']);
115117

116-
//Do some magic...
117-
if(in_array('ECDSAP256SHA256',$dnssec_algo)) {
118+
//* Create the Zone Signing and Key Signing Keys
119+
if(in_array('ECDSAP256SHA256',$dnssec_algo) && count(glob($dns_config['bind_zonefiles_dir'].'/K'.$domain.'.+013*.key')) == 0) {
118120
$app->system->exec_safe('cd ?; dnssec-keygen -3 -a ECDSAP256SHA256 -n ZONE ?; dnssec-keygen -f KSK -3 -a ECDSAP256SHA256 -n ZONE ?', $dns_config['bind_zonefiles_dir'], $domain, $domain);
119121
}
120-
if(in_array('NSEC3RSASHA1',$dnssec_algo)) {
122+
if(in_array('NSEC3RSASHA1',$dnssec_algo) && count(glob($dns_config['bind_zonefiles_dir'].'/K'.$domain.'.+007*.key')) == 0) {
121123
$app->system->exec_safe('cd ?; dnssec-keygen -a NSEC3RSASHA1 -b 2048 -n ZONE ?; dnssec-keygen -f KSK -a NSEC3RSASHA1 -b 4096 -n ZONE ?', $dns_config['bind_zonefiles_dir'], $domain, $domain);
122124
}
123125

@@ -138,23 +140,40 @@ function soa_dnssec_sign(&$data) {
138140
$domain = substr($data['new']['origin'], 0, strlen($data['new']['origin'])-1);
139141
if (!file_exists($dns_config['bind_zonefiles_dir'].'/'.$filespre.$domain)) return false;
140142

143+
//* Get DNSSEC Algorithms
144+
$dnssec_algo = explode(',',$data['new']['dnssec_algo']);
145+
146+
//* Get Zone file content
141147
$zonefile = file_get_contents($dns_config['bind_zonefiles_dir'].'/'.$filespre.$domain);
142148
$keycount=0;
143-
foreach (glob($dns_config['bind_zonefiles_dir'].'/K'.$domain.'*.key') as $keyfile) {
144-
$includeline = '$INCLUDE '.basename($keyfile);
145-
if (!preg_match('@'.preg_quote($includeline).'@', $zonefile)) $zonefile .= "\n".$includeline."\n";
146-
$keycount++;
149+
150+
//* Include ECDSAP256SHA256 keys in zone
151+
if(in_array('ECDSAP256SHA256',$dnssec_algo)) {
152+
foreach (glob($dns_config['bind_zonefiles_dir'].'/K'.$domain.'.+013*.key') as $keyfile) {
153+
$includeline = '$INCLUDE '.basename($keyfile);
154+
if (!preg_match('@'.preg_quote($includeline).'@', $zonefile)) $zonefile .= "\n".$includeline."\n";
155+
$keycount++;
156+
}
157+
}
158+
159+
//* Include NSEC3RSASHA1 keys in zone
160+
if(in_array('NSEC3RSASHA1',$dnssec_algo)) {
161+
foreach (glob($dns_config['bind_zonefiles_dir'].'/K'.$domain.'.+007*.key') as $keyfile) {
162+
$includeline = '$INCLUDE '.basename($keyfile);
163+
if (!preg_match('@'.preg_quote($includeline).'@', $zonefile)) $zonefile .= "\n".$includeline."\n";
164+
$keycount++;
165+
}
147166
}
148167

149168
$keycount_wanted = count(explode(',',$data['new']['dnssec_algo']))*2;
150169

151-
if ($keycount != $keycount_wanted) $app->log('DNSSEC Warning: There are more or less than 2 keyfiles for each algorithm for zone '.$domain, LOGLEVEL_WARN);
170+
if ($keycount != $keycount_wanted) $app->log('DNSSEC Warning: There are more or less than 2 keyfiles for each algorithm for zone '.$domain.'. Found: '.$keycount. ' Expected: '.$keycount_wanted, LOGLEVEL_WARN);
152171
file_put_contents($dns_config['bind_zonefiles_dir'].'/'.$filespre.$domain, $zonefile);
153172

154-
//Sign the zone and set it valid for max. 16 days
173+
//* Sign the zone and set it valid for max. 16 days
155174
$app->system->exec_safe('cd ?; dnssec-signzone -A -e +1382400 -3 $(head -c 1000 /dev/random | sha1sum | cut -b 1-16) -N increment -o ? -t ?', $dns_config['bind_zonefiles_dir'], $domain, $filespre.$domain);
156175

157-
//Write Data back ino DB
176+
//* Write Data back ino DB
158177
$dnssecdata = "DS-Records:\n".file_get_contents($dns_config['bind_zonefiles_dir'].'/dsset-'.$domain.'.');
159178
$dnssecdata .= "\n------------------------------------\n\nDNSKEY-Records:\n";
160179
foreach (glob($dns_config['bind_zonefiles_dir'].'/K'.$domain.'*.key') as $keyfile) {
@@ -209,7 +228,10 @@ function soa_dnssec_delete(&$data) {
209228

210229
$domain = substr($data['new']['origin'], 0, strlen($data['new']['origin'])-1);
211230

212-
unlink($dns_config['bind_zonefiles_dir'].'/K'.$domain.'.+*');
231+
$key_files = glob($dns_config['bind_zonefiles_dir'].'/K'.$domain.'.+*');
232+
foreach($key_files as $file) {
233+
unlink($file);
234+
}
213235
unlink($dns_config['bind_zonefiles_dir'].'/'.$this->zone_file_prefix().$domain.'.signed');
214236
unlink($dns_config['bind_zonefiles_dir'].'/dsset-'.$domain.'.');
215237

@@ -320,6 +342,7 @@ function soa_update($event_name, $data) {
320342
if (@$data['old']['dnssec_initialized'] == 'Y' && strlen(@$data['old']['origin']) > 3) $this->soa_dnssec_delete($data); //delete old keys
321343
if ($data['new']['dnssec_wanted'] == 'Y') $this->soa_dnssec_create($data);
322344
} elseif($data['old']['dnssec_algo'] != $data['new']['dnssec_algo']) {
345+
$app->log("DNSSEC Algorithm has changed: ".$data['new']['dnssec_algo'], LOGLEVEL_DEBUG);
323346
if ($data['new']['dnssec_wanted'] == 'Y') $this->soa_dnssec_create($data);
324347
} elseif ($data['new']['dnssec_wanted'] == 'Y' && $data['old']['dnssec_initialized'] == 'N') {
325348
$this->soa_dnssec_create($data);

0 commit comments

Comments
 (0)