Пятница, 15.11.2024, 06:30
# FreeBSD ГлавнаяРегистрацияВход
Приветствую Вас Гость | RSS
Меню сайта
Категории раздела
Мои статьи [167]
Статистика

Онлайн всего: 1
Гостей: 1
Пользователей: 0
Форма входа
 Каталог статей 
Главная » Статьи » Мои статьи

Скрипт автоматического переключения между основным и резервным каналом

Скрипт автоматического переключения между основным и резервным каналом

Есть офисный маршрутизатор на базе FreeBSD и два приходящих канала Internet.

Поставлена задача: автоматизировать переключения с основного канала на резервный в случае его падения и обратно, после возобновления работы основного канала.

В "закромах Родины" завалялся perl-скрипт, происхождение которого установить не получилось. Скорее всего был скачан "на всякий случай" из инета.

Итак, проанализировав содержимое скрипта, выполняем установку необходимого расширения Perl - Net-Ping:

# cd /usr/ports/net/p5-Net-Ping-External && make install clean && rehash

Далее правим переменные в скрипте. Листинг скрипта следующий:

#!/usr/bin/perl -w
use strict;
use warnings;
use Net::Ping::External qw(ping);
# 1 - автоматический режим переключение канала
# 2 - принудительное переключение на второй канал.
my $action = 1;
my $host_gw = "192.168.213.129"; # default gateway
my $gw = "192.168.178.209"; # backup gateway
my $now = localtime time;
my $log = "/var/log/route-change.log";
 
if($action == 1){
 
my $command = `netstat -rn | grep default`;
my @b = split('\s+',$command,3);
 
if (ping(hostname=>$host_gw, count=>5)){
   print "host $host_gw is ok\n";
       if($b[1] ne $host_gw){
           if($b[1] eq ""){
               `route add default $host_gw`;
           }else{
               `route change default $host_gw`;
               open(LOG,">>$log");
                   print LOG "[!] $now Route change to $host_gw\n";
               close(LOG);
           }
       }
}else{
   print "host $host_gw is bad.\n";
   if($b[1] ne $gw){
     `route change default $gw`;
   open(LOG,">>$log");
       print LOG "[!] $now Route change to $gw\n";
   close(LOG);
   }
}
}
 
if($action == 2){
 
my $command = `netstat -rn | grep default`;
my @b = split('\s+',$command,3);
 
if($b[1] ne $gw){
   if($b[1] eq ""){
       `route add default $gw`;
   }else{
       `route change default $gw`;
       open(LOG,">>/change_route.log");
           print LOG "[!] $now Route change to $gw\n";
       close(LOG);
   }
   }
}

Разместим данный скрипт под названием route-change.pl  в каталоге /usr/local/etc. Проверим дефолт до запуска скрипта:

# netstat -rn | grep default
default            192.168.213.129     UGS       335 51206943 vlan32

Запустим скрипт:

# perl /usr/local/etc/route-change.pl
host 192.168.213.129 is ok

Проверяем значение маршрута по умолчанию:

# netstat -rn | grep default
default            192.168.213.129     UGS       346 51212415 vlan32

Проверим, выполняется ли переключение, выполнив имитацию падения канала.

# ipfw add 1 deny icmp from any to 192.168.213.129
00001 deny icmp from any to 192.168.213.129

# perl /usr/local/etc/route-change.pl
host 91.204.213.129 is bad.

# netstat -rn | grep default
default            192.168.178.209     UGS       521 51732384 vlan33

Все работает! Осталось только проверить, происходит ли обратное переключение на основной канал:

# ipfw 1 delete

# perl /usr/local/etc/route-change.pl
host 91.204.213.129 is ok

# netstat -rn | grep default
default            192.168.213.129     UGS       374 51751262 vlan32

 

Проверим, ведется ли логгирование переключений:

# cat /var/log/route-change.log
[!] Thu Oct 28 16:13:45 2010 Route change to 85.223.178.209
[!] Thu Oct 28 16:16:41 2010 Route change to 91.204.213.129

Все гуд... Последний штрих - добавим запуск скрипта в cron с ежеминутным запуском:

# echo '# Route check and change' >> /etc/crontab

# echo '*       *       *       *       *       root    /usr/bin/perl /usr/local/etc/route-change.pl > /dev/null 2>&1' >> /etc/crontab

# killall -HUP cron

 

Преимущество даного скрипта - простота и надежность.

Недостатком можно считать то, что он проверяет только доступность шлюза. В случае, если инет "упал" за шлюзом, переключение выполняться не будет. Как вариант - можно прописать статический маршрут к какому-то надежному серверу (например, к одному из серверов google.com)  через основной канал и выполнять проверку доступности именно этого сервера. Выполнить модификацию скрипта в таком случае не так уж и сложно...

Ваша оценка: Пусто Средняя: 5 (3 голосов)

Добрый день низкий Вам поклон

Добрый день низкий Вам поклон за Ваш труд.

С Вашего разрешения пару вопросов ?

1 - ee /etc/rc.conf

ifconfig_fxp0="inet 192.168.1.1/24"
ifconfig_fxp1="inet 192.168.5.2/30"
ifconfig_fxp2="inet 192.168.6.2/30"
defaultrouter="192.168.213.129"
defaultrouter="192.168.178.209"

Какой шлюз комментить в кц конфе.Я так понимаю второй или его писать не надо и скрипт сам поменяет первый на второй ?

 

2 - Как быть с натом ? Он же висит на одном интерфейсе скрипт сам переключит на другой ?

 

3 - Как быть с фаерволом ?

 

#!/bin/sh
FwCMD="/sbin/ipfw -q  "

LanOut="fxp0"
IpOut="192.168.1.1"

IpIn="192.168.5.2"
LanIn="fxp1"

IpIn2="192.168.6.2"

IpIn2="fxp2"

Как скрипт переключит нужные сетевухи или как правильно прописать в фаерволе все сразу.

 

Ещё раз прошу помощи и поподробнее если будет желание ответить.

                С огромным уважением.
 

1. defaultrouter - оставляете

1. defaultrouter - оставляете только "главный" канал.

Для управления маршрутами используется стандартный демон маршрутизации route. Опция defaultrouter="192.168.213.129" указывает на необходимость выполнения следующей команды:

# route add default 192.168.213.129

Скрипт же будет проверять доступность шлюза и в случае необходимости переходить на резервный канал. Тоесть, фактически выполнится команда:

# route change default 192.168.178.209

 

2. Я сразу подымаю НАТ на двух интерфейсах (использую pf, либо же ipnat - без проблем НАТят на двух интерфейсах одновременно).

3. Это уже зависит от конфигурации файрвола. Нужно, чтобы можно было "ходить" и в один и в другой канал без изменения конфигурации. Либо же "пилить" скрипт под свои нужды, чтобы он выполнял необходимые изменения.

а почему бы не использовать

а почему бы не использовать утилиту ping, вместо модуля Net::Ping?вы же используете утилиты netstat и route? 

Писал скрипт не я, только

Писал скрипт не я, только немножно допилил.

Кстати, если использовать Net::Ping::External, то нету никаких проблем с ложным срабатыванием (заменил в статье).

Категория: Мои статьи | Добавил: Admin (23.12.2011)
Просмотров: 2136 | Комментарии: 5 | Рейтинг: 0.0/0
Всего комментариев: 0
Имя *:
Email *:
Код *:
Поиск
Друзья сайта
  • Официальный блог
  • Сообщество uCoz
  • FAQ по системе
  • Инструкции для uCoz
  • Copyright MyCorp © 2024Сделать бесплатный сайт с uCoz