# HG changeset patch # User heiko # Date 1133333720 0 # Node ID d1dd256c037abb765de8cf39aa8e4b1ceaaf4c28 # Parent 8f7ba479860c06f0099178f6cd56b869bdc9d9b8 So koennte das jetzt gehen diff -r 8f7ba479860c -r d1dd256c037a Makefile --- a/Makefile Mon Nov 28 13:11:11 2005 +0000 +++ b/Makefile Wed Nov 30 06:55:20 2005 +0000 @@ -8,9 +8,8 @@ rcdir = /etc/init.d/ -install: +stow: install -m 0755 -d $(sbindir) install -m 0755 -d $(rcdir) install -m 0755 $(SCRIPT) $(sbindir)/ - install -m 0755 $(RC) $(rcdir)/ stow -d /usr/local/stow -vR $(p) diff -r 8f7ba479860c -r d1dd256c037a dns-autoslave --- a/dns-autoslave Mon Nov 28 13:11:11 2005 +0000 +++ b/dns-autoslave Wed Nov 30 06:55:20 2005 +0000 @@ -8,24 +8,24 @@ use File::Basename; use Net::Pcap; use Net::DNS::Packet; +use Fcntl ":flock"; use AppConfig; # Es kommen Zeilen # add slave domain.com use constant ME => basename $0; -use constant CF_FILE => "/etc/".ME.".conf"; +use constant CF_FILE => "/etc/".ME."/".ME.".conf"; +use constant LIB_DIR => "/etc/".ME; use constant CONFIG => ( { CASE => 1 }, dev => { ARGS => "=s", DEFAULT => "eth0", ALIAS => "interface" }, filter => { ARGS => "=s", DEFAULT => "udp and src host (%accept) and dst port domain" }, accept => { ARGS => "=s" }, - - cmd => { ARGS => "=s", DEFAULT => "/usr/local/sbin/add-slave" }, + pid => { ARGS => "=s", DEFAULT => "/var/run/".ME.".pid" }, ); sub process($$$); -sub createZone($$$); openlog(ME, LOG_PERROR | LOG_NDELAY | LOG_PID, LOG_DAEMON); $SIG{__DIE__} = sub { die @_ if $^S; syslog(LOG_ERR, shift, @_); exit 1; }; @@ -43,6 +43,11 @@ s/%accept/join " or ", split " ", $Cf->accept/e; $Cf->filter($_); + require lib; + import lib LIB_DIR; + require "local.pm"; + + my $err; my ($net, $mask); my ($pcap, $filter); @@ -52,6 +57,31 @@ 0 == Net::Pcap::compile($pcap, \$filter, $Cf->filter, 1, $mask) or die $@; Net::Pcap::setfilter($pcap, $filter); + ## + my $pidfile = $Cf->pid; + my $pid; + open(PID, "+>>$pidfile") or die "Can't open $pidfile: $!\n"; + flock(PID, LOCK_EX) or die "Can't flock $pidfile: $!\n"; + seek(PID, 0, 0) or die "Can't seek $pidfile: $!\n"; + if (defined ($pid = )) { + chomp $pid; + die "Process $pid is running\n" if kill 0, $pid; + } + seek(PID, 0, 0); + truncate(PID, 0); + + $pid = fork; + die "Can't fork: $!\n" if not defined $pid; + + if ($pid) { + print PID "$pid\n"; + warn "Child pid: $pid\n"; + exit 0; + } + + $SIG{TERM} = sub { warn "Exit.\n"; exit 0; }; + close(STDIN); close(STDOUT); close(STDERR); close(PID); + $0 = ME." [capturing]"; Net::Pcap::loop($pcap, -1, \&process, undef); } @@ -104,16 +134,26 @@ next unless $q->qtype eq "SOA"; my $domain = $q->qname; - print "NOTIFY from $src about $domain"; + my $msg = "NOTIFY from $src about $domain:"; - print " OK\n" and next if exists $Seen{$domain}; - print " OK(new)\n" and next if -f $Cf->zones . "/$domain" and $Seen{$domain} = time; + if (exists $Seen{$domain} && (time - $Seen{$domain} < 60) ) { + warn "$msg OK(seen)\n"; + next; + } - print " Create....\n"; - $ENV{ZONE} = $domain; - $ENV{SOURCE} = $src; - $ENV{DATE} = scalar localtime; - system $Cf->cmd; + if ((new Net::DNS::Resolver (recurse => 0))->query($domain, "SOA")) { + $Seen{$domain} = time; + warn "$msg OK(soa checked)\n"; + next; + } + + if (local::addZone($domain, $src)) { + warn "$msg ADDED", $@ ? "($@)" : "", "\n"; + next; + } + + warn "ERROR ", $@ ? "($@)" : "", "\n"; + } } diff -r 8f7ba479860c -r d1dd256c037a dns-autoslave.conf.ex --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dns-autoslave.conf.ex Wed Nov 30 06:55:20 2005 +0000 @@ -0,0 +1,2 @@ +accept = 192.168.7.2 \ + 192.168.7.3 diff -r 8f7ba479860c -r d1dd256c037a local.pm.ex --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/local.pm.ex Wed Nov 30 06:55:20 2005 +0000 @@ -0,0 +1,58 @@ +# Example +# $Id$ +# $URL$ + +# remove the next line if you know, what you're doing +die "Sure? You should adapt this file to your needs!"; + +package local; + +# in: zone name +# src ip +# out: 0 failure ($@ contains message) +# !0 ok ($@ may contain message) +sub addZone($$) { + my ($zone, $src) = @_; + + my $txt = <<__; +// Autoadded %time by $0 +zone "$zone" IN { + type slave; + file "/var/cache/bind/slave/$zone"; + masters { %masters; }; + allow-query { any; }; + allow-transfer { none; }; +}; + +__ + + $txt =~ s/%time/scalar localtime/eg; + $txt =~ s/%masters/$src/g; + + if (-f ($_ = "/etc/bind/zones.auto/$zone")) { + $@ = "$_ already exists"; + return 0; + } + + open(OUT, $_ = ">$_") or die "Can't open $_: $!\n"; + print OUT $txt; + + open(OUT, $_ = ">>/etc/bind/zones.all") or die "Can't open $_: $!\n"; + print OUT $txt; + + close OUT; + + # return 0 == system("rndc reload"); + local @ARGV = qw(/var/run/bind/run/named.pid); + chomp($_ = <>); + warn "Sending HUP to $_\n"; + $@ = "Nameserver reloaded (HUP sent)"; + kill "HUP", $_ and return 1; + + $@ = "No process $_"; + return 0; +} + + +1; +# vim:sts=4 sw=4 aw ai sm: diff -r 8f7ba479860c -r d1dd256c037a rc.dns-autoslave --- a/rc.dns-autoslave Mon Nov 28 13:11:11 2005 +0000 +++ b/rc.dns-autoslave Wed Nov 30 06:55:20 2005 +0000 @@ -1,31 +1,29 @@ -#! /bin/bash +#! /bin/sh +# $Id$ +# $URL$ -DAEMON=/usr/local/sbin/master_watcher -PIDFILE=/var/run/master_watcher.pid +DAEMON=/usr/local/sbin/dns-autoslave +NAME=`basename $DAEMON` test -x $MASTER_WATCHER || exit 0 case $1 in start) - echo -n "Starting $DAEMON..." - start-stop-daemon --start --pid $PIDFILE --exec $DAEMON -- -f - echo " OK"; + start-stop-daemon -v --start --name $NAME --startas $DAEMON ;; stop) - echo -n "Stopping $DAEMON..." - start-stop-daemon --stop --pid $PIDFILE - echo " OK"; + start-stop-daemon -v --stop --retry 30 --name $NAME ;; - restart) echo -n "Restarting $DAEMON..." + restart) echo "Restarting $NAME..." $0 stop $0 start ;; *) - echo "Usage: /etc/init.d/$DAEMON {start|stop|restart}" >&2 + echo "Usage: $0 {start|stop|restart}" >&2 exit 1 ;; esac