Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #!/usr/bin/perl -w-
- # --------------------------------------------------------------------- #
- # reconf-exim4andbind - Modify named.conf.local and reconfig named #
- # when necessary. This is intended to allow #
- # lsa-svr to forward DNS request from outside #
- # to students' VM, by monitoring update request #
- # that will generate 'no authoritative' message #
- # in daemon.log file. #
- # - Plus add exim4 relay_domains config. #
- # #
- ## version 0.1 - cj (2012-11-28) init. #
- ## version 0.2 - cj (2012-12-02) modified form gen-lsa-namedconflocal #
- ## version 0.2a - cj (2012-12-11) some cosmetic added. #
- # version 0.3 - cj (2012-12-13) change to reconf-exim4andbind #
- # --------------------------------------------------------------------- #
- use strict;
- my $exim4updateconf = "/var/cache/exim4/update-exim4.conf.conf";
- my $namedconflocal = "/var/cache/bind/conf/named.conf.local";
- my $daemonlogfile = "/var/log/daemon.log";
- my $namedconfnewfile = "${namedconflocal}.new";
- my $exim4confnewfile = "${exim4updateconf}.new";
- my $logfile = "/var/log/named/reconf-dnsandmail.log";
- my %zonelist = ();
- my %tm = (); # last seen for that specific zone
- my $TOO_OLD = 600; # Number of seconds since last seen
- # Append log message to log file
- sub logappend() {
- my ($mesg) = @_;
- my $DATE = `date "+%Y%m%d %H:%M:%S"`; chomp($DATE);
- open LOG, ">> $logfile" or die "Can't append to log file : $!\n";
- print LOG "$DATE\t$mesg\n";
- close LOG;
- }
- # Check whether that provide IP is alive by using icmp 'ping' check
- sub isAlive() {
- my ($ip) = @_;
- # Make sure that the IP is defined and actual ip number
- # before send it to fping command.
- return 0 unless defined($ip);
- return 0 unless $ip =~ /^[0-9]{1-3}\.[0-9]{1-3}\.[0-9]{1-3}\.[0-9]{1-3}$/;
- my $cmd = "fping -q -A $ip";
- # then do it.
- open CMD, "$cmd |"
- or die "Can't execute command '$cmd'\n";
- my $ret = <CMD>;
- close CMD;
- # check the result.
- chomp($ret);
- return "$ip" eq "$ret";
- }
- # Generate new named.conf.local file, and run "rndc reconfig"
- sub newBindConf() {
- my $date = `date "+%Y-%m-%d %H:%M"`;
- chomp($date);
- if (-f $namedconfnewfile ) { unlink $namedconfnewfile; }
- die "Can't remove old '$namedconfnewfile', bail out!\n" if (-f $namedconfnewfile );
- my $zonecount = 0;
- open OUTPUT, "> $namedconfnewfile" or die "Can't create '$namedconfnewfile' : $!\n";
- for my $zone (keys %zonelist) {
- my $ip = $zonelist{$zone}->{'ip'};
- $zonecount ++;
- print OUTPUT << "EOT";
- zone "$zone" { type forward; forward only; forwarders { $ip; }; };
- EOT
- }
- close OUTPUT;
- $date =~ s/[-: ]//g;
- # New named.conf.local file
- rename $namedconflocal, "${namedconflocal}-${date}"
- or die "Can't backup original $namedconflocal file\n";
- rename $namedconfnewfile, $namedconflocal
- or die "Can't rename new $namedconflocal file\n";
- system("rndc reconfig");
- &logappend("Generate new Bind config with $zonecount zones ...");
- }
- # Generate new update-exim4.conf.conf file, and run "service exim4 reload"
- sub newExim4Conf() {
- my $date = `date "+%Y-%m-%d %H:%M"`;
- chomp($date);
- if (-f $exim4confnewfile ) { unlink $exim4confnewfile; }
- die "Can't remove old '$exim4confnewfile', bail out!\n" if (-f $exim4confnewfile );
- my $newrelaydomains = "";
- my $zonecount = 0;
- for my $zone (keys %zonelist) {
- $newrelaydomains .= "$zone;";
- $zonecount ++;
- }
- chop($newrelaydomains); # get rid of the last ';'
- $date =~ s/[-: ]//g;
- # New update-exim4.conf.conf file
- open CONF, "$exim4updateconf" or die "Can't open $exim4updateconf file : $!\n";
- open OUTPUT, "> $exim4confnewfile" or die "Can't create $exim4confnewfile : $!\n";
- while (<CONF>) {
- if (!/^dc_relay_domains/) {
- print OUTPUT $_;
- next;
- }
- print OUTPUT "dc_relay_domains='$newrelaydomains'\n";
- }
- close OUTPUT;
- close CONF;
- rename $exim4updateconf, "${exim4updateconf}-${date}"
- or die "Can't backup original $exim4updateconf file\n";
- rename $exim4confnewfile, $exim4updateconf
- or die "Can't rename new $exim4updateconf file\n";
- system("sudo service exim4 reload");
- &logappend("Generate new Exim4 config with $zonecount zones ...");
- }
- # Timeout Check for zonelist
- sub timeoutCheck() {
- my $now = time();
- my %newzonelist = ();
- my $ret = 0;
- for my $zone (keys %zonelist) {
- my $ip = $zonelist{$zone}->{'ip'};
- my $t = $zonelist{$zone}->{'time'};
- if (&isAlive($ip)) {
- $newzonelist{$zone}->{'ip'} = $ip;
- $newzonelist{$zone}->{'time'} = $now;
- $ret = 1;
- } elsif (($now - $t) < $TOO_OLD) {
- $newzonelist{$zone}->{'ip'} = $ip;
- $newzonelist{$zone}->{'time'} = $t;
- } else {
- $ret = 1;
- }
- }
- %zonelist = %newzonelist;
- return $ret;
- }
- # Regular expression for match 'not authoriative' line.
- my $MSTR = "(.{15}) lsa-svr named\[[0-9]+\]: " .
- "client ([\.0-9]+)#[0-9]+: received notify for zone " .
- "'([^']+)': not authoritative\$";
- my ($lastsize, $thissize);
- open INPUT, "$daemonlogfile" or die "Can't open '$daemonlogfile' : $!\n";
- while (1) {
- my $newzone = 0;
- my $zonetimeout = 0;
- while (my $line = <INPUT>) {
- chomp($line);
- next unless $line =~ /received notify for zone/ ;
- my ($tstamp,$ip,$zone) = ($line =~ /$MSTR/);
- if (!defined($tstamp) or !defined($ip) or !defined($zone)) {
- &logappend("ERROR:[$line]");
- next;
- }
- if (defined($zonelist{$zone}->{'ip'}) and
- ($zonelist{$zone}->{'ip'} eq "$ip")) {
- $zonelist{$zone}->{'time'} = time();
- next;
- }
- $newzone++;
- $zonelist{$zone}->{'ip'} = $ip;
- $zonelist{$zone}->{'time'} = time();
- &logappend("$tstamp $ip $zone");
- }
- # Generate new config file only when there are new zone
- if ($newzone) {
- &newBindConf();
- &newExim4Conf();
- }
- $lastsize = (stat "$daemonlogfile")[7];
- do {
- sleep(10);
- if (&timeoutCheck()) {
- &newBindConf();
- &newExim4Conf();
- }
- $thissize = (stat "$daemonlogfile")[7];
- } while ($lastsize == $thissize);
- if ($thissize < $lastsize) {
- close INPUT;
- open INPUT, "$daemonlogfile" or
- die "Can't open '$daemonlogfile' : $!\n";
- &logappend("[ --- Reopen new daemon.log file --- ]");
- }
- }
- close INPUT;
- # --------------------------------------------------------------------- #
- # end of file. #
- # --------------------------------------------------------------------- #
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement