Просто хочу поделится :)
Система FreeBSD 5.5Требуется установить 2 файла в /usr/local/etc/rc.d c правами 555
# cat /usr/local/etc/rc.d/reserv.sh
#!/bin/sh
case "$1" in
start)
[ -x /usr/local/etc/rc.d/reserv.pl ] && /usr/local/etc/rc.d/reserv.pl && echo -n ' reserv'
;;
stop)
[ -r /var/run/reserv.pl.pid ] && kill -s TERM `cat /var/run/reserv.pl.pid` > /dev/null && echo -n ' reserv'
;;
*)
echo "Usage: `basename $0` {start|stop}" >&2
;;
esacexit 0
Собственно сам скрипт, в котором нужно поменять гетвеи на ваши#!/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 = "robot\@my.ru";
my $from = "robot\@my.ru";my $check;
my $ext_gw_a = "x.x.x.x";
my $ext_gw_b = "z.z.z.z";my $cmd_ping = "/sbin/ping -q -c 2";
my $cmd_mail="/usr/sbin/sendmail -t";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 |grep default';
my $DGB=`$cmd_netstat`;
unless ($DGB =~ /$defg/) {
system("route delete default");
system("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;my ($prow1,$prow2);
for (;;) {
# Check channel
if (ping($ext_gw_a)) {
$prow1=1;
}else{
$prow1=0;
}
if (ping($ext_gw_b)) {
$prow2=1;
}else{
$prow2=0;
}if ($prow1 && $prow2) {
change_dg($ext_gw_a);
}
if ($prow1 && !$prow2) {
change_dg($ext_gw_a);
}
if (!$prow1 && $prow2) {
change_dg($ext_gw_b);
}
sleep(40);
}sub SHUTDOWN() {
unlink($pidfile);
closelog();
exit;
}
Буду рад коментариям :)
>Просто хочу поделится :)
>
>
>Буду рад коментариям :)
Замечания - не везде прописаны полные пути к системным утилитам grep и route
Вот конечный вариант - более продвинутый :)
Изменился только#!/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.99my @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;
}