Поставили тут задачу настроить автоматическое переключение основного интернет канала на резервный и обратно.
Собственно, зная, что подобная задача есть у многих админов, я отправился искать готовый скрипт во всемирную паутину. И наткнулся вот на эту страничку:
Однако в этом скрипте есть ошибки. Причём, очень напрашивается чувство, что эти ошибки специально добавлены в скрипт, чтобы типа не совсем халява была. Честно говоря, я совсем не понимаю такого подхода к вещам. Ибо, если уж хочешь поделиться с людьми добрым делом, то делись, а не издевайся!
Вобщем, пришлось немного подправить этот скрипт, и у меня он получился вот такой:
# !/bin/bash
# Default GW's
GW1=111.111.111.111
GW2=222.222.222.222
# IP основного интерфейса
eth0=111.111.111.112
# IP хоста для проверки
dst1=4.2.2.1
# Переменная
inet=0
# Сам скрипт
inet=$(ping -c 1 -I $eth0 $dst1 | grep "64 bytes from" | awk '{print $2}' )
if [ "$inet" != "bytes" ]; then
if [ -f /etc/ppp/second.gw ]; then
echo Already switched to secondary
else
/sbin/route delete default
/sbin/route add default gw $GW2 eth2
/sbin/route add -host $dst1 gw $GW1
touch /etc/ppp/second.gw
echo "Primary failed. Switching to secondary" | sendEmail -f admin@my.ru -t admin@my.ru -u "primary failed" -m "primary failed" -s 172.16.0.62:25
fi
else
if [ -f /etc/ppp/second.gw ]; then
/sbin/route delete default
/sbin/route add default gw $GW1 eth0
/sbin/route del -host $dst1 gw $GW1
echo "Primary restored. Switching back" | sendEmail -f admin@my.ru -t admin@my.ru -u "primary restored" -m "primary restored" -s 172.16.0.62:25
rm /etc/ppp/second.gw
fi
fi
Где eth0 − основной канал, а eth2 − резервный. (локальная сеть − eth1, так вышло...)
На Linux Fedora 13 скрипт работает 100%-но. Здесь я исправил некоторые ошибки + от себя добавил, что для проверки будет пинговаться хост 4.2.2.1 − это один из бесплатных публичных DNS-серверов, который доступен всегда (в отличие от апорта, который используется в оригинале скрипта). Далее, от себя, я изменил способ отправки уведомления на электронную почту, использовав программку sendEmail. Эта программка умеет отправлять сообщение, используя сторонний MTA. О том, как её установить, смотрите тут:
http://technotrance.su/index.php/zametki-iz-drugikh-istochnikov/23-sendemail
Также, на основе этого скрипта, я сделал аналогичный скрипт, но для FreeBSD. Вот он:
#!/bin/sh
# Default GW's
GW1=111.111.111.111
GW2=222.222.222.222
# IP основного интерфейса
eth0=111.111.111.112
# IP хоста для проверки
dst1=4.2.2.1
# Переменная
inet=0
# Сам скрипт
inet=$(ping -c 1 -S $eth0 $dst1 | grep "64 bytes from" | awk '{print $2}' )
if [ "$inet" != "bytes" ]; then
if [ -f /etc/ppp/second.gw ]; then
echo Already switched to secondary
else
/sbin/route change default $GW2
/sbin/route add -host $dst1 $GW1
touch /etc/ppp/second.gw
echo "Primary failed. Switching to secondary" | sendEmail -f admin@my.ru -t admin@my.ru -u "primary failed" -m "primary failed" -s 172.16.0.62:25
fi
else
if [ -f /etc/ppp/second.gw ]; then
/sbin/route change default $GW1
/sbin/route del -host $dst1 $GW1
echo "Primary restored. Switching back" | sendEmail -f admin@my.ru -t admin@my.ru -u "primary restored" -m "primary restored" -s 172.16.0.62:25
rm /etc/ppp/second.gw
fi
fi
Принцип действия абсолютно такой же, здесь лишь изменены некоторые команды. Работает 100%-но на FreeBSD 9.1.
Ну, и что эти скрипты надо добавить в Cron, думаю понятно и так.
Добавлено 02.10.2014
Как показала практика, скрипт выше, очень чувствителен и к кратковременным глюкам интернета, когда, например, связь с проверочным хостом пропадает буквально на минуту, но при этом, остальное всё доступно и нормально работает. Т.е. скрипт очень часто срабатывает ложно.
Это очень быстро начало меня нервировать, и я начал искать решение. И мне помог мой давний коллега и товарищ Иван Мартюшев. Он дополнил скрипт, приведённый выше. И теперь скрипт работает следующим образом: для проверки используется три разных хоста, и каждый из них пингуется три раза. И если хоть один пинг проходит, то значит основной канал жив (просто немного лагает), и переключаться на резерв НЕ нужно.
Вот как выглядит доработанный скрипт:
#!/bin/bash
# Default GW's
GW1=111.111.111.111
GW2=222.222.222.222
# IP хостов для проверки
dst1=4.2.2.1
dst2=193.232.146.1
dst3=31.31.194.3
# Переменная
ping1=0
ping2=0
ping3=0
# Сам скрипт
ping1=$(ping -c 3 -w 15 $dst1 | awk 'BEGIN{s=""} $2~/bytes/{s=s "X"} END{print s}')
ping2=$(ping -c 3 -w 15 $dst2 | awk 'BEGIN{s=""} $2~/bytes/{s=s "X"} END{print s}')
ping3=$(ping -c 3 -w 15 $dst3 | awk 'BEGIN{s=""} $2~/bytes/{s=s "X"} END{print s}')
all=$ping1$ping2$ping3
if [ "$all" == "" ]; then
if [ -f /etc/ppp/second.gw ]; then
echo Already switched to secondary
else
/sbin/route delete default
/sbin/route add default gw $GW2 eth2
/sbin/route add -host $dst1 gw $GW1
/sbin/route add -host $dst2 gw $GW1
/sbin/route add -host $dst3 gw $GW1
touch /etc/ppp/second.gw
echo "Primary failed. Switching to secondary" | sendEmail -f router@my.me -t me@my.me -u "for router primary failed" -m "for router primary failed" -s 172.16.0.62:25
fi
else
if [ -f /etc/ppp/second.gw ]; then
/sbin/route delete default
/sbin/route add default gw $GW1 eth0
/sbin/route del -host $dst1 gw $GW1
/sbin/route del -host $dst2 gw $GW1
/sbin/route del -host $dst3 gw $GW1
echo "Primary restored. Switching back" | sendEmail -f router@my.me -t me@my.me -u "for router primary restored" -m "for router primary restored" -s 172.16.0.62:25
rm /etc/ppp/second.gw
fi
fi
Этот скрипт на 99% исключает ложные срабатывания. У меня работает больше полугода, и переключает на резервный канал только когда основной канал реально совсем полёг.
Он же для FreeBSD:
#!/bin/sh
# Default GW's
GW1=111.111.111.111
GW2=222.222.222.222
# IP хостов для проверки
dst1=4.2.2.1
dst2=193.232.146.1
dst3=31.31.194.3
# Переменная
ping1=0
ping2=0
ping3=0
# Сам скрипт
ping1=$(ping -c 3 -t 15 $dst1 | awk 'BEGIN{s=""} $2~/bytes/{s=s "X"} END{print s}')
ping2=$(ping -c 3 -t 15 $dst2 | awk 'BEGIN{s=""} $2~/bytes/{s=s "X"} END{print s}')
ping3=$(ping -c 3 -t 15 $dst3 | awk 'BEGIN{s=""} $2~/bytes/{s=s "X"} END{print s}')
all=$ping1$ping2$ping3
if [ "$all" = "" ]; then
if [ -f /etc/ppp/second.gw ]; then
echo Already switched to secondary
else
/sbin/route change default $GW2
/sbin/route add -host $dst1 $GW1
/sbin/route add -host $dst2 $GW1
/sbin/route add -host $dst3 $GW1
touch /etc/ppp/second.gw
echo "Primary failed. Switching to secondary" | sendEmail -f gateway@my.me -t me@my.me -u "for gateway primary failed" -m "for gateway primary failed" -s 172.16.0.62:25
fi
else
if [ -f /etc/ppp/second.gw ]; then
/sbin/route change default $GW1
/sbin/route del -host $dst1 $GW1
/sbin/route del -host $dst2 $GW1
/sbin/route del -host $dst3 $GW1
echo "Primary restored. Switching back" | sendEmail -f gateway@my.me -t me@my.me -u "for gateway primary restored" -m "for gateway primary restored" -s 172.16.0.62:25
rm /etc/ppp/second.gw
fi
fi
Донаты принимаются на кошельки:
Yoomoney:
4100118091867315
Карта Т-Банк (бывший Тиньков):
2200 7017 2612 2077
Карта Альфа-Банк:
2200 1539 1357 2013