Linux.FreeBSD. Автоматическое переключение на резервный канал интернет.

Рейтинг:   / 5
ПлохоОтлично 

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

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

http://moywww.ru/zapiski-admina/9-nastroyka-linux/6-avtomaticheskoe-perekluchenie-interfeysov-linux-suse

Однако в этом скрипте есть ошибки. Причём, очень напрашивается чувство, что эти ошибки специально добавлены в скрипт, чтобы типа не совсем халява была. Честно говоря, я совсем не понимаю такого подхода к вещам. Ибо, если уж хочешь поделиться с людьми добрым делом, то делись, а не издевайся!

Вобщем, пришлось немного подправить этот скрипт, и у меня он получился вот такой:

# !/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

You have no rights to post comments

Вы здесь: Home Мои Заметки Linux.FreeBSD. Автоматическое переключение на резервный канал интернет.