Может у меня со скриптом не так, что-то?
Из всех решений найденных в гугле по автоматической синхронизации зон, это самое простое и удобное.
#!/usr/bin/perl -w
#Created by stimpack <
alexey.kerdivare@gmail.com>
#at 2010/02/19
use strict;
use POSIX 'setsid';
use English;
$PROGRAM_NAME='zoneadd';
my %cfg=(notifylog=>'/var/named/var/log/bind/notify.log',
'named.conf'=>'/var/named/var/log/bind/named.conf',
restart_cmd=>'/etc/rc.d/named restart',
mail_cmd=>'echo "%zone created by %server at %time" |mail -s "%zone created by %server at %time"
root@bzpz.ru',
failed_mail_cmd=>'echo "ALARM: DNS server NOT RESTARTED" |mail -s "ALARM: DNS server NOT RESTARTED"
root@bzpz.ru',
interval=>10,
daemon=>1,
allowed=>['192.168.2.254'],
keynames=>{
'192.168.2.254'=>'key-sync',
},pattern=>"//added: %time\n"
."zone \"\%zone\" {\n"
."\ttype slave;\n"
."\tfile \"/etc/namedb/slave/\%zone\";\n"
."\tmasters { \%server; };\n"
."\tallow-query { localhost; 0.0.0.0/0; };\n"
."\tallow-notify { \%server; };\n"
."\tallow-transfer { \%server; };\n};\n");
#use Data::Dumper;print Dumper(\%cfg);exit;
#Daemon part
if ( $cfg{'daemon'} ) {
open(STDIN,'</dev/null');
open(STDOUT,'>/dev/null');
open(STDERR, '>&STDOUT');
defined( my $pid = fork) or die('Error: Can\'t fork '.$!);
exit if $pid;
setsid or die('Error: Can\'t start new session!');
umask 0;
chdir('/');
$PROGRAM_NAME='zoneadd';
}
open ZONES, $cfg{'named.conf'} or die $cfg{'named.conf'}." ".$!;
while (<ZONES>) {
if ( /^zone\s+"([\w\.]+)"\s+{/ ) {
push @{$cfg{'zones'}}, $1;
}
}
close ZONES;
#Main cycle
my $exit;
$cfg{'notifylog_size'}= -s $cfg{'notifylog'} or die "Empty or nonexistent notify log!\n";
while ( ! defined($exit) ) {
sleep int($cfg{'interval'});
if ( -s $cfg{'notifylog'} > $cfg{'notifylog_size'}) {
processing_log() or $exit=1;
}
}
##########################
#Functions
##########################
sub processing_log{
my ($log,$server,$domain,$keyname);
my @notifies;
#Parse log
open LOG, $cfg{'notifylog'} or die $cfg{'notifylog'}." ".$!;
while (<LOG>) {
$log.=$_;
if ( /notify: notice: client ([\d\:\.]+)#\d+: received notify for zone '([-\w\.]+)': TSIG '([\w\.]+)': not authoritative/ ) {
($server,$domain,$keyname)=($1,$2,$3);
foreach ( @{$cfg{'allowed'}}) {
if ( $_ eq $server and $cfg{'keynames'}->{$server} eq $keyname ) {
push @notifies, {server=>$server,domain=>$domain};
}
}
}
}
#Clean log and move processed data to other log
close LOG;
open LOG, '>',$cfg{'notifylog'} or die $cfg{'notifylog'}." ".$!;
print LOG "cleaned by ".$PROGRAM_NAME."\n";
close LOG;
open LOG, '>>',$cfg{'notifylog'}.'.'.$PROGRAM_NAME or die $cfg{'notifylog'}.'.'.$PROGRAM_NAME." ".$!;
print LOG $log;
close LOG;
$cfg{'notifylog_size'}= -s $cfg{'notifylog'} or die "Empty or nonexistent notify log!\n";
#Create backup
if ( scalar(@notifies) ) {my $config;
open ZONES, $cfg{'named.conf'} or die $cfg{'named.conf'}." ".$!;
while (<ZONES>) { $config.=$_;}
close ZONES;
open ZONES, '>',$cfg{'named.conf'}.'.'.time or die $cfg{'named.conf'}.'.'.time." ".$!;
print ZONES $config;
close ZONES;
}
#Parse notifies
my $restart=0;
foreach my $notify ( @notifies ) {
#Check for already registered
my $found=0;
foreach ( @{$cfg{'zones'}}) {
if ( lc($_) eq lc($notify->{'domain'}) ) { $found++;last;}
}
next if $found;
#Create addons/mail
my $time=scalar(localtime(time));
my ($zone,$mail)=($cfg{'pattern'},$cfg{'mail_cmd'});
$zone=~s/\%server/$notify->{'server'}/g;
$zone=~s/\%zone/$notify->{'domain'}/g;
$zone=~s/\%time/$time/g;
$mail=~s/\%server/$notify->{'server'}/g;
$mail=~s/\%zone/$notify->{'domain'}/g;
$mail=~s/\%time/$time/g;
#Append to main conf
open CONF, '>>'.$cfg{'named.conf'} or die $cfg{'named.conf'}." ".$!;
print CONF $zone;
close CONF;
#add to self array
push @{$cfg{'zones'}}, $notify->{'domain'};
#Admin notify
system($mail);
$restart++;
}
if ( $restart ) {
system($cfg{'restart_cmd'}) and system($cfg{'failed_mail_cmd'});
sleep 5;
$cfg{'notifylog_size'}= -s $cfg{'notifylog'} or die "Empty or nonexistent notify log!\n";
}
return 1;
}