пятница, 28 декабря 2012 г.

Скрипт переключения провайдеров


Скрипт переключения провайдеров

Данный текст не рассматривать как инструкцию к действию и тем более не копипастить в терминал приведенные команды.
Предоставлен исключительно для общего развития и понимания направления мыслительного процесса.
Претензии относительно "красивости" написания bash-скриптов не принимаются.
У меня этот скрипт работает на нескольких рабочих серверах.


План:

1. Необходимые знания
2. Постановка задачи
3. Скрипт
4. Ротация логов

1. Необходимые знания


Для наилучшего понимания необходимо прочитать следующие статьи:
Компьютерные сети и сетевые порты
Управление сетевыми настройками (iproute2)
Пишем скрипты в Linux (обучение на примерах)
Системные сообщения и управление ими (logrotate)
Автозагрузка и запланированные задания (rc.local, cron)

2. Постановка задачи


Есть два провайдера. Хотим переключаться на второй только в случае, если первый недоступен. При этом будут писаться два журнала (логи):
в первый /etc/scripts/log/route-change.log будут записываться дата,время, смена маршрутизации и пинг-флаги вида
2012-12-15--23-58-59 192.168.0.1 > 10.0.0.1 000

во второй /etc/scripts/log/route-nochange.log будет записываться дата, время действующий маршрут и пинг-флаги вида
2012-12-15--23-59-59 192.168.0.1 111


Почему именно два - мне так удобнее. Можно сделать и один файл, а потом грепать (grep)

3. Скрипт


Создаём файл /etc/scripts/route-change.sh:
#!/bin/bash
# каталог, в который будем складывать логи выполнения наших скриптов. Если меняем его расположение, не забываем поменять пути к логам в /etc/logrotate.d/route-change
LOGDIR=/etc/scripts/log
mkdir -p $LOGDIR
# в этот лог будем записывать только в случае смены маршрута
LOG_change=$LOGDIR/route-change.log
# в этот лог будем записывать если смены маршрута не состоялось
LOG_nochange=$LOGDIR/route-nochange.log
# время формата 2012-12-06--23-59-59
DATE=$(date +%Y'-'%m'-'%d'--'%H'-'%M'-'%S)
# .google-public-dns-a.google.com
ip1=8.8.8.8
# .www.yandex.ru
ip2=93.158.134.203
# .www.mail.ru
ip3=217.69.141.21
# шлюз первого провайдера
gw_1=192.168.0.1
# шлюз второго провайдера
gw_2=10.0.0.1
# интерфейс, на котором висит провайдер 1
iface1=eth0
# интерфейс, на котором висит провайдер 2
iface2=eth1
# нынешний актуальный шлюз
GW=$(ip ro ls |grep default|awk '{print $3}')
# флаги, на основании которых будет приниматься решение о смене маршрутизации.
# добавляем маршруты до трёх ip-адресов (ip1,ip2,ip3) через шлюз первого провайдера
# выполняем пинг этих адресов. В случае удачи ip1,ip2 и ip3 станут равны 1,1 и 1 соответственно (либо 110, если один из них недоступен, например, и т.п.)
# удаляем маршрутизацию до этих адресов. Это необходимо для того, чтобы они были доступны в случае неработоспособности первого провайдера
ping1=0
 ip ro add $ip1 via $gw_1 dev $iface1
 ping -q -c 1 $ip1 > /dev/null && ping1=1
 ip ro del $ip1 2>/dev/null
ping2=0
 ip ro add $ip2 via $gw_1 dev $iface1
 ping -q -c 1 $ip2 > /dev/null && ping2=1
 ip ro del $ip2 2>/dev/null
ping3=0
 ip ro add $ip3 via $gw_1 dev $iface1
 ping -q -c 1 $ip3 > /dev/null && ping3=1
 ip ro del $ip3 2>/dev/null
# если ни один из трёх ip-адресов не пинговался (через шлюз первого провайдера)
if [ $ping1$ping2$ping3 = 000 ]
then
# И маршрутизация шла через шлюз первого провайдера, то
 if [ $GW = $gw_1 ]
 then
# Записываем в лог сообщение о смене маршрутизации
 echo "$DATE $gw_1 > $gw_2 $ping1$ping2$ping3" >> $LOG_change
# Меняем на шлюз второго провайдера
 ip ro del default
 ip ro ad default via $gw_2 dev $iface2
 else
 # в противном случае (первый провайдер не работает, хотя и так работаем через второго провайдера), просто записываем в лог состояние
 echo "$DATE $GW $ping1$ping2$ping3" >> $LOG_nochange
 fi
# Если же был хоть один удачный пинг на один из трёх ip-адресов, значит первый провайдер работает
else
# И соответственно, если был маршрут по умолчанию - шлюз второго провайдера, то
 if [ $GW = $gw_2 ]
 then
# Записываем в лог сообщение о смене маршрутизации
 echo "$DATE $gw_2 > $gw_1 $ping1$ping2$ping3" >> $LOG_change
# Меняем на шлюз первого провайдера
 ip ro del default
 ip ro ad default via $gw_1 dev $iface1
 else
# Иначе просто записываем в лог
 echo "$DATE $GW $ping1$ping2$ping3" >> $LOG_nochange
 fi
fi

Добавляем в /etc/crontab ежеминутное выполнение скрипта

4. Ротация логов


Мы же хотим делать ежедневную ротацию логов. Добавляем файл /etc/logrotate.d/route-change:


/etc/scripts/log/route-change.log {
daily
missingok
rotate 14
compress
notifempty
delaycompress
postrotate
test ! -e /etc/scripts/log/route-change.log.1 || cat /etc/scripts/log/route-change.log.1 | grep ">" | mail -s "route change" admin@server.org
endscript
}



/etc/scripts/log/route-nochange.log {
daily
missingok
rotate 14
compress
notifempty
delaycompress
}
Делаем его выполняемым

chmod +x /etc/logrotate.d/route-change

4 комментария:

  1. Отлично работает. Спасибо.

    P.S. В строке echo "$DATE $GW $ping1$ping2$ping3" >> $LOGDIR/$LOG_nochange, лишний $LOGDIR.

    ОтветитьУдалить
  2. На CentOS работает 100% только нужно в /etc/sysconfig/network-scripts/ifcfg-xxx добавить NM_CONTROLLED=no

    ОтветитьУдалить
  3. завелось все с первого раза

    ОтветитьУдалить