Linux.FreeBSD. Автоматическое переключение на резервный канал интернет.
Поставили тут задачу настроить автоматическое переключение основного интернет канала на резервный и обратно.
Собственно, зная, что подобная задача есть у многих админов, я отправился искать готовый скрипт во всемирную паутину. И наткнулся вот на эту страничку:
Однако в этом скрипте есть ошибки. Причём, очень напрашивается чувство, что эти ошибки специально добавлены в скрипт, чтобы типа не совсем халява была. Честно говоря, я совсем не понимаю такого подхода к вещам. Ибо, если уж хочешь поделиться с людьми добрым делом, то делись, а не издевайся!
Вобщем, пришлось немного подправить этот скрипт, и у меня он получился вот такой:
# !/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
BTC:
bc1qzw9vam8mv6derwscxl0vrnd6m9t2rpjg273mna
ETH / BNB BSC / Polygon MATIC:
0x5cc07FF76490350ac6112fbFdA1B545Bc794602F
Tron:
TJUz8sJr9XYMjVqzmFNnCzzRWfPa57X2RV
USDT/USDC в сетях ETH/BSC/Polygon:
0x5cc07FF76490350ac6112fbFdA1B545Bc794602F
USDT в сети TRX (Tron):
TJUz8sJr9XYMjVqzmFNnCzzRWfPa57X2RV
LTC:
LRMZaFCSyCT6FUF62WEX1BokWV7v2dh2zo
Doge:
DTEnGLZRps9XaWNtAhchJWSeD4uTNDRxg7
XMR:
4A6uP1WxEc7HktToZFyiJuK6YmjdL8bSn2aY653qPwABhT4Y56iFuedgHcmpvLwWE55u8qkjGc715ZJs761FqedA8gkgznr
TON:
UQAdSPiWIDx2Q1VIeezkUV3s4sNlZM90w2ohSO6bD2-okwgY