Advertisement
chatchai_j

reconf-exim4andbind

Dec 13th, 2012
131
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Perl 6.26 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 -q -A $ip";
  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.     chomp($ret);
  58.     return "$ip" eq "$ret";
  59. }
  60.  
  61. # Generate new named.conf.local file, and run "rndc reconfig"
  62. sub newBindConf() {
  63.     my $date = `date "+%Y-%m-%d %H:%M"`;
  64.     chomp($date);
  65.  
  66.     if (-f $namedconfnewfile ) { unlink $namedconfnewfile; }
  67.     die "Can't remove old '$namedconfnewfile', bail out!\n" if (-f $namedconfnewfile );
  68.  
  69.     my $zonecount = 0;
  70.     open OUTPUT, "> $namedconfnewfile" or die "Can't create '$namedconfnewfile' : $!\n";
  71.     for my $zone (keys %zonelist) {
  72.         my $ip = $zonelist{$zone}->{'ip'};
  73.         $zonecount ++;
  74.         print OUTPUT << "EOT";
  75. zone "$zone" { type forward; forward only; forwarders { $ip; }; };
  76. EOT
  77.     }
  78.     close OUTPUT;
  79.  
  80.     $date =~ s/[-: ]//g;
  81.  
  82.     # New named.conf.local file
  83.     rename $namedconflocal, "${namedconflocal}-${date}"
  84.         or die "Can't backup original $namedconflocal file\n";
  85.     rename $namedconfnewfile, $namedconflocal
  86.         or die "Can't rename new $namedconflocal file\n";
  87.     system("rndc reconfig");
  88.     &logappend("Generate new Bind config with $zonecount zones ...");
  89. }
  90.  
  91. # Generate new update-exim4.conf.conf file, and run "service exim4 reload"
  92. sub newExim4Conf() {
  93.     my $date = `date "+%Y-%m-%d %H:%M"`;
  94.     chomp($date);
  95.  
  96.     if (-f $exim4confnewfile ) { unlink $exim4confnewfile; }
  97.     die "Can't remove old '$exim4confnewfile', bail out!\n" if (-f $exim4confnewfile );
  98.  
  99.     my $newrelaydomains = "";
  100.     my $zonecount = 0;
  101.     for my $zone (keys %zonelist) {
  102.         $newrelaydomains .= "$zone;";
  103.         $zonecount ++;
  104.     }
  105.     chop($newrelaydomains); # get rid of the last ';'
  106.     $date =~ s/[-: ]//g;
  107.  
  108.     # New update-exim4.conf.conf file
  109.     open CONF, "$exim4updateconf" or die "Can't open $exim4updateconf file : $!\n";
  110.     open OUTPUT, "> $exim4confnewfile" or die "Can't create $exim4confnewfile : $!\n";
  111.     while (<CONF>) {
  112.         if (!/^dc_relay_domains/) {
  113.             print OUTPUT $_;
  114.             next;
  115.         }
  116.         print OUTPUT "dc_relay_domains='$newrelaydomains'\n";
  117.     }
  118.     close OUTPUT;
  119.     close CONF;
  120.  
  121.     rename $exim4updateconf, "${exim4updateconf}-${date}"
  122.         or die "Can't backup original $exim4updateconf file\n";
  123.     rename $exim4confnewfile, $exim4updateconf
  124.         or die "Can't rename new $exim4updateconf file\n";
  125.     system("sudo service exim4 reload");
  126.     &logappend("Generate new Exim4 config with $zonecount zones ...");
  127. }
  128.  
  129. # Timeout Check for zonelist
  130. sub timeoutCheck() {
  131.     my $now = time();
  132.     my %newzonelist = ();
  133.     my $ret = 0;
  134.     for my $zone (keys %zonelist) {
  135.         my $ip = $zonelist{$zone}->{'ip'};
  136.         my $t = $zonelist{$zone}->{'time'};
  137.         if (&isAlive($ip)) {
  138.             $newzonelist{$zone}->{'ip'} = $ip;
  139.             $newzonelist{$zone}->{'time'} = $now;
  140.             $ret = 1;
  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.     while (my $line = <INPUT>) {
  164.         chomp($line);
  165.         next unless $line =~ /received notify for zone/ ;
  166.         my ($tstamp,$ip,$zone) = ($line =~ /$MSTR/);
  167.  
  168.         if (!defined($tstamp) or !defined($ip) or !defined($zone)) {
  169.             &logappend("ERROR:[$line]");
  170.             next;
  171.         }
  172.  
  173.         if (defined($zonelist{$zone}->{'ip'}) and
  174.             ($zonelist{$zone}->{'ip'} eq "$ip")) {
  175.             $zonelist{$zone}->{'time'} = time();
  176.             next;
  177.         }
  178.  
  179.         $newzone++;
  180.         $zonelist{$zone}->{'ip'} = $ip;
  181.         $zonelist{$zone}->{'time'} = time();
  182.         &logappend("$tstamp $ip $zone");
  183.     }
  184.  
  185.     # Generate new config file only when there are new zone
  186.     if ($newzone) {
  187.         &newBindConf();
  188.         &newExim4Conf();
  189.     }
  190.  
  191.     $lastsize = (stat "$daemonlogfile")[7];
  192.     do {
  193.         sleep(10);
  194.  
  195.         if (&timeoutCheck()) {
  196.             &newBindConf();
  197.             &newExim4Conf();
  198.         }
  199.         $thissize = (stat "$daemonlogfile")[7];
  200.     } while ($lastsize == $thissize);
  201.  
  202.     if ($thissize < $lastsize) {
  203.         close INPUT;
  204.         open INPUT, "$daemonlogfile" or
  205.             die "Can't open '$daemonlogfile' : $!\n";
  206.         &logappend("[ --- Reopen new daemon.log file --- ]");
  207.     }
  208. }
  209. close INPUT;
  210.  
  211. # --------------------------------------------------------------------- #
  212. # end of file.                              #
  213. # --------------------------------------------------------------------- #
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement