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

Скрипт по смене каналов провайдера

 ,


1

1

Всем привет! Есть всем известный скрипт по смене или балансировке каналов между провайдерами. Многим этот скрипт известен, т.к. эта тема уже не раз мусолилась. В общем мой скрипт отрабатывает нормально в одну сторону :) С основного канала на резервный переключается всё ок, но вот когда обратно поднимается основной канал, скрипт не перескакивает обратно на основной, ну это понятно потому, что нету куска кода, который проверял бы это :) Я дописал проверочный кусочек и на основном канале всё ок, а когда переключается на резервный, он почему-то пытается постоянно перескачить на основной канал обратно, в следствии чего пропадают пинги при попытке переключиться. Собственно вот код :)

#!/bin/bash

. /usr/sbin/vars

OLDIF1=0
OLDIF2=0

LOG='/var/log/providers'

. /usr/sbin/routing.sh
while true; do

ping -c 3 -s 100 $GW1 -I $IF1 > /dev/null
if [ $? -ne 0 ]; then
        echo $(date +%D-%T) prov1 is down!!! >> $LOG
        NEWIF1=0
else
        NEWIF1=1
fi

ping -c 3 -s 100 $GW2 -I $IF2 > /dev/null
if [ $? -ne 0 ]; then
        echo $(date +%D-%T) prov2 is down!!! >> $LOG
        NEWIF2=0
else
        NEWIF2=1
fi

if (( ($NEWIF1!=$OLDIF1) || ($NEWIF2!=$OLDIF2) )); then
        echo $(date +%D-%T) Changing channels >> $LOG

# elif (( ($NEWIF1==1) && ($NEWIF2==1) )); then
#       echo $(date +%D-%T) Verifycation channels. Both channels is up.  >> $LOG
#       if ip route | grep 'default via $GW1 dev eth2' > /dev/null; then
#               echo $(date +%D-%T) All clients stay on prov1!!! >> $LOG
#       else
#               ip route delete default
#               ip route add default via $GW1 dev $IF1
#               echo $(date +%D-%T) Changing channels from prov2 to prov1!!! >> $LOG

elif (( ($NEWIF1==1) && ($NEWIF2==0) )); then
        echo $(date +%D-%T) All clients routes to prov1 >> $LOG
        ip route delete default
        ip route add default via $GW1 dev $IF1
        systemctl restart openvpn@server.service
        systemctl restart openvpn@client.service
elif (( ($NEWIF1==0) && ($NEWIF2==1) )); then
        echo $(date +%D-%T) All clients routes to prov2 >> $LOG
        ip route delete default
        ip route add default via $GW2 dev $IF2
        systemctl restart openvpn@server.service
        systemctl restart openvpn@client.service

else
echo > /dev/null
fi

OLDIF1=$NEWIF1
OLDIF2=$NEWIF2
sleep 3
done

Код, который я добавил в изначально работающий скрипт, закоментирован. Может быть мой кусок поставить до сравнения значений newif и oldif? А вообще я уже чет запутался :) Прошу помочь разобраться. Спасибо.

Ответ на: комментарий от XMs

Когда занимался настройкой переключения, не попадал на статьи по ifenslave. Сейчас уже хочется разобраться со скриптом, ну а в дальнейшем может и перейду на него :).

metal-psix ()

Вообще следуя логике именно этого скрипта, я бы проверил вот так

elif (( ($NEWIF1==1) && ($OLDIF1==0) )); then
               ip route delete default
               ip route add default via $GW1 dev $IF1

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

Так не катит. При 2-х поднятых каналах работает на обоих нормально и на основном и на резервном. Как только 1 канал падает начинается пляска пингов. От 2 до 4 пингов проходит, потом теряются примерно 4 или 5. Поднимаю канал, сразу всё ок становится, но не переключается.

Есть еще у кого-то идеи? :)

XMs
Поднял я тестовую машинку (debian 8.6), чтобы попробовать ifenslave. На машинке 2 сетевухи ну и соответственно разные подсети. Интерфейс поднялся, но нету интернета :) Маршрутов вообще нет, кроме bond интерфейса, который смотрит сам на себя в таблице Local :). При настройке ifenslave еще что-то надо настраивать? Ну к примеру маршруты прописать и iptables подправить.

metal-psix ()
Ответ на: комментарий от metal-psix

Меня надо было скастовать (через [user][/user]), если бы я не заглянул в тред, не увидел бы вопроса.

Покажи выхлоп route, ip addr и traceroute 77.88.8.8

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

XMs

root@test:~# route -n
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref  
Use Iface
0.0.0.0          192.168.42.1     0.0.0.0         UG    0      0        0 bond0
192.168.42.0     0.0.0.0         255.255.255.0   U     0      0        0 bond0

root@test:~# ip addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host
       valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,SLAVE> mtu 1500 qdisc pfifo_fast master bond0 state DOWN group default qlen 1000
    link/ether b8:97:5a:5a:52:dc brd ff:ff:ff:ff:ff:ff
3: eth1: <BROADCAST,MULTICAST,SLAVE,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast master bond0 state UP group default qlen 1000
    link/ether b8:97:5a:5a:52:dc brd ff:ff:ff:ff:ff:ff
4: bond0: <BROADCAST,MULTICAST,MASTER,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
    link/ether b8:97:5a:5a:52:dc brd ff:ff:ff:ff:ff:ff
    inet 192.168.42.144/24 brd 192.168.42.255 scope global bond0
       valid_lft forever preferred_lft forever
    inet6 fe80::ba97:5aff:fe5a:52dc/64 scope link
       valid_lft forever preferred_lft forever

root@test:~# traceroute 77.88.8.8
traceroute to 77.88.8.8 (77.88.8.8), 30 hops max, 60 byte packets
 1  Test.lan (192.168.42.1)  0.255 ms  0.299 ms  0.361 ms
 2  192.168.13.1 (192.168.13.1)  1.199 ms  1.209 ms  1.200 ms
 3  unnamed.prov1.net (45.114.98.1)  5.133 ms  5.157 ms  5.148 ms
 4  yandex-gw.crimea-ix.net (91.194.162.152)  13.152 ms  13.163 ms  14.774 ms
 5  dns.yandex.ru (77.88.8.8)  17.113 ms  17.126 ms  17.154 ms

В общем ifenslave завелся, но странно то, что на 192.168.42.144 и интернет есть и впн сетки пингуются, а вот на 192.168.13.92(это основной канал) ничего не пингуется. При пингах destination host unreachable. Вот выводы команд с основного канала.

root@test:/etc/network# route -n
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
0.0.0.0         192.168.13.1     0.0.0.0         UG    0      0        0 bond0
192.168.13.0     0.0.0.0         255.255.255.0   U     0      0        0 bond0

root@test:/etc/network# ip addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default 
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host 
       valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,SLAVE> mtu 1500 qdisc pfifo_fast master bond0 state DOWN group default qlen 1000
    link/ether b8:97:5a:5a:52:dc brd ff:ff:ff:ff:ff:ff
3: eth1: <NO-CARRIER,BROADCAST,MULTICAST,SLAVE,UP> mtu 1500 qdisc pfifo_fast master bond0 state DOWN group default qlen 1000
    link/ether b8:97:5a:5a:52:dc brd ff:ff:ff:ff:ff:ff
4: bond0: <NO-CARRIER,BROADCAST,MULTICAST,MASTER,UP> mtu 1500 qdisc noqueue state DOWN group default 
    link/ether b8:97:5a:5a:52:dc brd ff:ff:ff:ff:ff:ff
    inet 192.168.13.92/24 brd 192.168.13.255 scope global bond0
       valid_lft forever preferred_lft forever
    inet6 fe80::ba97:5aff:fe5a:52dc/64 scope link 
       valid_lft forever preferred_lft forever

root@test:/etc/network# traceroute 77.88.8.8
traceroute to 77.88.8.8 (77.88.8.8), 30 hops max, 60 byte packets
 1  test (192.168.13.92)  2617.388 ms !H  2617.356 ms !H  2617.342 ms !H 

В обоих выводах смущает, то что eth0 лежит, да и на основном канале bond почему-то тоже лежит :) Надеюсь у тебя получится немного прояснить картину :) Заранее спасибо.

metal-psix ()
Ответ на: комментарий от metal-psix

Если коротко: http://xgu.ru/wiki/Linux_Bonding — почитай, тут есть ответы на многие вопросы. Суть в том, что два интерфейса рассматриваются как один, вплоть до клонирования MAC-адресов. Я не учёл, что у тебя разные провайдеры и разные подсети (bonding немного для других задач и условий создавался). Как вариант, ты можешь организовать NAT для интерфейсов, чтобы пакеты ходили через оба. Либо отказаться от аггрегирования.

PS: когда отвечаешь на сообщение, того, кому отвечаешь, кастовать не обязательно (при ответах уведомление приходит и так)

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

Прежде чем настраивать естесно я обратился к гуглу. И на вики тоже был :) Вот у меня сразу были подозрения по поводу разруливания моей проблемы через bonding, но это хороший опыт, который думаю не будет лишним :) Если б мне нужна была балансировка, я бы уже скриптами разрулился, а так нужно, чтобы переключался при падении одного из каналов. Насколько я понял, он больше для балансировки и в одной подсети?

metal-psix ()
Ответ на: комментарий от metal-psix

он больше для балансировки и в одной подсети?

Не обязательно балансировки, но рассчитывает, что адрес един для всех интерфейсов. Хотя конфигурация сети может быть очень сложной. Например, я поднимал агрегирование двух VPN-каналов через два разных маршрута (спутник и свисток). Задействовал много всего: бриджи, network namespaces, виртуальный ethernet. Но мне и трафик не перекидывать с интерфейса на интерфейс надо было, а полностью зеркалировать. В итоге bond0 имел адрес в VPN-сети, а физические интерфейсы подключались по своим

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

Но это опять-таки только про скрипт.
ЗЫ А в целом общий подход, не пользуем def route в main, прописываем отдельно для каждого канала свои таблицы, и в случае падения одного канала переправляем через другую таблицу. Но к данному скрипту это не имеет отношения и это уже отдельная тема.
btw нагуглить возможно, да и тут темы были.

anc ★★★★★ ()
Ответ на: комментарий от anc
#!/bin/bash

. /usr/sbin/vars

echo "1" > /proc/sys/net/ipv4/ip_forward

ip route add $P1_NET dev $IF1 src $IP1 table $pr1 > /dev/null 2>&1
ip route add default via $GW1 table $pr1 > /dev/null 2>&1
ip route add $P1_NET dev $IF2 src $IP2 table $pr2 > /dev/mull 2>&1
ip route add default via $GW2 table $pr2 > /dev/null 2>&1

ip route add $P1_NET dev $IF1 src $IP1 > /dev/null 2>&1
ip route add $P2_NET dev $IF2 src $IP2 > /dev/null 2>&1

ip route add default via $GW1 > /dev/null 2>&1

ip rule add from $IP1 table $pr1 > /dev/null 2>&1
ip rule add from $IP2 table $pr2 > /dev/null 2>&1

ip route add $P0_NET dev $IF0 table $pr1 > /dev/null 2>&1
ip route add $P2_NET dev $IF2 table $pr1 > /dev/null 2>&1
ip route add 127.0.0.0/8 dev lo table $pr1 > /dev/null 2>&1
ip route add $P0_NET dev $IF0 table $pr2 > /dev/null 2>&1
ip route add $P1_NET dev $IF1 table $pr2 > /dev/null 2>&1
ip route add 127.0.0.0/8 dev lo table $pr2 > /dev/null 2>&1
metal-psix ()
Ответ на: комментарий от metal-psix

Чего-то напутано, дальше некуда. Давайте схему, и лучше с ip адресами (внешние замаскарадьте), а то вдруг у вас сети пересекаются. будем с нуля разбирать.
ЗЫ Да и localnet нафига ?

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

vars

#!/bin/bash

# LAN interface
IF0="eth1"
# WAN interface 1
IF1="eth2"
# WAN interface 2
IF2="eth0"

# ip interfeisov
IP1="178.хх.хх.54"
IP2="175.хх.хх.2"

# gateway 1
GW1="178.хх.хх.1"
# gateway 2
GW2="175.хх.хх.1"


# LAN netmask
P0_NET="172.хх.хх.0/24"
# WAN1 netmask
P1_NET="178.хх.хх.0/23"
# WAN2 netmask
P2_NET="175.хх.хх.0/24"

# provaider tables
pr1="prov1"
pr2="prov2"

И еще вопросик немного не по теме.
Как можно проверить вывод команды? Ну например

if ip route | grep !'lalala' > /dev/null; then 
blalala
Это правильная проверка отрицания или есть более надежные конструкции?

metal-psix ()
Ответ на: комментарий от metal-psix

1. Ми просили схему, а то догадываться уже тяжеловато :)
2. Нет. Опять-таки чего достигнуть хотим?

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

1. Схема: не понимаю :) Схема сети или как должен работать скрипт?
2. Хочу достигнуть проверки вывода команды и если там такой строчки не существует, то проделать какие-то действия. А как правильно можно проверить?

metal-psix ()
Ответ на: комментарий от anc

1. Есть 3 сетевушки. Локалка и 2 провайдера. + 2 vpn: 1-клиент, 2-сервер. vpn маршруты падают в main. Где-то попадал на то, что это не оч правильно и лучше создать отдельную таблицу с правилом.
2. Спасибо :)

metal-psix ()
Ответ на: комментарий от metal-psix

Вот, а теперь все тоже самое в виде схемки и ip адресами. Повторюсь перечитывать кусками и догадываться тяжело. Лучше задачу с нуля начать.

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

1. переменные: файл vars

#!/bin/bash

# LAN interface
IF0="eth1"
# WAN interface 1
IF1="eth2"
# WAN interface 2
IF2="eth0"

# ip interfeisov
IP1="178.хх.хх.54"
IP2="175.хх.хх.2"

# gateway 1
GW1="178.хх.хх.1"
# gateway 2
GW2="175.хх.хх.1"


# LAN netmask
P0_NET="172.хх.хх.0/24"
# WAN1 netmask
P1_NET="178.хх.хх.0/23"
# WAN2 netmask
P2_NET="175.хх.хх.0/24"

# provaider tables
pr1="prov1"
pr2="prov2"
2. маршруты: файл routing.sh
#!/bin/bash

. /usr/sbin/vars

echo "1" > /proc/sys/net/ipv4/ip_forward

ip route add $P1_NET dev $IF1 src $IP1 table $pr1 > /dev/null 2>&1
ip route add default via $GW1 table $pr1 > /dev/null 2>&1
ip route add $P1_NET dev $IF2 src $IP2 table $pr2 > /dev/mull 2>&1
ip route add default via $GW2 table $pr2 > /dev/null 2>&1

ip route add $P1_NET dev $IF1 src $IP1 > /dev/null 2>&1
ip route add $P2_NET dev $IF2 src $IP2 > /dev/null 2>&1

ip route add default via $GW1 > /dev/null 2>&1

ip rule add from $IP1 table $pr1 > /dev/null 2>&1
ip rule add from $IP2 table $pr2 > /dev/null 2>&1

ip route add $P0_NET dev $IF0 table $pr1 > /dev/null 2>&1
ip route add $P2_NET dev $IF2 table $pr1 > /dev/null 2>&1
ip route add 127.0.0.0/8 dev lo table $pr1 > /dev/null 2>&1
ip route add $P0_NET dev $IF0 table $pr2 > /dev/null 2>&1
ip route add $P1_NET dev $IF1 table $pr2 > /dev/null 2>&1
ip route add 127.0.0.0/8 dev lo table $pr2 > /dev/null 2>&1
3. Скрипт для проверки состояния каналов. Файл: check.sh
#!/bin/bash

. /usr/sbin/vars

OLDIF1=0
OLDIF2=0

LOG='/var/log/providers'

. /usr/sbin/routing.sh
while true; do

ping -c 3 -s 100 $GW1 -I $IF1 > /dev/null
if [ $? -ne 0 ]; then
        echo $(date +%D-%T) prov1 is down!!! >> $LOG
        NEWIF1=0
else
        NEWIF1=1
fi

ping -c 3 -s 100 $GW2 -I $IF2 > /dev/null
if [ $? -ne 0 ]; then
        echo $(date +%D-%T) prov2 is down!!! >> $LOG
        NEWIF2=0
else
        NEWIF2=1
fi

if (( ($NEWIF1!=$OLDIF1) || ($NEWIF2!=$OLDIF2) )); then
        echo $(date +%D-%T) Changing channels >> $LOG

elif (( ($NEWIF1==1) && ($NEWIF2==0) )); then
        echo $(date +%D-%T) All clients routes to prov1 >> $LOG
        ip route delete default
        ip route add default via $GW1 dev $IF1
        ip route flush cache
        systemctl restart openvpn@server.service
        systemctl restart openvpn@client.service
elif (( ($NEWIF1==0) && ($NEWIF2==1) )); then
        echo $(date +%D-%T) All clients routes to prov2 >> $LOG
        ip route delete default
        ip route add default via $GW2 dev $IF2
        ip route flush cache
        systemctl restart openvpn@server.service
        systemctl restart openvpn@client.service

else
echo > /dev/null
fi

OLDIF1=$NEWIF1
OLDIF2=$NEWIF2
sleep 3
done
4. Есть 3 сетевушки. Локалка и 2 провайдера. + 2 vpn: 1-клиент, 2-сервер. vpn маршруты падают в main. Интернет ходит через локалку, к удалённым офисам через vpn. Маршруты vpn прописаны в конфиг файлах.
Хочу добиться от сего чуда: резервирования. То есть пока основной канал живой, значит на нём и оставаться, если упал, то переключиться на резервный и ждать пока основной канал появится. Как только он появляется, переключиться на него и забыть про резервный :) Надеюсь схема не принципиальна :)

metal-psix ()
Ответ на: комментарий от metal-psix

Схема это схема... простите за тавтологию. Можно даже здесь варганить, но лучше нарисовать. Т.е. исходные вводные, с интерфейсами и адресами.
ЗЫ После этого и парсить скрипты даже вам легче станет.

anc ★★★★★ ()
Ответ на: комментарий от metal-psix

попробуй адаптировать под себя, так как это не линукс, но твоей логике соответствует и проще.

#!/bin/sh

default_gw="x.x.x.x"
backup_gw="y.y.y.y"

change () {
route change default $1
}

check () {
if ping -q -c 3 8.8.8.8 > /dev/null; then
  echo "Default GW and Internet is OK"
  exit 0
else
  echo "Some problem with Default connection"
  change $backup_gw
fi
}

while :; do

current_gw=$(netstat -rn | head -5 | tail -1 | awk '{print $2}')

case $current_gw in
  $default_gw) check
  ;;
  $backup_gw) change $default_gw; check
  ;;
esac

sleep 5
done

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

Извините конечно, но что там рисовать? прямоугольник с 2-мя внешними сосками и одной внутренней? Я вроде понимаю суть происходящего, но не понимаю как это пофиксить из-за недостатка знаний в баше, т.к. это первый нормальный скрипт в моей практике, до этого максимум, что делал так это пинговалка состоящая из 4 строчек :)

metal-psix ()
Ответ на: комментарий от metal-psix

это конкретно подходит в моем случае. в вашем надо изменить функции check, change, default_gw и вписать туда недостающие действия при этом оставив логику неизменной.

nerve ★★ ()
Ответ на: комментарий от metal-psix

Выше писал «routing.sh» «весьма забавный», поэтому и предложил начать с нуля.
Нет, вот серьезно, вы хоть сами понимаете что там написано? Если нет, то наверное последний раз предлагаю начать со схемы.

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

И по другому, я незнаю откуда вы это скопипастили, но это очень плохие скрипты.
ЗЫ Вы его точно не читали /dev/mull как бэ намекает.

anc ★★★★★ ()
Ответ на: комментарий от anc
#!/bin/bash

. /usr/sbin/vars

echo "1" > /proc/sys/net/ipv4/ip_forward

ip route add $P1_NET dev $IF1 src $IP1 table $pr1 > /dev/null 2>&1 # инфа о сети первого провайдера в таблице для первого провайдера
ip route add default via $GW1 table $pr1 > /dev/null 2>&1 # дабвление дефолтного гейта первого провайдера в таблицу первого провайдера.
ip route add $P1_NET dev $IF2 src $IP2 table $pr2 > /dev/null 2>&1 # инфа о сети первого провайдера в таблице для второго провайдера 
ip route add default via $GW2 table $pr2 > /dev/null 2>&1 # Добавление дефолтного гейта в таблицу второго провайдера

ip route add $P1_NET dev $IF1 src $IP1 > /dev/null 2>&1 # добавление в основную таблицу адресов. сеть на первого провайдера
ip route add $P2_NET dev $IF2 src $IP2 > /dev/null 2>&1 # добавление в основную таблицу адресов. сеть на второго провайдера

ip route add default via $GW1 > /dev/null 2>&1 # основной гейт для общей таблицы

ip rule add from $IP1 table $pr1 > /dev/null 2>&1 # все пакеты от ip адреса первого провайдера маршрутизировать по таблице prov1
ip rule add from $IP2 table $pr2 > /dev/null 2>&1 #все пакеты от ip адреса второго провайдера маршрутизировать по таблице prov2

ip route add $P0_NET dev $IF0 table $pr1 > /dev/null 2>&1 # добавление в первую таблицу информации о том, что у нас существует локальная сеть.
ip route add $P2_NET dev $IF2 table $pr1 > /dev/null 2>&1 # добавление в первую таблицу информации о том, что у нас существует сеть второго провайдера
ip route add 127.0.0.0/8 dev lo table $pr1 > /dev/null 2>&1 
ip route add $P0_NET dev $IF0 table $pr2 > /dev/null 2>&1 # добавление во вторую таблицу информации о том, что у нас существует локальная сеть.
ip route add $P1_NET dev $IF1 table $pr2 > /dev/null 2>&1 # добавление в вторую таблицу информации о том, что у нас существует сеть первого провайдера
ip route add 127.0.0.0/8 dev lo table $pr2 > /dev/null 2>&1

Теперь мы можем закрыть вопрос со схемами? :) А перейдём непосредственно к скрипту проверки? Возможно там что-то неправильно или много лишнего, но в силу того что я как бы не супер хацкер и вообще себя таким не считаю, прошу не ругайтесь, а просто подскажите как мне преодолеть это всё?

P.S. Чувствую себя как на экзамене :)

metal-psix ()
Ответ на: комментарий от metal-psix

Похоже вы так и не поняли, да в попу скрипт, давайте задачу вашу решим :) А вы все скрипт скрипт :)

anc ★★★★★ ()
Ответ на: комментарий от metal-psix

Чуть в продолжение «мулов» этот тот момент который с самого начала, а вы его даже прокомментировали:
ip route add $P1_NET dev $IF2 src $IP2 table $pr2 > /dev/null 2>&1 # инфа о сети первого провайдера в таблице для второго провайдера
Нафейхуа?

anc ★★★★★ ()
Ответ на: комментарий от metal-psix

Ну да, смотрите вы заворачиваете сеть провайдера1 через сеть провайдера2, при этом выше есть такое же правило где таже сеть завернута через провайдера1

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

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

#!/bin/bash

# LAN interface
IF0="eth1"
# WAN interface 1
IF1="eth2"
# WAN interface 2
IF2="eth0"

# ip interfeisov
IP1="178.хх.хх.54"
IP2="175.хх.хх.2"

# gateway 1
GW1="178.хх.хх.1"
# gateway 2
GW2="175.хх.хх.1"


# LAN netmask
P0_NET="172.хх.хх.0/24"
# WAN1 netmask
P1_NET="178.хх.хх.0/23"
# WAN2 netmask
P2_NET="175.хх.хх.0/24"

# provaider tables
pr1="prov1"
pr2="prov2"

#!/bin/bash

. /usr/sbin/vars

echo "1" > /proc/sys/net/ipv4/ip_forward

ip route add $P1_NET dev $IF1 src $IP1 table $pr1 > /dev/null 2>&1
ip route add default via $GW1 table $pr1 > /dev/null 2>&1
ip route add $P2_NET dev $IF2 src $IP2 table $pr2 > /dev/null 2>&1
ip route add default via $GW2 table $pr2 > /dev/null 2>&1

ip route add $P1_NET dev $IF1 src $IP1 > /dev/null 2>&1
ip route add $P2_NET dev $IF2 src $IP2 > /dev/null 2>&1

ip route add default via $GW1 > /dev/null 2>&1

ip rule add from $IP1 table $pr1 > /dev/null 2>&1
ip rule add from $IP2 table $pr2 > /dev/null 2>&1

ip route add $P0_NET dev $IF0 table $pr1 > /dev/null 2>&1
ip route add $P2_NET dev $IF2 table $pr1 > /dev/null 2>&1
ip route add $P0_NET dev $IF0 table $pr2 > /dev/null 2>&1
ip route add $P1_NET dev $IF1 table $pr2 > /dev/null 2>&1
#!/bin/sh

. /usr/sbin/vars

LOG='/var/log/providers'
. /usr/sbin/routing.sh

while true; do

if !( ip route | grep 'default via $GW1 dev eth2' > /dev/null ); then
        if ip route | grep 'default via $GW2' > /dev/nul; then
                ping -c 3 -I eth2 $GW1 > /dev/null
                        if [ $? -eq 0 ]; then
                                echo $(date +%D-%T) prov1 is up!!! Change from prov2 to prov1 >> $LOG
                                ip route delete default
                                ip route add default via $GW1 dev $IF1
                                ip route flush cache
                                systemctl restart openvpn@client.service
                                systemctl restart openvpn@server.service
                        else
                                echo > /dev/null
                        fi
        else
                        echo $(date +%D-%T) prov1 is down!!! Change to prov2 >> $LOG
                        ip route delete default
                        ip route add default via $GW2 dev $IF2
                        ip route flush cache
                        systemctl restart openvpn@client.service
                        systemctl restart openvpn@server.service
        fi
else
echo > /dev/null
fi
sleep 3
done

И еще вопрос. Ну так на будущее :) В конструкции if/then/else. Else обязателен или можно его опустить?

metal-psix ()
Ответ на: комментарий от metal-psix

Вот это

ip route add $P0_NET dev $IF0 table $pr1 > /dev/null 2>&1
ip route add $P0_NET dev $IF0 table $pr2 > /dev/null 2>&1
точно надо?

В конструкции if/then/else. Else обязателен или можно его опустить?

необязателен.

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