dnssec-keytool
changeset 38 d50f6874b7ab
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 sub read_conf {
       
    13     # liest die Konfiguration ein
       
    14     my @configs = ( "$FindBin::Bin/dnstools.conf", "/etc/dnstools.conf" );
       
    15     our %config;
       
    16 
       
    17     for ( grep {-f} @configs ) {
       
    18         open( CONFIG, $_ ) or die "Can't open $_: $!\n";
       
    19     }
       
    20     unless ( seek( CONFIG, 0, 0 ) ) {
       
    21         die "Can't open config (searched: @configs)\n";
       
    22     }
       
    23     while (<CONFIG>) {
       
    24         chomp;
       
    25         s/#.*//;
       
    26         s/\t//g;
       
    27         s/\s//g;
       
    28 
       
    29         next unless length;
       
    30         my ( $cname, $ccont ) = split( /\s*=\s*/, $_, 2 );
       
    31         $config{$cname} = $ccont;
       
    32     }
       
    33     close(CONFIG);
       
    34 }
       
    35 
       
    36 sub read_argv {
       
    37     # wertet argv aus oder gibt die hilfe aus
       
    38     my $arg = shift @ARGV;
       
    39     my $zone;
       
    40     our $do;
       
    41     our @zones;
       
    42     our $master_dir;
       
    43 
       
    44     if ( ! defined $arg ) {
       
    45         print " usage: dnssec-keytool <option> zone\n";
       
    46         print "   -z  erstellt einen neuen ZSK\n";
       
    47         print "   -k  erstellt je einen neuen ZSK und KSK\n";
       
    48         print "   -rm loescht das Schluesselmaterial einer Zone\n";
       
    49         print "   -c  erstellt bei existierenden ksk konfigurationsdateien\n";
       
    50         print "       fuer die dnstools, sowie einen neuen zsk\n";
       
    51         print "\n";
       
    52 
       
    53         exit;
       
    54     }
       
    55     elsif ($arg eq "-k")  {$do = "ksk";}
       
    56     elsif ($arg eq "-rm") {$do = "rm";}
       
    57     elsif ($arg eq "-c")  {$do = "ck";}
       
    58     elsif ($arg eq "-z") {$do = "zsk";}
       
    59     else {
       
    60         print "keine gueltige Option.\n";
       
    61         exit;
       
    62     }
       
    63 
       
    64     # prueft die zonen in argv ob es verwaltete zonen sind
       
    65     for (@ARGV) {
       
    66         chomp( $zone = `idn --quiet "$_"` );
       
    67         if ( -e "$master_dir/$zone/$zone" ) {
       
    68             push @zones, $zone;
       
    69         }
       
    70     }
       
    71 }
       
    72 
       
    73 sub rm_keys {
       
    74     our @zones;
       
    75     our $master_dir;
       
    76     my $zone;
       
    77     my @new_zone_content;
       
    78     my @old_zone_content;
       
    79 
       
    80     for (@zones) {
       
    81         $zone = $_;
       
    82 
       
    83         my $zpf = "$master_dir/$zone";
       
    84         my $ep = 0;
       
    85 
       
    86         if ( -e "$zpf/$zone.signed" )  { 
       
    87             unlink "$zpf/$zone.signed"  and $ep = 1 }
       
    88         if ( -e "$zpf/.keycounter" )   {
       
    89             unlink "$zpf/.keycounter"   and $ep = 1 }
       
    90         if ( -e "$zpf/.index.ksk" )    {
       
    91             unlink "$zpf/.index.ksk"    and $ep = 1 }
       
    92         if ( -e "$zpf/.index.zsk" )    {
       
    93             unlink "$zpf/.index.zsk"    and $ep = 1 }
       
    94         if ( -e "$zpf/dsset-$zone." )  { 
       
    95             unlink "$zpf/dsset-$zone."  and $ep = 1 }
       
    96         if ( -e "$zpf/keyset-$zone." ) { 
       
    97             unlink "$zpf/keyset-$zone." and $ep = 1 }
       
    98 
       
    99         for (`ls $zpf/K$zone*`) { 
       
   100             chomp($_);
       
   101             print "weg du scheissezwerg $_";
       
   102             unlink ("$_");
       
   103         }
       
   104 
       
   105         if ($ep == 1) {
       
   106             print " * $zone: schluesselmaterial entfernt\n";
       
   107         }
       
   108 
       
   109         open( ZONE, "$zpf/$zone" )
       
   110             or die "$zpf/$zone: $!\n";
       
   111         @old_zone_content = <ZONE>;
       
   112         close(ZONE);
       
   113         
       
   114         for (@old_zone_content) {
       
   115             unless (m#\$INCLUDE.*\"K$zone.*\.key\"#) {
       
   116                 push @new_zone_content, $_;
       
   117             }
       
   118         }
       
   119 
       
   120         open( ZONE, ">$zpf/$zone" ) or die "$zpf/$zone: $!\n";
       
   121         print ZONE @new_zone_content;
       
   122         close(ZONE);
       
   123     }
       
   124 }
       
   125 
       
   126 sub creat_ksk {
       
   127     our @zones;
       
   128     our $master_dir;
       
   129     my @index;
       
   130     my $zone;
       
   131     my $keyname;
       
   132     my $zpf;
       
   133 
       
   134     for (@zones) {
       
   135         $zone = $_;
       
   136         $zpf = "$master_dir/$zone";
       
   137 
       
   138         chdir "$zpf" or die "$zpf: $!\n";
       
   139         $keyname = `dnssec-keygen -a RSASHA1 -b 2048 -f KSK -n ZONE $zone`;
       
   140 
       
   141         unless ( -f ".index.ksk" ) { @index = ();}
       
   142         else {
       
   143             open( INDEX, ".index.ksk" ) or die "$zpf/.index.ksk: $!\n";
       
   144             @index = <INDEX>;
       
   145             close(INDEX);
       
   146         }
       
   147 
       
   148         push @index, $keyname;
       
   149         if ( @index > 2 ) { shift(@index);}
       
   150 
       
   151         open( INDEX, ">.index.ksk" ) or die "$zpf/.index.ksk: $!\n";
       
   152         print INDEX @index;
       
   153         close(INDEX);
       
   154 
       
   155         chomp($keyname);
       
   156         print " * $zone: neuer KSK $keyname\n";
       
   157         
       
   158 
       
   159         print "!! DER KSK muss der Chain of Trust veroeffentlicht werden !! \n";
       
   160 
       
   161     }
       
   162 }
       
   163 
       
   164 sub creat_zsk {
       
   165     our @zones;
       
   166     our $master_dir;
       
   167     my @index;
       
   168     my $zone;
       
   169     my $keyname;
       
   170     my $zpf;
       
   171 
       
   172     for (@zones) {
       
   173         $zone = $_;
       
   174         $zpf = "$master_dir/$zone";
       
   175 
       
   176         chdir "$zpf" or die "$zpf: $!\n";
       
   177         $keyname = `dnssec-keygen -a RSASHA1 -b 512 -n ZONE $zone`;
       
   178 
       
   179         unless ( -f ".index.zsk" ) { @index = ();}
       
   180         else {
       
   181             open( INDEX, ".index.zsk" ) or die "$zpf/.index.zsk: $!\n";
       
   182             @index = <INDEX>;
       
   183             close(INDEX);
       
   184         }
       
   185 
       
   186         push @index, $keyname;
       
   187         if ( @index > 2 ) { shift(@index);}
       
   188 
       
   189         open( INDEX, ">.index.zsk" ) or die "$zpf/.index.zsk: $!\n";
       
   190         print INDEX @index;
       
   191         close(INDEX);
       
   192 
       
   193         chomp($keyname);
       
   194         print " * $zone: neuer ZSK $keyname\n";
       
   195 
       
   196         open( KC, ">.keycounter" ) or die "$zpf/keycounter: $!\n";
       
   197         print KC "0";
       
   198         close(KC);
       
   199 
       
   200     }
       
   201 }
       
   202 
       
   203 sub ck_zone {
       
   204     our @zones;
       
   205     our $master_dir;
       
   206     my $zone;
       
   207 
       
   208     for (@zones) {
       
   209         $zone = $_;
       
   210         my $zpf = "$master_dir/$zone";
       
   211         my $keyfile;
       
   212         my @content;
       
   213         my @keylist;
       
   214 
       
   215         for (<$zpf/*>) {
       
   216             if (m#(K$zone.*\.key)#) {
       
   217                 $keyfile = $1;
       
   218                 open (KEYFILE, "<$zpf/$keyfile");
       
   219                 @content = <KEYFILE>;
       
   220                 close (KEYFILE);
       
   221                 for (@content) {
       
   222                     if (m#DNSKEY.257#) {
       
   223                         push @keylist, $keyfile;
       
   224                     }
       
   225                 }
       
   226             }
       
   227         }
       
   228 
       
   229         open( INDEX, ">.index.ksk" ) or die "$zpf/.index.ksk: $!\n";
       
   230         for (@keylist) {
       
   231             s#\.key##;
       
   232             print INDEX "$_\n";
       
   233         }
       
   234         close(INDEX);
       
   235         
       
   236         print " * $zone: neue .index.ksk erzeugt\n";
       
   237 
       
   238         if (-f "$zpf/.index.zsk") {
       
   239             unlink ("$zpf/.index.zsk") or die "$zpf/.index.zsk: $!\n";
       
   240         }
       
   241     }
       
   242 }
       
   243 
       
   244 sub post_creat {
       
   245     our @zones;
       
   246     our $master_dir;
       
   247 
       
   248     for (@zones) {
       
   249         my $zone = $_;
       
   250         `touch $master_dir/$zone/$zone`;
       
   251 
       
   252         &kill_useless_keys($zone);
       
   253         &key_to_zonefile($zone);
       
   254     }
       
   255 
       
   256 }
       
   257 
       
   258 sub kill_useless_keys {
       
   259     # die funktion loescht alle schluessel die nicht in der index.zsk
       
   260     # der uebergebenen zone stehen
       
   261     our $master_dir;
       
   262     my $zone     = $_[0];
       
   263     my @keylist  = ();
       
   264     my $zpf      = "$master_dir/$zone";
       
   265 
       
   266     open (INDEX, "<$zpf/.index.zsk") or die "$zpf/.index.zsk: $!\n";
       
   267     @keylist = <INDEX>;
       
   268     close(INDEX);
       
   269     open (INDEX, "<$zpf/.index.ksk") or die "$zpf/.index.ksk: $!\n";
       
   270     push @keylist, <INDEX>;
       
   271 
       
   272     # kuerzt die schluessel-bezeichnung aus der indexdatei auf die id um sie
       
   273     # besser vergleichen zu koennen.
       
   274     for ( @keylist ) {
       
   275         chomp;
       
   276         s#K.*\+.*\+(.*)#$1#;
       
   277     }
       
   278 
       
   279     # prueft alle schluesseldateien (ksk, zsk) ob sie in der jeweiligen
       
   280     # indexdatei beschrieben sind. wenn nicht werden sie geloescht.
       
   281     for (`ls $master_dir/$zone/K*[key,private]`) {
       
   282         chomp;
       
   283         my $file = $_;
       
   284         my $rm_count = 1;
       
   285         my $keyname;
       
   286         for (@keylist) {
       
   287             if ( $file =~ /$_/ ) { $rm_count = 0;}
       
   288         }
       
   289         if ($rm_count == 1) {
       
   290             unlink "$file";
       
   291             if ($file =~ /$zpf\/(.*\.key)/ ) {
       
   292                 print " * $zone: Schluessel $1 entfernt \n";
       
   293             }
       
   294         }
       
   295     }
       
   296 }
       
   297 
       
   298 sub key_to_zonefile {
       
   299     # die funktion fugt alle schluessel in eine zonedatei
       
   300     our $master_dir;
       
   301     my $zone = $_[0];
       
   302     my $zpf = "$master_dir/$zone";
       
   303     my @old_content;
       
   304     my @new_content = ();
       
   305 
       
   306     open(ZONEFILE, "<$zpf/$zone");
       
   307     @old_content = <ZONEFILE>;
       
   308     close(ZONEFILE);
       
   309 
       
   310     for (@old_content) {
       
   311         unless (m#INCLUDE.*key#) { push @new_content, $_; }
       
   312     }
       
   313 
       
   314     for (<$zpf/*>) {
       
   315         if (m#(.*\/)(K.*\.key)#) {
       
   316             push @new_content, "\$INCLUDE \"$2\"\n";
       
   317         }
       
   318     }
       
   319     open( ZONEFILE, ">$zpf/$zone" ) or die "$zpf/$zone: $!\n";
       
   320     print ZONEFILE @new_content;
       
   321     close(ZONEFILE);
       
   322 }
       
   323 
       
   324 
       
   325 &read_conf;
       
   326 
       
   327 our %config;
       
   328 our $do;     # arbeitsschritte aus argv
       
   329 our @zones;  # liste der zonen in argv
       
   330 our $master_dir      = $config{master_dir};
       
   331 our $bind_dir        = $config{bind_dir};
       
   332 our $conf_dir        = $config{zone_conf_dir};
       
   333 our $sign_alert_time = $config{sign_alert_time};
       
   334 our $indexzone       = $config{indexzone};
       
   335 our $key_counter_end = $config{key_counter_end};
       
   336 our $ablauf_zeit     = $config{abl_zeit};
       
   337 
       
   338 &read_argv;
       
   339 
       
   340 unless (@zones) {exit;} # beendet das programm, wurden keine
       
   341                         # gueltigen zonen uebergeben
       
   342 
       
   343 if ($do eq "rm") { &rm_keys; exit;}
       
   344 if ($do eq "ck") { &ck_zone;}
       
   345 if ($do eq "ksk") { &creat_ksk; }
       
   346 
       
   347 &creat_zsk;
       
   348 &post_creat;
       
   349 
       
   350