sbin/dnssec-keytool
changeset 137 69856eb1e826
parent 131 d8fa60488868
child 142 ae564015b7b0
equal deleted inserted replaced
136:43e9d618af43 137:69856eb1e826
    13 
    13 
    14 my $ME = basename $0;
    14 my $ME = basename $0;
    15 
    15 
    16 sub rm_keys($@);
    16 sub rm_keys($@);
    17 sub check_zone($@);
    17 sub check_zone($@);
    18 sub create_ksk($@);
    18 sub create_key($@);
       
    19 sub create_ksk(@);
    19 sub create_zsk(@);
    20 sub create_zsk(@);
    20 sub post_create($@);
    21 sub post_create($@);
    21 
    22 
    22 my $CHARSET = "UTF-8";
    23 my $CHARSET = "UTF-8";
    23 my %cf;
    24 my %cf;
    63         push @zones, $zone;
    64         push @zones, $zone;
    64     }
    65     }
    65 
    66 
    66     given ($cmd) {
    67     given ($cmd) {
    67         when ("zsk")   { exit create_zsk(@zones) };
    68         when ("zsk")   { exit create_zsk(@zones) };
    68         #when ("ksk")   { return create_ksk(@zones) };
    69         when ("ksk")   { exit create_ksk(@zones) };
    69         #when ("check") { return check_zone(@zones) };
    70         #when ("check") { exit check_zone(@zones) };
    70         #when ("rm")    { return rm_keys(@zones) };
    71         #when ("rm")    { exit rm_keys(@zones) };
    71 	default		{ die "not implemented\n" };
    72 	default		{ die "not implemented\n" };
    72     };
    73     };
    73 }
    74 }
    74 
    75 
    75 sub rm_keys ($@) {
    76 sub rm_keys ($@) {
   118         rename($fh->filename => "$zpf/$zone")
   119         rename($fh->filename => "$zpf/$zone")
   119           or die "Can't rename " . $fh->filename . " to $zpf/$zone: $!\n";
   120           or die "Can't rename " . $fh->filename . " to $zpf/$zone: $!\n";
   120     }
   121     }
   121 }
   122 }
   122 
   123 
   123 sub create_ksk ($@) {
   124 sub create_key ($@) {
   124     my ($master_dir, @zone) = @_;
   125 
   125     my @index;
   126     my ($type, @zones) = @_;
   126     my $keyname;
   127     my $master_dir = "$cf{master_dir}";
   127 
   128 
   128     for (@zone) {
   129     my $args = {
   129         my $zone = $_;
   130 
   130         my $zpf  = "$master_dir/$zone";
   131         ksk => {
   131 
   132             cmd => 'cd %s && dnssec-keygen -a RSASHA1 -b 2048 -f KSK -n ZONE %s'
   132         $keyname =
   133         },
   133           `cd $zpf && dnssec-keygen -a RSASHA1 -b 2048 -f KSK -n ZONE $zone`;
   134         zsk => {
   134 
   135             cmd => 'cd %s && dnssec-keygen -a RSASHA1 -b 512 -n ZONE %s'
   135         unless (-f "$zpf/.index.ksk") { @index = (); }
   136         }
   136         else {
   137 
   137             open(INDEX, "$zpf/.index.ksk") or die "$zpf/.index.ksk: $!\n";
   138     };
   138             @index = <INDEX>;
   139 
   139             close(INDEX);
   140     die "Invalid type $type" unless defined $args->{$type};
   140         }
   141 
       
   142     for my $zone (@zones) {
       
   143 
       
   144         my (@index, $keyname, $idx);
       
   145         my $dir = "$master_dir/$zone";
       
   146         my $cmd = sprintf $args->{$type}->{cmd}, $dir, $zone;
       
   147 
       
   148         chomp($keyname = qx/$cmd/);
       
   149         die "Key generation failed! (output was: '$keyname')" unless $keyname =~ /^K\Q$zone\E\.?\+\d{3}\+\d{5}$/;
       
   150 
       
   151         open $idx, '+>>', "$dir/.index.$type" or die "Can't open $dir/.index.$type: $!\n";
       
   152         seek $idx, 0 ,0 or die "Cant' seek: $!";
       
   153         chomp (@index = <$idx>);
   141 
   154 
   142         push @index, $keyname;
   155         push @index, $keyname;
   143         if (@index > 2) { shift(@index); }
   156         # TODO: this should be part of the key removal procedure, no?
   144 
   157         # shift @index if @index > 2;
   145         {
   158 
   146             my $fh = File::Temp->new(DIR => "$zpf")
   159         seek $idx, 0 ,0 or die "Cant' seek: $!";
   147               or die "Can't create tmpdir: $!\n";
   160         truncate $idx, 0 or die "Can't truncate: $!";
   148             print $fh join "" => @index, "";
   161         print $idx join "\n" => @index, '';
   149             rename($fh->filename => "$zpf/.index.ksk")
   162         close $idx;
   150               or die "Can't rename "
   163 
   151               . $fh->filename
   164         say "$zone: new ", uc $type, " $keyname";
   152               . " to $zpf/.index.ksk: $!\n";
   165 
   153         }
   166         key_to_zonefile($keyname);
   154 
   167 
   155         chomp($keyname);
   168         if (lc $type eq 'zsk') {
   156         print " * $zone: new KSK $keyname\n";
   169             open my $kc, '>', "$dir/.keycounter" or die "Can't open $dir/.keycounter: $!\n";
   157         print "!! THE KSK must be published !! \n";
   170             print $kc "0\n";
   158 
   171             close $kc;
   159     }
   172         }
   160 }
   173 
   161 
   174     }
   162 sub create_zsk (@) {
   175 
   163     my @zones = @_;
   176 }
   164 
   177 
   165     my $keyname;
   178 sub create_ksk (@) { return create_key 'ksk', @_; }
   166 
   179 sub create_zsk (@) { return create_key 'zsk', @_; }
   167     foreach my $zone (@zones) {
       
   168         my $dir  = "$cf{master_dir}/$zone";
       
   169 
       
   170         chomp($keyname = `cd $dir && dnssec-keygen -a RSASHA1 -b 512 -n ZONE $zone`);
       
   171 
       
   172 	my @index;
       
   173 	open(my $idx, "+>>", "$dir/.index.zsk") or die "Can't open $dir/.index.zsk: $!\n";
       
   174 	seek($idx, 0, 0);
       
   175 	chomp(@index = <$idx>);
       
   176 
       
   177         push @index, $keyname;
       
   178 	shift @index if @index > 2;
       
   179 
       
   180 	truncate($idx, 0);
       
   181 	print $idx join "\n" => @index, "";
       
   182 	close($idx);
       
   183 
       
   184         say "$zone: new ZSK $keyname";
       
   185 
       
   186         open(my $kc, ">", "$dir/.keycounter") or die "$dir/.keycounter: $!\n";
       
   187         print $kc "0\n";
       
   188         close($kc);
       
   189     }
       
   190 }
       
   191 
   180 
   192 sub check_zone ($@) {
   181 sub check_zone ($@) {
   193     my ($master_dir, @zone) = @_;
   182     my ($master_dir, @zone) = @_;
   194 
   183 
   195     for (@zone) {
   184     for (@zone) {
   277             }
   266             }
   278         }
   267         }
   279     }
   268     }
   280 }
   269 }
   281 
   270 
   282 sub key_to_zonefile ($@) {
   271 sub key_to_zonefile (@) {
   283 
   272 
   284     # the function added all keys to the indexfile
   273     (my ($keyname) = @_);
   285     my $zone       = $_[0];
   274     $keyname =~ /^K(.*)\.\+\d{3}\+\d{5}$/;
   286     my $master_dir = $_[1];
   275     my $zone = $1 or die "Can't determine zone from key name '$keyname'\n";
   287     my $zpf        = "$master_dir/$zone";
   276     my $zf = "$cf{master_dir}/$zone/$zone";
   288     my @old_content;
   277     my (@lines, $tmp);
   289     my @new_content = ();
   278 
   290 
   279     open OLD, '<', $zf or die "Can't open $zf: $!\n";
   291     open(ZONEFILE, "<$zpf/$zone");
   280     chomp (@lines = <OLD>);
   292     @old_content = <ZONEFILE>;
   281     close OLD;
   293     close(ZONEFILE);
   282 
   294 
   283     return if grep /^\s*\$include\s+("?)\Q$keyname\E\.key\1$/i, @lines;
   295     for (@old_content) {
   284 
   296         unless (m#INCLUDE.*key#) { push @new_content, $_; }
   285     $tmp = File::Temp->new(UNLINK => 0) or die "Can't create temporary file\n";
   297     }
   286     print $tmp join "\n", @lines, qq(\$INCLUDE "$keyname.key"\n);
   298 
   287     close $tmp;
   299     for (<$zpf/*>) {
   288 
   300         if (m#(.*\/)(K.*\.key)#) {
   289     rename $tmp => $zf or die "Can't rename '$tmp' => '$zf': $!";
   301             push @new_content, "\$INCLUDE \"$2\"\n";
   290 
   302         }
       
   303     }
       
   304     open(ZONEFILE, ">$zpf/$zone") or die "$zpf/$zone: $!\n";
       
   305     print ZONEFILE @new_content;
       
   306     close(ZONEFILE);
       
   307 }
   291 }
   308 
   292 
   309 __END__
   293 __END__
   310 
   294 
   311 =pod
   295 =pod
   326 
   310 
   327 =over
   311 =over
   328 
   312 
   329 =item B<--zsk> 
   313 =item B<--zsk> 
   330 
   314 
   331 Create a new ZSK for the zones.
   315 Create a new ZSK for the zones and include the DNSKEY record for it in the respective zone.
   332 
   316 
   333 =item B<--ksk>
   317 =item B<--ksk>
   334 
   318 
   335 Create a new KSK for the zones.
   319 Create a new KSK for the zones and include the DNSKEY record for it in the respective zone.
   336 
   320 
   337 =item B<--rm>
   321 =item B<--rm>
   338 
   322 
   339 Remote all key material from the zones.
   323 Remote all key material from the zones.
   340 
   324