bin/dns-vi
changeset 25 50fbb0fb1120
parent 23 6ea7152f33a7
equal deleted inserted replaced
24:6d79c81a2931 25:50fbb0fb1120
       
     1 #! /usr/bin/perl
       
     2 #line 3
       
     3 use 5.010;
       
     4 use strict;
       
     5 use warnings;
       
     6 use if $ENV{DEBUG} // '' eq 'dns-vi' => 'Smart::Comments';
       
     7 use Getopt::Long;
       
     8 use Pod::Usage;
       
     9 use File::Copy;
       
    10 
       
    11 #use blib;
       
    12 use DNS::Vi;
       
    13 
       
    14 sub slurp {
       
    15     local $/ = undef;
       
    16     local @ARGV = @_;
       
    17     <>;
       
    18 }
       
    19 
       
    20 sub main {
       
    21     my %o = (
       
    22         local  => undef,
       
    23         key    => undef,
       
    24         server => undef,
       
    25         debug  => undef,
       
    26         editor => $ENV{EDITOR} // 'vi',
       
    27         skip => [qw/NS RRSIG NSEC3 NSEC3PARAM NSEC DNSKEY TSIG/],
       
    28     );
       
    29 
       
    30     GetOptions(
       
    31         'k|key=s'    => \$o{key},
       
    32         's|server=s' => \$o{server},
       
    33         'd|debug!'   => \$o{debug},
       
    34         'l|local!'   => \$o{local},
       
    35         'editor=s'   => \$o{editor},
       
    36       )
       
    37       && @ARGV >= 1
       
    38       or pod2usage();
       
    39 
       
    40     my $zone = shift @ARGV;
       
    41 
       
    42     $o{server} =
       
    43       $o{local} ? 'localhost' : (split ' ', `dig +short soa $zone`)[0]
       
    44       if not defined $o{server};
       
    45 
       
    46     my @dig = (
       
    47         dig => 'AXFR',
       
    48         defined $o{key} ? (-k => $o{key}) : (),
       
    49         defined $o{server} ? ("\@$o{server}") : (),
       
    50         $zone
       
    51     );
       
    52 
       
    53     my @zone1 = parse($_ = `@dig`, { -skip => $o{skip} } )
       
    54       or die "Empty zone\n";
       
    55     my $fh2;
       
    56     my @zone2 = do {
       
    57 	if (my $file = shift @ARGV) {
       
    58 	    parse(slurp($file), { -skip => $o{skip} });
       
    59 	} 
       
    60 	else {
       
    61 	    edit(@zone1, { -skip => $o{skip}, -editor => $o{editor}, -backup => \$fh2 });
       
    62 	}
       
    63     };
       
    64     ### @zone2
       
    65 
       
    66     my ($add, $del) = delta(\@zone1, \@zone2);
       
    67     if ((@$add + @$del) == 0) {
       
    68 	    say 'nothing changed';
       
    69 	    return 0;
       
    70     }
       
    71 
       
    72     say 'The following changes need your confirmation.';
       
    73     say join "\n", show($add, $del);
       
    74     print 'confirm (yes|NO): ';
       
    75     return 1 if <STDIN> !~ /^y/i;
       
    76 
       
    77     update(\@zone1, $add, $del, {
       
    78 	-server => $o{server},
       
    79 	-local => $o{local},
       
    80 	-debug => $o{debug},
       
    81 	-key => $o{key}})
       
    82     or do { 
       
    83 	copy($fh2->filename, ",dns-vi-$$")
       
    84 	and say "Saved as ',dns-vi-$$'"
       
    85 	    if $fh2;
       
    86     };
       
    87 
       
    88     return 0;
       
    89 }
       
    90 
       
    91 exit main(@ARGV) if not caller;
       
    92 
       
    93 __END__
       
    94 
       
    95 =head1 NAME
       
    96 
       
    97  dns-vi -- editor for dynamically maintained zones
       
    98 
       
    99 =head1 SYNOPSIS
       
   100 
       
   101  dns-vi [[-l] | [[-k key] [-s server]]] [-d] <zone> [<file>]
       
   102 
       
   103 =head1 DESCRIPTION
       
   104 
       
   105 This tools supports you in maintaining a dynamic zone. Normally you'll
       
   106 use it with the name of zone. For batch mode you may use it with an
       
   107 additional parameter, die edited zone file.
       
   108 
       
   109 =head2 OPTIONS
       
   110 
       
   111 =over
       
   112 
       
   113 =item B<-l>|B<--local> 
       
   114 
       
   115 Local mode, when running on the server where the updates need to go to.
       
   116 But still zone transfers need to be enabled! (default: off)
       
   117 
       
   118 =item B<-s>|B<--server> B<server-name>
       
   119 
       
   120 The name of the server to contact for the AXFR and the update.
       
   121 (default: main nameserver from the SOA record)
       
   122 
       
   123 =item B<-k>|B<--key> B<key-file>
       
   124 
       
   125 The name of the key file we need for TSIG (the AXFR will use it,
       
   126 as well as the update).
       
   127 
       
   128 To create such a key you may use 
       
   129 
       
   130     dnssec-keygen -a HMAC-MD5 -b 512 -n USER heiko
       
   131 
       
   132 Then copy the resulting files somewhere (you'll need both files).
       
   133 On the server side include the key into to configuration:
       
   134 
       
   135     key "<name>" {
       
   136 	algorithm   HMAC-MD5;
       
   137 	secret	    "<the secret from the created key file>"
       
   138     };
       
   139 
       
   140 Per zone you should use 
       
   141 
       
   142     zone "<zone>" {
       
   143 	...
       
   144 	update-policy {
       
   145 	    grant local-ddns zonesub any;   // support for -l
       
   146 	    grant <key-name> zonesub;	    // support for -k
       
   147 	};
       
   148 	...
       
   149     };
       
   150 
       
   151 =item B<-d>
       
   152 
       
   153 This option enables debugging of C<nsupdate>. (default: off)
       
   154 
       
   155 =back
       
   156 
       
   157 =head1 PREREQUISITES
       
   158 
       
   159 We need some tools to be installed:
       
   160 
       
   161 =over
       
   162 
       
   163 =item B<dig>
       
   164 
       
   165 The domain information grabber is used for the zone transfer currently.
       
   166 
       
   167 =item B<nsupdate>
       
   168 
       
   169 The nsupdate tool is used to send the updates back to the server.
       
   170 
       
   171 =back
       
   172 
       
   173 =cut