Тут есть подобные темы, но «боевых» вариантов так и не нашёл, поэтому можете кидаться яйцами и помидорами, но добавлю свои 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'