Скрипт переключения провайдеров
Данный текст не рассматривать как инструкцию к действию и тем более не копипастить в терминал приведенные команды.Предоставлен исключительно для общего развития и понимания направления мыслительного процесса.
Претензии относительно "красивости" написания 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
Отлично работает. Спасибо.
ОтветитьУдалитьP.S. В строке echo "$DATE $GW $ping1$ping2$ping3" >> $LOGDIR/$LOG_nochange, лишний $LOGDIR.
Спасибо, исправил
УдалитьНа CentOS работает 100% только нужно в /etc/sysconfig/network-scripts/ifcfg-xxx добавить NM_CONTROLLED=no
ОтветитьУдалитьзавелось все с первого раза
ОтветитьУдалить