dnssec-creatkey
changeset 38 d50f6874b7ab
parent 37 d3158de72598
child 39 8b46e7c48995
child 43 7e472c559b36
child 45 5dc44dc86f61
equal deleted inserted replaced
37:d3158de72598 38:d50f6874b7ab
     1 #!/usr/bin/perl -w
       
     2 
       
     3 use strict;
       
     4 use FindBin;
       
     5 
       
     6 sub del_double {
       
     7     my %all;
       
     8     grep { $all{$_} = 0 } @_;
       
     9     return ( keys %all );
       
    10 }
       
    11 
       
    12 # liest die Konfiguration
       
    13 my @configs = ( "$FindBin::Bin/dnstools.conf", "/etc/dnstools.conf" );
       
    14 my %config;
       
    15 
       
    16 for ( grep {-f} @configs ) {
       
    17     open( CONFIG, $_ ) or die "Can't open $_: $!\n";
       
    18 }
       
    19 
       
    20 unless ( seek( CONFIG, 0, 0 ) ) {
       
    21     die "Can't open config (searched: @configs)\n";
       
    22 }
       
    23 
       
    24 while (<CONFIG>) {
       
    25     chomp;
       
    26     s/#.*//;
       
    27     s/\t//g;
       
    28     s/\s//g;
       
    29 
       
    30     next unless length;
       
    31     my ( $cname, $ccont ) = split( /\s*=\s*/, $_, 2 );
       
    32     $config{$cname} = $ccont;
       
    33 }
       
    34 close(CONFIG);
       
    35 
       
    36 my $master_dir      = $config{master_dir};
       
    37 my $key_counter_end = $config{key_counter_end};
       
    38 my @change;
       
    39 my @manu;
       
    40 my @index;
       
    41 my $zone;
       
    42 my $keyname;
       
    43 
       
    44 # prueft ob eingaben in ARGV domains sind und gibt sie in die liste @manu
       
    45 for (@ARGV) {
       
    46     chomp( my $zone = `idn --quiet "$_"` );
       
    47 
       
    48     if ( -d "$master_dir/$zone" ) {
       
    49         push( @manu, $zone );
       
    50     }
       
    51     else {
       
    52         print " $zone not exist\n ";
       
    53     }
       
    54 }
       
    55 
       
    56 # prueft ob zonen mit schluesselmaterial ueber index- und keycounterdatei
       
    57 # verfuegen.
       
    58 # legt .index.ksk an falls nicht und gibt die entsprechende zone in die
       
    59 # liste @change
       
    60 while (<$master_dir/*>) {
       
    61     chomp( $zone = $_ );
       
    62 
       
    63     if (    -f "$zone/.index.zsk"
       
    64         and -f "$zone/.index.ksk"
       
    65         and -f "$zone/.keycounter" )
       
    66     {
       
    67         next;
       
    68     }
       
    69 
       
    70     while (<$zone/*>) {
       
    71         if (m#^K#) {
       
    72             my $file_in_zone = $_;
       
    73 
       
    74             open( KEY, $_ ) or die "$_: $!\n";
       
    75             for (<KEY>) {
       
    76                 if (m#DNSKEY.257#) {
       
    77                     $file_in_zone =~ s#(/.*/)(.*).key#$2#;
       
    78 
       
    79                     open( INDEX, ">$zone/.index.ksk" ) or die;
       
    80                     print INDEX "$file_in_zone\n";
       
    81                     close(INDEX);
       
    82 
       
    83                     $zone =~ s#($master_dir/)(.*)#$2#;
       
    84                     push( @change, $zone );
       
    85 
       
    86                 }
       
    87             }
       
    88             close(KEY);
       
    89         }
       
    90     }
       
    91 }
       
    92 
       
    93 # gibt alle zonen mit abgelaufenen keycounter in die liste @change
       
    94 while (<$master_dir/*>) {
       
    95     chomp( $zone = $_ );
       
    96     my $key;
       
    97 
       
    98     unless ( -f "$zone/.keycounter" ) {
       
    99         next;
       
   100     }
       
   101 
       
   102     open( KEY, "$zone/.keycounter" ) or die "$zone/.keycounter: $!\n";
       
   103     $key = <KEY>;
       
   104     close(KEY);
       
   105 
       
   106     if ( $key_counter_end <= $key ) {
       
   107         $zone =~ s#($master_dir/)(.*)#$2#;
       
   108         push( @change, $zone );
       
   109     }
       
   110 }
       
   111 
       
   112 #erzeugt zsks
       
   113 for ( &del_double( @change, @manu ) ) {
       
   114     $zone = $_;
       
   115 
       
   116     chdir "$master_dir/$zone" or die "$master_dir/$zone: $!\n";
       
   117     $keyname = `dnssec-keygen -a RSASHA1 -b 512 -n ZONE $zone`;
       
   118 
       
   119     unless ( -f ".index.zsk" ) {
       
   120         @index = ();
       
   121     }
       
   122     else {
       
   123         open( INDEX, ".index.zsk" )
       
   124             or die "$master_dir/$zone/.index.zsk: $!\n";
       
   125         @index = <INDEX>;
       
   126         close(INDEX);
       
   127     }
       
   128 
       
   129     push @index, $keyname;
       
   130     if ( @index > 2 ) {
       
   131         shift(@index);
       
   132     }
       
   133 
       
   134     open( INDEX, ">.index.zsk" ) or die "$master_dir/$zone/.index.zsk: $!\n";
       
   135     print INDEX @index;
       
   136     close(INDEX);
       
   137 
       
   138     chomp($keyname);
       
   139     print "$keyname (ZSK) creat for $zone \n";
       
   140 
       
   141     open( KC, ">.keycounter" ) or die "$master_dir/$zone/keycounter: $!\n";
       
   142     print KC "0";
       
   143     close(KC);
       
   144 }
       
   145 
       
   146 #erzeugt ksks
       
   147 for ( &del_double(@manu) ) {
       
   148     $zone = $_;
       
   149 
       
   150     chdir "$master_dir/$zone" or die "$master_dir/$zone: $!\n";
       
   151     $keyname = `dnssec-keygen -a RSASHA1 -b 2048 -f KSK -n ZONE $zone`;
       
   152 
       
   153     print "creat new KSK for $zone? (no): ";
       
   154     unless ( <STDIN> =~ m/^yes/ ) {
       
   155         next;
       
   156     }
       
   157 
       
   158     unless ( -f ".index.ksk" ) {
       
   159         @index = ();
       
   160     }
       
   161     else {
       
   162 
       
   163         open( INDEX, ".index.ksk" )
       
   164             or die "$master_dir/$zone/.index.ksk: $!\n";
       
   165         @index = <INDEX>;
       
   166         close(INDEX);
       
   167     }
       
   168 
       
   169     push @index, $keyname;
       
   170     if ( @index > 2 ) {
       
   171         shift(@index);
       
   172     }
       
   173 
       
   174     open( INDEX, ">.index.ksk" ) or die "$master_dir/$zone/.index.ksk: $!\n";
       
   175     print INDEX @index;
       
   176     close(INDEX);
       
   177 
       
   178     chomp($keyname);
       
   179     print "$keyname (KSK) creat for $zone \n";
       
   180 }
       
   181 
       
   182 # loescht alle unbenoetigten schluessel, fuegt die schluessel in
       
   183 # die zone-datei
       
   184 for ( &del_double( @change, @manu ) ) {
       
   185     $zone = $_;
       
   186     my @old_zone_content = ();
       
   187     my @new_zone_content = ();
       
   188     my @kkeylist         = ();
       
   189     my @zkeylist         = ();
       
   190     my $file             = ();
       
   191 
       
   192     open( INDEX, "<$master_dir/$zone/.index.zsk" )
       
   193         or die "$master_dir/$zone/.index.zsk: $!\n";
       
   194     @zkeylist = <INDEX>;
       
   195     close(INDEX);
       
   196 
       
   197     open( INDEX, "<$master_dir/$zone/.index.ksk" )
       
   198         or die "$master_dir/$zone/.index.ksk: $!\n";
       
   199     @kkeylist = <INDEX>;
       
   200     close(INDEX);
       
   201 
       
   202     open( ZONE, "<$master_dir/$zone/$zone" )
       
   203         or die "$master_dir/$zone/$zone: $!\n";
       
   204     @old_zone_content = <ZONE>;
       
   205     close(ZONE);
       
   206 
       
   207     # kuerzt die schluessel-bezeichnung aus der indexdatei auf die id um sie
       
   208     # besser vergleichen zu koennen.
       
   209     for ( @kkeylist, @zkeylist ) {
       
   210         chomp;
       
   211         s#K.*\+.*\+(.*)#$1#;
       
   212     }
       
   213 
       
   214     # filtert alle schluessel aus der zonedatei
       
   215     # old_zone_content ==> new_zone_content
       
   216     for (@old_zone_content) {
       
   217         unless (/dnssec-(zsk|ksk)/) {
       
   218             push @new_zone_content, $_;
       
   219         }
       
   220     }
       
   221 
       
   222     # prueft alle schluesseldateien (ksk, zsk) ob sie in der jeweiligen
       
   223     # indexdatei beschrieben sind. wenn nicht werden sie geloescht.
       
   224     for (`ls $master_dir/$zone/K*[key,private]`) {
       
   225         chomp;
       
   226         $file = $_;
       
   227         my $rm_count = 1;
       
   228 
       
   229         for (@zkeylist) {
       
   230 
       
   231             if ( $file =~ /$_/ ) {
       
   232                 $rm_count = 0;
       
   233 
       
   234                 # schluessel die in der indexdatei standen, werden an die
       
   235                 # zonedatei angehangen.
       
   236                 if ( $file =~ /.*key/ ) {
       
   237 
       
   238                     $file =~ s#/.*/(K.*)#$1#;
       
   239                     push @new_zone_content,
       
   240                         "\$INCLUDE \"$file\"\t\t; dnssec-zsk\n";
       
   241 
       
   242                     last;
       
   243                 }
       
   244             }
       
   245         }
       
   246         for (@kkeylist) {
       
   247 
       
   248             if ( $file =~ /$_/ ) {
       
   249                 $rm_count = 0;
       
   250 
       
   251                 # schluessel die in der indexdatei standen, werden an die
       
   252                 # zonedatei angehangen.
       
   253                 if ( $file =~ /.*key/ ) {
       
   254 
       
   255                     $file =~ s#/.*/(K.*)#$1#;
       
   256                     push @new_zone_content,
       
   257                         "\$INCLUDE \"$file\"\t\t; dnssec-ksk\n";
       
   258 
       
   259                     last;
       
   260                 }
       
   261             }
       
   262         }
       
   263 
       
   264         #loescht alle unbenoetigten schluessel
       
   265         if ( $rm_count == 1 ) {
       
   266             unlink "$file";
       
   267         }
       
   268     }
       
   269 
       
   270     open( ZONE, ">$master_dir/$zone/$zone" )
       
   271         or die "$master_dir/$zone/$zone: $!\n";
       
   272     print ZONE @new_zone_content;
       
   273     close(ZONE);
       
   274 
       
   275 }
       
   276 
       
   277 # "toucht" alle zonen damit der serial erhoeht und die
       
   278 # zone neu signiert wird
       
   279 for ( &del_double( @change, @manu ) ) {
       
   280 	system "touch $master_dir/$_/$_";
       
   281 }