четверг, 12 июля 2007 г.

Вариант скрипта переключения канала на резервный

Источник: http://www.opennet.ru/openforum/vsluhforumID1/74056.html

#!/usr/bin/perl

use File::Basename;
use Sys::Syslog qw(:DEFAULT setlogsock);
use Proc::Daemon;
use strict;
use warnings;

my $me = basename($0);
my $pidfile = "/var/run/$me.pid";
if ( -e $pidfile ) {
print "Script is runing! Exist $pidfile";
exit;
}

my $alert_email = "my\@my.ru";
my $from = "my\@my.ru";

my $check;

my $ext_gw_a = "x.x.x.x";
my $ext_gw_b = "y.y.y.y";

my $curent_gw = $ext_gw_a;

my $cmd_ping = "/sbin/ping -q -c 2";
my $cmd_mail="/usr/sbin/sendmail -t";

# mail.ru 194.67.57.26
# f.root-servers.net 192.5.5.241
# ya.ru 87.250.251.8
# rambler.ru 81.19.70.3
# google.com 64.233.167.99

my @targets = ('194.67.57.26','192.5.5.241','87.250.251.8','81.19.70.3','64.233.167.99');


sub ping {
my ($host) = @_;
my $ping_output = `$cmd_ping $host`;
if ($ping_output =~ /100\% packet loss/){
return 0;
} else {
return 1;
}
}

sub send_mail {
my ($subj) = @_;
open (SENDMAIL, "|$cmd_mail") || syslog('warning', "Can not run sendmail - %m");
print SENDMAIL "MIME-Version: 1.0\n";
print SENDMAIL "Content-Type: text/plain; charset=\"koi8-r\"\n";
print SENDMAIL "Content-Transfer-Encoding: 8bit\n";
print SENDMAIL "To: $alert_email\n";
print SENDMAIL "From: MONITORING $from\n";
print SENDMAIL "Subject: ALERT: $subj\n\n";
close (SENDMAIL);
}

sub change_dg {
my ($defg) = @_;
my $time = scalar localtime;
my $soobsh = "Switch $defg / $time";
my $cmd_netstat = '/usr/bin/netstat -nr |/usr/bin/grep default';
my $DGB=`$cmd_netstat`;
unless ($DGB =~ /$defg/) {
system("/sbin/route delete default");
system("/sbin/route add default $defg");
syslog('info', $soobsh);
send_mail($soobsh);
}
}

Proc::Daemon::Init;

open (PID,">$pidfile") || die "cannot create pidfile $!";
print PID $$;
close (PID);

setlogsock('unix');
openlog ('rezerv', 'ndelay,pid', 'local0');
syslog('info', 'Starting rezerv test');

$SIG{INT} = \&SHUTDOWN;
$SIG{TERM} = \&SHUTDOWN;

# При старте задаём провайдера №1 (по умолчанию)
change_dg($ext_gw_a);

my ($prow1,$prow2,$up_hosts);
for (;;) {
# Проверяем работу шлюзов провайдеров
if (ping($ext_gw_a)) {
$prow1=1;
}else{
$prow1=0;
}
if (ping($ext_gw_b)) {
$prow2=1;
}else{
$prow2=0;
}
# Выясняем есть ли смысл пинговать удалённые хосты (если шлюз неработает - не пингуем)
if ((($curent_gw =~ /$ext_gw_a/) && ($prow1)) or (($curent_gw =~ /$ext_gw_b/) && ($prow2))) {
foreach my $host (@targets) {
$up_hosts++ if ping($host);
}
}

# Переключение на рабочего провайдера
if ($curent_gw =~ /$ext_gw_a/ ) {
if (!$prow1 or !$up_hosts){
if ($prow2) {
change_dg($ext_gw_b);
$curent_gw=$ext_gw_b;
}
}
}
if ($curent_gw =~ /$ext_gw_b/ ) {
if (!$prow2 or !$up_hosts){
if ($prow1) {
change_dg($ext_gw_a);
$curent_gw=$ext_gw_a;
}
}
}

# Переключение на провайдера по умолчанию если он стал вновь доступен
if (($curent_gw =~ /$ext_gw_b/ ) && ($prow1)) {
change_dg($ext_gw_a);
$curent_gw=$ext_gw_a;
}
sleep(40);
}

sub SHUTDOWN() {
unlink($pidfile);
closelog();
exit;
}

Комментариев нет:

Ярлыки