# HG changeset patch # User schlorke # Date 1040635086 0 # Node ID f1a025736621b6e8dc82e25c4a105c8925c85bbf # Parent 0c554cc52ba022e91f82e1be7a784c71146538a0 Initial revision diff -r 0c554cc52ba0 -r f1a025736621 master_watcher --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/master_watcher Mon Dec 23 09:18:06 2002 +0000 @@ -0,0 +1,160 @@ +#! /usr/bin/perl -w +my $USAGE = <<'#'; +Usage: $ME [options] + -l --logfile=s Name of the logfile we've to read [$opt_logfile] + -d --dir=s Where the named.conf's are expected [$opt_zonesdir] + -u --[no]update Update the "masters"-entries [$opt_update] + -c --[no]create Add newly appeared domains [$opt_create] + -f --[no]follow Follow the end of the logfile [$opt_follow] + -h --help This text [$opt_help] +# +# Es wird ein Verzeichnis geben, in diesem Verzeichnis liegt für +# *jede* Zone eine eigene Konfigurations-Datei. +# Diese ganzen Konfigurationsdateien werden dann zusammengefaßt +# und diese zusammengefaßte wird dem bind per "include" mitgeteilt. + +use strict; +use File::Basename; +use IO::Handle; +use File::Path; +use Getopt::Long; +use Unix::Syslog qw/:macros :subs/; + +my $ME = basename $0; + + +my %auth = ( + "212.172.233.34" => "pu.schlittermann.de", + "212.80.235.130" => "pu2.schlittermann.de", + "145.253.160.50" => "bastion.actech.de", + "212.172.233.146" => "ns.flaemingnet.de", + "212.172.127.34" => "mango.compot.com", + "62.144.175.34" => "ns.add-on.de", + "195.145.19.34" => "ns.datom.de", +); + +$SIG{__DIE__} = sub { syslog(LOG_ERR, $_[0]); exit -1; }; +$SIG{__WARN__} = sub { syslog(LOG_WARNING, $_[0]); }; + +my %seen; + +my $opt_help = 0; +my $opt_logfile = "./syslog"; +my $opt_zonesdir = "./zones"; +my $opt_follow = 0; +my $opt_create = 1; +my $opt_update = 1; + +my $naptime = 1; + + +sub updateFile($@); + + +MAIN: { + + + openlog($ME, LOG_PID | LOG_PERROR, LOG_DAEMON); + syslog(LOG_NOTICE, "starting"); + + GetOptions( + "help" => \$opt_help, + "logfile=s" => \$opt_logfile, + "follow!" => \$opt_follow, + "dir=s" => \$opt_zonesdir) + or die "$ME: Bad Usage\n"; + + if ($opt_help) { + print eval "\"$USAGE\""; + exit 0; + } + + open (LOGFILE, $_ = "<$opt_logfile") or die "Can't open $_: $!\n"; + for (;;) { + my (%masters, my %missing); + while () { + + my ($domain, $ip); + + # NOTIFY-Zeilen + ($domain, $ip) = /NOTIFY.*?\((\S+?),.*?\[([\d.]+)\]/ and do { + if (not exists $auth{$ip}) { + warn "notify for $domain from unauthorized ip $ip\n"; + next; + }; + $masters{$domain}->{$ip} = 1; + next; + }; + + # NOTIFY for vergessene + /NOTIFY for "(\S+?)".*not one of our zones/ and do { + if (not exists $masters{$1}) { + warn "skipping $1 (not authorized)\n"; + next; + } + $missing{$1} = 1; + }; + } + + # Jetzt sind wir erstmal durch und verarbeiten alles + + #foreach my $domain (sort keys %missing) { + #updateFile($domain, keys %{$masters{$domain}}); + #delete $masters{$domain}; + #delete $missing{$domain}; + #} + + foreach my $domain (sort keys %masters) { + updateFile($domain, keys %{$masters{$domain}}); + delete $masters{$domain}; + delete $missing{$domain} if exists $missing{$domain}; + } + + last if !$opt_follow; + sleep $naptime; + # seek(LOGFILE, 0, 1); + LOGFILE->clearerr(); + } +} + +sub updateFile($@) +{ + local $_; + my $domain = shift; + my $masters = join "; ", @_; + my $file = "$opt_zonesdir/$domain"; + + syslog(LOG_NOTICE, "Updating/Creating $file ($masters)\n"); + return; + + if (-f $file) { + open (IN, $_ = "<$file") or die "Can't open $_: $!\n"; + # ein etwas anderer Versuch - noch nicht fertig + $_ = join "", ; + close(IN); open(OUT, ">&STDOUT"); # Wenn's geht, dann in's File + s/(masters\s*{)(.*?)(};)/$1$2; $masters; $3/; + print OUT; + } + + else { + open(OUT, $_ = ">$file") or die "Can't open $_: $!\n"; + + print OUT <<_EOF_; +// Autogenerated +zone "$domain" { + type slave; + masters { $masters; }; + file "/etc/bind/slave/$domain"; + allow-query { any; }; + allow-transfer { none; }; + allow-update { none; }; +}; +_EOF_ + close OUT; + } + + return; +} + + +# vim:sts=4 sw=4 aw ai sm: