Advertisement
chatchai_j

reconf-exim4andbind

Dec 14th, 2012
147
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Perl 8.27 KB | None | 0 0
  1. #!/usr/bin/perl -w-
  2.  
  3. # --------------------------------------------------------------------- #
  4. # reconf-exim4andbind   - Modify named.conf.local and reconfig named    #
  5. #                         when necessary. This is intended to allow     #
  6. #                         lsa-svr to forward DNS request from outside   #
  7. #                         to students' VM, by monitoring update request #
  8. #                         that will generate 'no authoritative' message #
  9. #                         in daemon.log file.                           #
  10. #                       - Plus add exim4 relay_domains config.          #
  11. #                                                                       #
  12. ## version 0.1  - cj (2012-11-28) init.                                 #
  13. ## version 0.2  - cj (2012-12-02) modified form gen-lsa-namedconflocal  #
  14. ## version 0.2a - cj (2012-12-11) some cosmetic added.                  #
  15. # version 0.3   - cj (2012-12-13) change to reconf-exim4andbind         #
  16. # --------------------------------------------------------------------- #
  17.  
  18. use strict;
  19.  
  20. my $exim4updateconf = "/var/cache/exim4/update-exim4.conf.conf";
  21. my $namedconflocal = "/var/cache/bind/conf/named.conf.local";
  22. my $daemonlogfile = "/var/log/daemon.log";
  23. my $namedconfnewfile = "${namedconflocal}.new";
  24. my $exim4confnewfile = "${exim4updateconf}.new";
  25. my $logfile = "/var/log/named/reconf-dnsandmail.log";
  26.  
  27. my %zonelist = ();
  28. my %tm = ();            # last seen for that specific zone
  29. my $TOO_OLD = 600;      # Number of seconds since last seen
  30.  
  31. # Append log message to log file
  32. sub     logappend() {
  33.         my ($mesg) = @_;
  34.         my $DATE  = `date "+%Y%m%d %H:%M:%S"`; chomp($DATE);
  35.         open LOG, ">> $logfile" or die "Can't append to log file : $!\n";
  36.         print LOG "$DATE\t$mesg\n";
  37.         close LOG;
  38. }
  39.  
  40. # Check whether that provide IP is alive by using icmp 'ping' check
  41. sub     isAlive() {
  42.         my ($ip) = @_;
  43.  
  44.         # Make sure that the IP is defined and actual ip number
  45.         # before send it to fping command.
  46.         return 0 unless defined($ip);
  47.         return 0 unless $ip =~ /^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$/;
  48.         my $cmd = "fping -a $ip 2> /dev/null";
  49.  
  50.         # then do it.
  51.         open CMD, "$cmd |"
  52.                 or die "Can't execute command '$cmd'\n";
  53.         my $ret = <CMD>;
  54.         close CMD;
  55.  
  56.         # check the result.
  57.         return 0 unless defined($ret);
  58.         chomp($ret);
  59.         return "$ip" eq "$ret";
  60. }
  61.  
  62. # Generate new named.conf.local file, and run "rndc reconfig"
  63. sub     newBindConf() {
  64.         my $date = `date "+%Y-%m-%d %H:%M"`;
  65.         chomp($date);
  66.  
  67.         if (-f $namedconfnewfile ) { unlink $namedconfnewfile; }
  68.         die "Can't remove old '$namedconfnewfile', bail out!\n" if (-f $namedconfnewfile );
  69.  
  70.         my $zonecount = 0;
  71.         open OUTPUT, "> $namedconfnewfile" or die "Can't create '$namedconfnewfile' : $!\n";
  72.         for my $zone (keys %zonelist) {
  73.                 my $ip = $zonelist{$zone}->{'ip'};
  74.                 $zonecount ++;
  75.                 print OUTPUT << "EOT";
  76. zone "$zone" { type forward; forward only; forwarders { $ip; }; };
  77. EOT
  78.         }
  79.         close OUTPUT;
  80.  
  81.         $date =~ s/[-: ]//g;
  82.  
  83.         # New named.conf.local file
  84.         rename $namedconflocal, "${namedconflocal}-${date}"
  85.                 or die "Can't backup original $namedconflocal file\n";
  86.         rename $namedconfnewfile, $namedconflocal
  87.                 or die "Can't rename new $namedconflocal file\n";
  88.         system("rndc reconfig");
  89.         &logappend("Generate new Bind config with $zonecount zones ...");
  90. }
  91.  
  92. # Generate new update-exim4.conf.conf file, and run "service exim4 reload"
  93. sub     newExim4Conf() {
  94.         my $date = `date "+%Y-%m-%d %H:%M"`;
  95.         chomp($date);
  96.  
  97.         if (-f $exim4confnewfile ) { unlink $exim4confnewfile; }
  98.         die "Can't remove old '$exim4confnewfile', bail out!\n" if (-f $exim4confnewfile );
  99.  
  100.         my $newrelaydomains = "";
  101.         my $zonecount = 0;
  102.         for my $zone (keys %zonelist) {
  103.                 $newrelaydomains .= "$zone;";
  104.                 $zonecount ++;
  105.         }
  106.         chop($newrelaydomains); # get rid of the last ';'
  107.         $date =~ s/[-: ]//g;
  108.  
  109.         # New update-exim4.conf.conf file
  110.         open CONF, "$exim4updateconf" or die "Can't open $exim4updateconf file : $!\n";
  111.         open OUTPUT, "> $exim4confnewfile" or die "Can't create $exim4confnewfile : $!\n";
  112.         while (<CONF>) {
  113.                 if (!/^dc_relay_domains/) {
  114.                         print OUTPUT $_;
  115.                         next;
  116.                 }
  117.                 print OUTPUT "dc_relay_domains='$newrelaydomains'\n";
  118.         }
  119.         close OUTPUT;
  120.         close CONF;
  121.  
  122.         rename $exim4updateconf, "${exim4updateconf}-${date}"
  123.                 or die "Can't backup original $exim4updateconf file\n";
  124.         rename $exim4confnewfile, $exim4updateconf
  125.                 or die "Can't rename new $exim4updateconf file\n";
  126.         system("sudo service exim4 reload");
  127.         &logappend("Generate new Exim4 config with $zonecount zones ...");
  128. }
  129.  
  130. # Timeout Check for zonelist
  131. sub     timeoutCheck() {
  132.         my $now = time();
  133.         my %newzonelist = ();
  134.         my $ret = 0;
  135.         for my $zone (keys %zonelist) {
  136.                 my $ip = $zonelist{$zone}->{'ip'};
  137.                 my $t = $zonelist{$zone}->{'time'};
  138.                 if (&isAlive($ip)) {
  139.                         $newzonelist{$zone}->{'ip'} = $ip;
  140.                         $newzonelist{$zone}->{'time'} = $now;
  141.                 } elsif (($now - $t) < $TOO_OLD) {
  142.                         $newzonelist{$zone}->{'ip'} = $ip;
  143.                         $newzonelist{$zone}->{'time'} = $t;
  144.                 } else {
  145.                         $ret = 1;
  146.                 }
  147.         }
  148.         %zonelist = %newzonelist;
  149.  
  150.         return $ret;
  151. }
  152.  
  153. # Regular expression for match 'not authoriative' line.
  154. my $MSTR =      "(.{15}) lsa-svr named\[[0-9]+\]: " .
  155.                 "client ([\.0-9]+)#[0-9]+: received notify for zone " .
  156.                 "'([^']+)': not authoritative\$";
  157.  
  158. my ($lastsize, $thissize);
  159. open INPUT, "$daemonlogfile" or die "Can't open '$daemonlogfile' : $!\n";
  160. while (1) {
  161.         my $newzone = 0;
  162.         my $zonetimeout = 0;
  163.         my %tmpzonelist = ();
  164.  
  165.         while (my $line = <INPUT>) {
  166.                 chomp($line);
  167.                 next unless $line =~ /received notify for zone/ ;
  168.                 my ($tstamp,$ip,$zone) = ($line =~ /$MSTR/);
  169.  
  170.                 if (!defined($tstamp) or !defined($ip) or !defined($zone)) {
  171.                         &logappend("ERROR:[$line]");
  172.                         next;
  173.                 }
  174.  
  175.                 $tmpzonelist{$zone}->{'ip'} = $ip;
  176.                 &logappend("$tstamp $ip $zone");
  177.                 print "LOG: $tstamp $ip $zone\n";
  178.         }
  179.  
  180.         for my $zone (keys %tmpzonelist) {
  181.                 my $ip = $tmpzonelist{$zone}->{'ip'};
  182.                 if (&isAlive($ip)) {
  183.                         $newzone++;
  184.                         my $t = time();
  185.                         $zonelist{$zone}->{'ip'} = $ip;
  186.                         $zonelist{$zone}->{'time'} = $t;
  187.                         print "ZONE: $t $ip $zone\n";
  188.                 }
  189.         }
  190.  
  191.         $lastsize = (stat "$daemonlogfile")[7];
  192.         do {
  193.                 # Generate new config file only when there are new zones
  194.                 # or host for that zone is not active for sometimes.
  195.                 if (&timeoutCheck() or $newzone) {
  196.                         &newBindConf();
  197.                         &newExim4Conf();
  198.                         $newzone = 0;
  199.                 }
  200.                 sleep(10);
  201.                 $thissize = (stat "$daemonlogfile")[7];
  202.         } while ($lastsize == $thissize);
  203.  
  204.         if ($thissize < $lastsize) {
  205.                 close INPUT;
  206.                 open INPUT, "$daemonlogfile" or
  207.                         die "Can't open '$daemonlogfile' : $!\n";
  208.                 &logappend("[ --- Reopen new daemon.log file --- ]");
  209.                 print "LOG: --- new daemon.log ---\n";
  210.         }
  211. }
  212. close INPUT;
  213.  
  214. # --------------------------------------------------------------------- #
  215. # end of file.                                                          #
  216. # --------------------------------------------------------------------- #
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement