44 %config = read_conf("$FindBin::Bin/dnstools.conf", "/etc/dnstools.conf"); |
44 %config = read_conf("$FindBin::Bin/dnstools.conf", "/etc/dnstools.conf"); |
45 |
45 |
46 our @new_serial; # liste fuer neuen serial |
46 our @new_serial; # liste fuer neuen serial |
47 our @begin_ro_list; # liste mit zonen deren key-rollover beginnt |
47 our @begin_ro_list; # liste mit zonen deren key-rollover beginnt |
48 our @end_ro_list; # liste mit zonen deren key-rollover fertig ist |
48 our @end_ro_list; # liste mit zonen deren key-rollover fertig ist |
49 our $master_dir = $config{master_dir}; |
|
50 our $bind_dir = $config{bind_dir}; |
49 our $bind_dir = $config{bind_dir}; |
51 our $conf_dir = $config{zone_conf_dir}; |
50 our $conf_dir = $config{zone_conf_dir}; |
52 our $sign_alert_time = $config{sign_alert_time}; |
51 our $sign_alert_time = $config{sign_alert_time}; |
53 our $indexzone = $config{indexzone}; |
52 our $indexzone = $config{indexzone}; |
54 our $key_counter_end = $config{key_counter_end}; |
53 our $key_counter_end = $config{key_counter_end}; |
55 our $ablauf_zeit = $config{abl_zeit}; |
54 our $ablauf_zeit = $config{abl_zeit}; |
56 |
55 |
57 add_argv; |
56 add_argv; |
|
57 |
58 changed_zone; |
58 changed_zone; |
59 sign_end; |
59 sign_end; |
60 |
60 |
61 to_begin_ro; # prueft nach beginnenden rollover-verfahren |
61 to_begin_ro; # prueft nach beginnenden rollover-verfahren |
62 to_end_ro; # prueft nach endenden rollover-verfahren |
62 to_end_ro; # prueft nach endenden rollover-verfahren |
110 |
110 |
111 sub add_argv { |
111 sub add_argv { |
112 # checked whether the zones in argv are managed zones and |
112 # checked whether the zones in argv are managed zones and |
113 #inserted them into the list new_serial |
113 #inserted them into the list new_serial |
114 our @new_serial; |
114 our @new_serial; |
115 our $master_dir; |
|
116 my $zone; |
115 my $zone; |
117 |
116 |
118 for (@ARGV) { |
117 for (@ARGV) { |
119 chomp($zone = `idn --quiet "$_"`); |
118 chomp($zone = `idn --quiet "$_"`); |
120 if (-e "$master_dir/$zone/$zone") { |
119 if (-e "$config{master_dir}/$zone/$zone") { |
121 push @new_serial, $zone; |
120 push @new_serial, $zone; |
122 } |
121 } |
123 } |
122 } |
124 } |
123 } |
125 |
124 |
126 sub changed_zone { |
125 sub changed_zone { |
127 our $master_dir; |
126 our @new_serial; |
128 our @new_serial; |
127 |
129 |
128 while (glob "$config{master_dir}/*") { |
130 for (<$master_dir/*>) { |
|
131 my $zone = basename($_); |
129 my $zone = basename($_); |
132 |
130 |
133 if (-e "$master_dir/$zone/.stamp") { |
131 if (-e "$config{master_dir}/$zone/.stamp") { |
134 my $stamptime = (-M "$master_dir/$zone/.stamp"); |
132 my $stamptime = (-M "$config{master_dir}/$zone/.stamp"); |
135 my $filetime = (-M "$master_dir/$zone/$zone"); |
133 my $filetime = (-M "$config{master_dir}/$zone/$zone"); |
136 if ($stamptime > $filetime) { |
134 if ($stamptime > $filetime) { |
137 push @new_serial, $zone; |
135 push @new_serial, $zone; |
138 print " * $zone: zonedatei wurde geaendert\n"; |
136 print " * $zone: zonedatei wurde geaendert\n"; |
139 } |
137 } |
140 } |
138 } |
148 } |
146 } |
149 |
147 |
150 sub sign_end { |
148 sub sign_end { |
151 our $sign_alert_time; # the time between the end and the new signing |
149 our $sign_alert_time; # the time between the end and the new signing |
152 # (see external configuration) |
150 # (see external configuration) |
153 our $master_dir; |
|
154 our @new_serial; |
151 our @new_serial; |
155 |
152 |
156 # erzeugt $time (die zeit ab der neu signiert werden soll) |
153 # erzeugt $time (die zeit ab der neu signiert werden soll) |
157 my $unixtime = time + (3600 * $sign_alert_time); |
154 my $unixtime = time + (3600 * $sign_alert_time); |
158 my $time = `date -d \@$unixtime +%Y%m%d%H`; |
155 my $time = `date -d \@$unixtime +%Y%m%d%H`; |
159 |
156 |
160 ## vergleicht fuer alle zonen im ordner $master_dir mit einer |
157 ## vergleicht fuer alle zonen im ordner $config{master_dir} mit einer |
161 ## <zone>.signed-datei den zeitpunkt in $time mit dem ablaufdatum der |
158 ## <zone>.signed-datei den zeitpunkt in $time mit dem ablaufdatum der |
162 ## signatur, welcher aus der datei <zone>.signed ausgelesen wird. |
159 ## signatur, welcher aus der datei <zone>.signed ausgelesen wird. |
163 for (<$master_dir/*>) { |
160 while (glob "$config{master_dir}/*") { |
164 s#($master_dir/)(.*)#$2#; |
161 s#($config{master_dir}/)(.*)#$2#; |
165 my $zone = $_; |
162 my $zone = $_; |
166 |
163 |
167 if (-e "$master_dir/$zone/$zone.signed") { |
164 if (-e "$config{master_dir}/$zone/$zone.signed") { |
168 open(ZONE, "$master_dir/$zone/$zone.signed"); |
165 open(ZONE, "$config{master_dir}/$zone/$zone.signed"); |
169 my @zone_sig_content = <ZONE>; |
166 my @zone_sig_content = <ZONE>; |
170 close(ZONE); |
167 close(ZONE); |
171 |
168 |
172 for (@zone_sig_content) { |
169 for (@zone_sig_content) { |
173 if (m#SOA.*[0-9]{14}#) { |
170 if (m#SOA.*[0-9]{14}#) { |
183 |
180 |
184 sub sign_zone { |
181 sub sign_zone { |
185 |
182 |
186 # signiert die zonen und erhoeht den wert in der keycounter-datei |
183 # signiert die zonen und erhoeht den wert in der keycounter-datei |
187 our @new_serial; |
184 our @new_serial; |
188 our $master_dir; |
|
189 my $zone; |
185 my $zone; |
190 my $kc; |
186 my $kc; |
191 |
187 |
192 for (uniq(@new_serial)) { |
188 for (uniq(@new_serial)) { |
193 $zone = $_; |
189 $zone = $_; |
194 |
190 |
195 unless (-e "$master_dir/$zone/.index.zsk") { |
191 unless (-e "$config{master_dir}/$zone/.index.zsk") { |
196 next; |
192 next; |
197 } |
193 } |
198 |
194 |
199 chdir "$master_dir/$zone"; |
195 chdir "$config{master_dir}/$zone"; |
200 if (`dnssec-signzone $zone 2>/dev/null`) { |
196 if (`dnssec-signzone $zone 2>/dev/null`) { |
201 print " * $zone neu signiert \n"; |
197 print " * $zone neu signiert \n"; |
202 |
198 |
203 # erhoeht den keycounter |
199 # erhoeht den keycounter |
204 if ("$master_dir/$zone/.keycounter") { |
200 if ("$config{master_dir}/$zone/.keycounter") { |
205 open(KC, "$master_dir/$zone/.keycounter"); |
201 open(KC, "$config{master_dir}/$zone/.keycounter"); |
206 $kc = <KC>; |
202 $kc = <KC>; |
207 close(KC); |
203 close(KC); |
208 $kc += 1; |
204 $kc += 1; |
209 } |
205 } |
210 else { |
206 else { |
211 $kc = 1; |
207 $kc = 1; |
212 } |
208 } |
213 open(KC, ">$master_dir/$zone/.keycounter"); |
209 open(KC, ">$config{master_dir}/$zone/.keycounter"); |
214 print KC $kc; |
210 print KC $kc; |
215 close(KC); |
211 close(KC); |
216 } |
212 } |
217 else { print "$zone konnte nicht signiert werden \n"; } |
213 else { print "$zone konnte nicht signiert werden \n"; } |
218 } |
214 } |
219 } |
215 } |
220 |
216 |
221 sub update_serial { |
217 sub update_serial { |
222 our $master_dir; |
|
223 our @new_serial; |
218 our @new_serial; |
224 chomp(my $date = `date +%Y%m%d`); |
219 chomp(my $date = `date +%Y%m%d`); |
225 my @new_content; |
220 my @new_content; |
226 my $sdate; |
221 my $sdate; |
227 my $scount; |
222 my $scount; |
229 |
224 |
230 for (uniq(@new_serial)) { |
225 for (uniq(@new_serial)) { |
231 |
226 |
232 # erhoeht den serial |
227 # erhoeht den serial |
233 my $zone = $_; |
228 my $zone = $_; |
234 my $file = "$master_dir/$zone/$zone"; |
229 my $file = "$config{master_dir}/$zone/$zone"; |
235 my @new_content = (); |
230 my @new_content = (); |
236 |
231 |
237 open(SER, "<$file") or die "$file: $!\n"; |
232 open(SER, "<$file") or die "$file: $!\n"; |
238 for (<SER>) { |
233 for (<SER>) { |
239 if (/^\s+(\d+)(\d{2})\s*;\s*serial/i) { |
234 if (/^\s+(\d+)(\d{2})\s*;\s*serial/i) { |
258 open(RES, ">$file") or die "$file: $!\n"; |
253 open(RES, ">$file") or die "$file: $!\n"; |
259 print RES @new_content; |
254 print RES @new_content; |
260 close(RES); |
255 close(RES); |
261 print " * $zone: serial erhoeht \n"; |
256 print " * $zone: serial erhoeht \n"; |
262 |
257 |
263 open(STAMP, ">$master_dir/$zone/.stamp") |
258 open(STAMP, ">$config{master_dir}/$zone/.stamp") |
264 or die "$master_dir/$zone/.stamp: $!\n"; |
259 or die "$config{master_dir}/$zone/.stamp: $!\n"; |
265 close(STAMP); |
260 close(STAMP); |
266 print " * $zone: stamp aktualisiert \n"; |
261 print " * $zone: stamp aktualisiert \n"; |
267 } |
262 } |
268 } |
263 } |
269 |
264 |
287 sub update_index { |
282 sub update_index { |
288 |
283 |
289 # aktualisiert die indexzone; |
284 # aktualisiert die indexzone; |
290 our @new_serial; |
285 our @new_serial; |
291 our $indexzone; |
286 our $indexzone; |
292 our $master_dir; |
|
293 my @iz_content_old; |
287 my @iz_content_old; |
294 my @iz_content_new; |
288 my @iz_content_new; |
295 |
289 |
296 open(INDEXZONE, "$master_dir/$indexzone/$indexzone") |
290 open(INDEXZONE, "$config{master_dir}/$indexzone/$indexzone") |
297 or die "$master_dir/$indexzone/$indexzone: $!\n"; |
291 or die "$config{master_dir}/$indexzone/$indexzone: $!\n"; |
298 @iz_content_old = <INDEXZONE>; |
292 @iz_content_old = <INDEXZONE>; |
299 close(INDEXZONE); |
293 close(INDEXZONE); |
300 |
294 |
301 for (@iz_content_old) { |
295 for (@iz_content_old) { |
302 unless (m#ZONE::#) { |
296 unless (m#ZONE::#) { |
303 push @iz_content_new, $_; |
297 push @iz_content_new, $_; |
304 } |
298 } |
305 } |
299 } |
306 |
300 |
307 for my $dir (glob "$master_dir/*") { |
301 for my $dir (glob "$config{master_dir}/*") { |
308 my $zone = basename($dir); |
302 my $zone = basename($dir); |
309 my $info_end = "::sec-off"; |
303 my $info_end = "::sec-off"; |
310 |
304 |
311 if (-e "$dir/.keycounter") { |
305 if (-e "$dir/.keycounter") { |
312 $info_end = "::sec-on"; |
306 $info_end = "::sec-on"; |
315 my $iz_line = "\t\tIN TXT\t\t\"ZONE::$zone$info_end\"\n"; |
309 my $iz_line = "\t\tIN TXT\t\t\"ZONE::$zone$info_end\"\n"; |
316 |
310 |
317 push @iz_content_new, $iz_line; |
311 push @iz_content_new, $iz_line; |
318 } |
312 } |
319 |
313 |
320 open(INDEXZONE, ">$master_dir/$indexzone/$indexzone") |
314 open(INDEXZONE, ">$config{master_dir}/$indexzone/$indexzone") |
321 or die "$master_dir/$indexzone/$indexzone: $!\n"; |
315 or die "$config{master_dir}/$indexzone/$indexzone: $!\n"; |
322 print INDEXZONE @iz_content_new; |
316 print INDEXZONE @iz_content_new; |
323 close(INDEXZONE); |
317 close(INDEXZONE); |
324 |
318 |
325 # fuegt die index-zone in die liste damit der serial erhoet wird |
319 # fuegt die index-zone in die liste damit der serial erhoet wird |
326 push @new_serial, $indexzone; |
320 push @new_serial, $indexzone; |
328 print "** index-zone aktualisiert \n"; |
322 print "** index-zone aktualisiert \n"; |
329 } |
323 } |
330 |
324 |
331 sub file_entry { |
325 sub file_entry { |
332 |
326 |
333 # prueft jede domain, die ein verzeichnis in $master_dir hat, ob sie |
327 # prueft jede domain, die ein verzeichnis in $config{master_dir} hat, ob sie |
334 # dnssec nutzt. |
328 # dnssec nutzt. |
335 # passt die eintraege in $config_file falls noetig an. |
329 # passt die eintraege in $config_file falls noetig an. |
336 our $master_dir; |
|
337 our $conf_dir; |
330 our $conf_dir; |
338 |
331 |
339 while (<$master_dir/*>) { |
332 while (glob "$config{master_dir}/*") { |
340 s#($master_dir/)(.*)#$2#; |
333 s#($config{master_dir}/)(.*)#$2#; |
341 my $zone = $_; |
334 my $zone = $_; |
342 my $zone_file = "$master_dir/$zone/$zone"; |
335 my $zone_file = "$config{master_dir}/$zone/$zone"; |
343 my $conf_file = "$conf_dir/$zone"; |
336 my $conf_file = "$conf_dir/$zone"; |
344 my @c_content; |
337 my @c_content; |
345 |
338 |
346 unless (-f "$conf_file") { |
339 unless (-f "$conf_file") { |
347 die "$conf_file: $! \n"; |
340 die "$conf_file: $! \n"; |
348 } |
341 } |
349 |
342 |
350 if (-e "$master_dir/$zone/.keycounter") { |
343 if (-e "$config{master_dir}/$zone/.keycounter") { |
351 open(FILE, "<$conf_file") or die "$conf_file: $!\n"; |
344 open(FILE, "<$conf_file") or die "$conf_file: $!\n"; |
352 @c_content = <FILE>; |
345 @c_content = <FILE>; |
353 close(FILE); |
346 close(FILE); |
354 for (@c_content) { |
347 for (@c_content) { |
355 if (m{(.*)($zone_file)(";)}) { |
348 if (m{(.*)($zone_file)(";)}) { |
404 close(KEY); |
396 close(KEY); |
405 |
397 |
406 # vergleicht den wert aus der keycount-datei mit dem wert aus der |
398 # vergleicht den wert aus der keycount-datei mit dem wert aus der |
407 #dnstools.conf (key_counter_end) |
399 #dnstools.conf (key_counter_end) |
408 if ($key_counter_end <= $key) { |
400 if ($key_counter_end <= $key) { |
409 $zone =~ s#($master_dir/)(.*)#$2#; |
401 $zone =~ s#($config{master_dir}/)(.*)#$2#; |
410 push @begin_ro_list, $zone; |
402 push @begin_ro_list, $zone; |
411 } |
403 } |
412 } |
404 } |
413 } |
405 } |
414 |
406 |
417 # funktion ueberprueft ob ein keyrollover fertig ist |
409 # funktion ueberprueft ob ein keyrollover fertig ist |
418 # die bedingung dafuer ist das: |
410 # die bedingung dafuer ist das: |
419 # - eine datei .index.zsk vorhanden ist |
411 # - eine datei .index.zsk vorhanden ist |
420 # - die datei .index.zsk vor mehr x stunden geaendert wurde |
412 # - die datei .index.zsk vor mehr x stunden geaendert wurde |
421 # - die datei .index.zsk ueber mehr als zwei zeilen gross ist |
413 # - die datei .index.zsk ueber mehr als zwei zeilen gross ist |
422 our $master_dir; |
|
423 our @end_ro_list; |
414 our @end_ro_list; |
424 our $ablauf_zeit; |
415 our $ablauf_zeit; |
425 chomp(my $now_time = `date +%s`); |
416 chomp(my $now_time = `date +%s`); |
426 |
417 |
427 for (<$master_dir/*>) { |
418 while (glob "$config{master_dir}/*") { |
428 my $zone = $_; |
419 my $zone = $_; |
429 $zone =~ s#($master_dir/)(.*)#$2#; |
420 $zone =~ s#($config{master_dir}/)(.*)#$2#; |
430 |
421 |
431 my @index = (); |
422 my @index = (); |
432 my $index_wc; |
423 my $index_wc; |
433 my @status; |
424 my @status; |
434 |
425 |
435 # prueft nach der ".index.zsk"-datei und erstellt den zeitpunkt |
426 # prueft nach der ".index.zsk"-datei und erstellt den zeitpunkt |
436 # an dem das key-rollover endet. - $status[9] |
427 # an dem das key-rollover endet. - $status[9] |
437 if (-e "$master_dir/$zone/.index.zsk") { |
428 if (-e "$config{master_dir}/$zone/.index.zsk") { |
438 @status = stat("$master_dir/$zone/.index.zsk"); |
429 @status = stat("$config{master_dir}/$zone/.index.zsk"); |
439 $status[9] += (3600 * $ablauf_zeit); |
430 $status[9] += (3600 * $ablauf_zeit); |
440 } |
431 } |
441 else { next; } |
432 else { next; } |
442 |
433 |
443 # $status[9] ist der zeitpunkt an dem der key-rollover endet |
434 # $status[9] ist der zeitpunkt an dem der key-rollover endet |
444 # prueft ob das key-rollover-ende erreicht ist |
435 # prueft ob das key-rollover-ende erreicht ist |
445 unless ($status[9] < $now_time) { next; } |
436 unless ($status[9] < $now_time) { next; } |
446 |
437 |
447 # prueft die anzahl der schluessel in der .index.zsk |
438 # prueft die anzahl der schluessel in der .index.zsk |
448 open(INDEX, "$master_dir/$zone/.index.zsk") |
439 open(INDEX, "$config{master_dir}/$zone/.index.zsk") |
449 or die "$master_dir/$zone/.index.zsk: $!\n"; |
440 or die "$config{master_dir}/$zone/.index.zsk: $!\n"; |
450 @index = <INDEX>; |
441 @index = <INDEX>; |
451 $index_wc = @index; |
442 $index_wc = @index; |
452 close(INDEX); |
443 close(INDEX); |
453 if ($index_wc > 1) { push @end_ro_list, $zone; } |
444 if ($index_wc > 1) { push @end_ro_list, $zone; } |
454 } |
445 } |
456 |
447 |
457 sub begin_ro { |
448 sub begin_ro { |
458 |
449 |
459 # anfang des key-rollovers |
450 # anfang des key-rollovers |
460 our @begin_ro_list; |
451 our @begin_ro_list; |
461 our $master_dir; |
|
462 our @new_serial; |
452 our @new_serial; |
463 |
453 |
464 for (uniq(@begin_ro_list)) { |
454 for (uniq(@begin_ro_list)) { |
465 |
455 |
466 #erzeugt zsks |
456 #erzeugt zsks |
467 my $zone = $_; |
457 my $zone = $_; |
468 my $zpf = "$master_dir/$zone"; |
458 my $zpf = "$config{master_dir}/$zone"; |
469 my @index; |
459 my @index; |
470 |
460 |
471 chdir "$zpf" or die "$zpf: $!\n"; |
461 chdir "$zpf" or die "$zpf: $!\n"; |
472 my $keyname = `dnssec-keygen -a RSASHA1 -b 512 -n ZONE $zone`; |
462 my $keyname = `dnssec-keygen -a RSASHA1 -b 512 -n ZONE $zone`; |
473 |
463 |
496 } |
486 } |
497 |
487 |
498 sub key_to_zonefile { |
488 sub key_to_zonefile { |
499 |
489 |
500 # die funktion fugt alle schluessel in eine zonedatei |
490 # die funktion fugt alle schluessel in eine zonedatei |
501 our $master_dir; |
|
502 my $zone = $_[0]; |
491 my $zone = $_[0]; |
503 my $zpf = "$master_dir/$zone"; |
492 my $zpf = "$config{master_dir}/$zone"; |
504 my @old_content; |
493 my @old_content; |
505 my @new_content = (); |
494 my @new_content = (); |
506 |
495 |
507 open(ZONEFILE, "<$zpf/$zone"); |
496 open(ZONEFILE, "<$zpf/$zone"); |
508 @old_content = <ZONEFILE>; |
497 @old_content = <ZONEFILE>; |
524 |
513 |
525 sub kill_useless_keys { |
514 sub kill_useless_keys { |
526 |
515 |
527 # die funktion loescht alle schluessel die nicht in der index.zsk |
516 # die funktion loescht alle schluessel die nicht in der index.zsk |
528 # der uebergebenen zone stehen |
517 # der uebergebenen zone stehen |
529 our $master_dir; |
|
530 my $zone = $_[0]; |
518 my $zone = $_[0]; |
531 my @keylist = (); |
519 my @keylist = (); |
532 my $zpf = "$master_dir/$zone"; |
520 my $zpf = "$config{master_dir}/$zone"; |
533 |
521 |
534 open(INDEX, "<$zpf/.index.zsk") or die "$zpf/.index.zsk: $!\n"; |
522 open(INDEX, "<$zpf/.index.zsk") or die "$zpf/.index.zsk: $!\n"; |
535 @keylist = <INDEX>; |
523 @keylist = <INDEX>; |
536 close(INDEX); |
524 close(INDEX); |
537 open(INDEX, "<$zpf/.index.ksk") or die "$zpf/.index.ksk: $!\n"; |
525 open(INDEX, "<$zpf/.index.ksk") or die "$zpf/.index.ksk: $!\n"; |
563 } |
551 } |
564 } |
552 } |
565 |
553 |
566 sub end_ro { |
554 sub end_ro { |
567 our @end_ro_list; |
555 our @end_ro_list; |
568 our $master_dir; |
|
569 our @new_serial; |
556 our @new_serial; |
570 my @content; |
557 my @content; |
571 |
558 |
572 for (@end_ro_list) { |
559 for (@end_ro_list) { |
573 my $zone = $_; |
560 my $zone = $_; |
574 my $count = 0; |
561 my $count = 0; |
575 my @content; |
562 my @content; |
576 my $last_key; |
563 my $last_key; |
577 |
564 |
578 open(INDEX, "<$master_dir/$zone/.index.zsk"); |
565 open(INDEX, "<$config{master_dir}/$zone/.index.zsk"); |
579 @content = <INDEX>; |
566 @content = <INDEX>; |
580 close(INDEX); |
567 close(INDEX); |
581 |
568 |
582 for (@content) { |
569 for (@content) { |
583 $count++; |
570 $count++; |
584 $last_key = $_; |
571 $last_key = $_; |
585 } |
572 } |
586 if ($count > 1) { |
573 if ($count > 1) { |
587 open(INDEX, ">$master_dir/$zone/.index.zsk"); |
574 open(INDEX, ">$config{master_dir}/$zone/.index.zsk"); |
588 print INDEX $last_key; |
575 print INDEX $last_key; |
589 close(INDEX); |
576 close(INDEX); |
590 } |
577 } |
591 &kill_useless_keys($zone); |
578 &kill_useless_keys($zone); |
592 &key_to_zonefile($zone); |
579 &key_to_zonefile($zone); |