LINUX.ORG.RU
решено ФорумAdmin

2 канала инета, скрипт автопереключения на резервный и обратно

 ,


4

4

Тут есть подобные темы, но «боевых» вариантов так и не нашёл, поэтому можете кидаться яйцами и помидорами, но добавлю свои 3 копейки.

Начальные данные:

- основной канал со статическим ip, имя интерфейса ens19

- резервный канал динамический, имя интерфейса wwx0c5b8f279a64 (да, это модем)

- метрика роута для основного канала по умолчанию 100

- метрика роута для резервного канала по умолчанию 700

Что делаем в цикле:

- последовательно добавляем, проверяем и удаляем маршруты до тестируемых узлов, это сделано потому, что при поднятии резервного канала пакеты даже при указании ping -I «net» не пойдут через основной канал

- если все 9 пакетов icmp потерялись, то включаем роут через резервный канал с метрикой 50 и присваиваем переменной gw2 значение off

- если хоть до одного из 3 узлов все ответы пришли, то проверяем переменную gw2, если она on, то на паузу и далее по кругу. Если она off, то удаляем маршрут с метрикой 50 и присваиваем переменной gw2 значение on и далее на круг

Пауза проверки основного канала 20+9, основного (при включенном резервном) 300+9 (сек)

Сам скрипт (/etc/auto_net_switch.sh):

#!/bin/bash

# Основные переменные
# gw2 - шлюз резервного канала, состояние on или off, default=off
# net1 - имя сетевого интерфейса основного канала
# net2 - имя сетевого интерфейса резервного канала
# net1_gw_ip - ip адрес шлюза основного канала
# net2_gw_ip - ip адрес шлюза резервного канала динамический, поэтому определяем его каждый цикл
# net2_ip - ip адрес сетевой карты резервного канала динамический, поэтому определяем его каждый цикл
# ip[1-3] - ip адреса узлов для проверки соединения основного канала

# Изменить нужно только эти 5 переменных:
net1=ens19
net2=wwx0c5b8f279a64
ip1="1.1.1.1"
ip2="2.2.2.2"
ip3="3.3.3.3"

# Далее переменные менять не надо
gw2=off
net1_gw_ip=`ip route | awk '/'$net1'.*static/ { print $3 }'`

# Файл логов
logfile=/var/log/net_switch.log
echo `date +%Y.%m.%d__%H:%M:%S`' Скрипт автопереключения канала запущен' >> ${logfile}
# бесконечный цикл
while [ true ]; do
    net2_gw_ip=`ip route | awk '/default.*'$net2'/ { print $3 }'`
    net2_ip=`ifconfig | grep $net2 -A1 | grep -E "([0-9]{1,3}\.){3}[0-9]{1,3}" | awk '{ print $2 }' | cut -f2 -d:`
    route add $ip1 gw $net1_gw_ip
    result1=$(ping -c 3 -I ${net1} -W 1 ${ip1} 2<&1| grep -icE 'unknown|expired|unreachable|time out|100% packet loss')
    route del $ip1
    route add $ip2 gw $net1_gw_ip
    result2=$(ping -c 3 -I ${net1} -W 1 ${ip2} 2<&1| grep -icE 'unknown|expired|unreachable|time out|100% packet loss')
    route del $ip2
    route add $ip3 gw $net1_gw_ip
    result3=$(ping -c 3 -I ${net1} -W 1 ${ip3} 2<&1| grep -icE 'unknown|expired|unreachable|time out|100% packet loss')
    route del $ip3
    if [[ $result1 == 0 && $result2 == 0 && $result3 == 0 ]]; then
        if [[ $gw2 == on ]]; then
	    	route del -net default gw $net2_gw_ip metric 50 dev $net2
	    	ip route flush cache
	    	real_ip=`wget -q -O /dev/stdout http://checkip.dyndns.org/ | awk '{ print $6 }' | cut -d \< -f1`
	    	echo `date +%Y.%m.%d__%H:%M:%S`' Основной канал активирован, внешний ip' $real_ip >> ${logfile}
	    	gw2=off
	fi
	sleep 20
    else
	if [[ $gw2 == off ]]; then
	    	route add -net default gw $net2_gw_ip metric 50 dev $net2
	    	ip route flush cache
	    	real_ip=`wget -q -O /dev/stdout http://checkip.dyndns.org/ | awk '{ print $6 }' | cut -d \< -f1`
	    	echo `date +%Y.%m.%d__%H:%M:%S`' Основной канал деактивирован, включен резевный канал, внешний ip' $real_ip >> ${logfile}
	    	gw2=on
	fi
	sleep 300
    fi
done

Даём права на исполнение и закидываем в автозагрузку крона

sudo chmod 700 /etc/auto_net_switch.sh
sudo sh -c 'echo "@reboot root sleep 120; /etc/auto_net_switch.sh" >> /etc/crontab'



Последнее исправление: Dimarius (всего исправлений: 1)
Ответ на: комментарий от vodz

Это не связаные задачи — отправка пакета по текущему каналу и отправка пакета по заданному каналу. То, что в скрипте будет ″ping -I ip-адрес″ не подразумевает, что в таблице main не будет маршрута по умолчанию.

mky ★★★★★
()
Ответ на: комментарий от mky

Это не связаные задачи

Связали — вы. Я вам не запрещал делать ping -I IP и прочие сложные тесты. Именно вы тут развели тупняк, что у нас получается проще и потому правильнее. Может вы ещё забыли, что вы пошли по поводу anc и отказались от изменений default main.

vodz ★★★★★
()
Ответ на: комментарий от vodz

То есть для вас KISS это тупняк? Ну тогда понятно, откуда растут ноги.

вы пошли по поводу anc и отказались от изменений default main.

Я такого не писал. Я писал, что не нужно убирать default из main, изменять я него не запрещал.

mky ★★★★★
()
Ответ на: комментарий от Deleted

Была (и даже есть, валяется без дела) железка длинк за 700$ на 2 прова. Более дырявого и глючного железа не встречал: раз в неделю гарантировано фризил. Даже вифи-роутеры для домашнего сегмента стабильнее. В результате установлен полноценный комп (списанный металлолом) с полноценной ОС и всеми плюшками, работает уже несколько лет вообще без нареканий. Фризы, перезагрузки, отражение атак и прочие приключения забыты как в кошмарном сне.

Dimarius
() автор топика
Ответ на: комментарий от mky

Если прописать для каждого интерфейса (ip-адреса) свою таблицу со своим default маршрутом, то ping'у указывается ″-I ip-адрес″ и icmp-пакет идут именно через этот интерфейс

Встала задача реализовать резервный канал и эта тема, и высказанная мысль указала нужное направление движения.

Jurik_Phys ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.