Два канала в Интернет, резервирование

Автор: Pafnut Дата: 25.05.2006 17:35 Ситуация такая, есть два ADSL-Ethernet модема, подключенные к провайдерам. К провайдеру модемы подключены по ADSL. К серверу (ASPLinux 9.2, ядро 2.4.22) модемы подключены по Ethernet.

Модемы имеют следующие IP адреса:
Модем 1 - 192.168.1.1
Модем 2 - 192.168.3.1

Сервер имеет три сетевых интерфейса:
eth0 - 192.168.3.33 - подключен к модему 2
eth1 - 192.168.1.33 - подключен к модему 1
eth2 - 192.168.10.254 - подключен к локальной сети предприятия.

С помощью iptables я настроил NAT для интерфейсов eth0 и eth1:
iptables -t nat -A POSTROUTING -o eth0 -j SNAT --to-source 192.168.3.33
iptables -t nat -A POSTROUTING -o eth1 -j SNAT --to-source 192.168.1.33

С помощью iproute2 настроил балансировку нагрузки между двумя модемами:
ip route add default scope global nexthop via 192.168.3.1 dev eth0 weight 1 nexthop via 192.168.1.1 dev eth1 weight 1

всё работает.

Задача: в случае неработоспособности одной из DSL линий выходить в Интернет через другую линию.

Я делал эксперимент: отключал от модема 192.168.3.1 телефонную линию и сервер всёравно пытается перенаправлять запросы пользователей на модем 192.168.3.1.

Собственно вопрос в том, как сделать так чтобы сервер определял, что одна из DSL линий не работает и изменял таблицу маршрутизации.

Способы решения проблемы:

1. Использование протоколов динамической маршрутизации, например RIP.
2. С помощью iptables маркировать icmp пакеты от модемов и дальше запускать скрипт, который будет анализировать эти пакеты и изменять таблицу маршрутизации.

Может есть еще какие-нибудь способы решения этой проблемы?
Если нету, то какой из способов лучше?

спасибо.
Re: Два канала в Интернет, резервирование 26.05.2006 07:45huan не хочется давать глупые советы, но в OSPF решение такой проблемы заложено в принципе. смотри в сторону zebra. RIP вроде так не умеет
Re: Два канала в Интернет, резервирование 27.05.2006 06:08Pafnut ясно, пасиб, будем копать.. =)
Re: Два канала в Интернет, резервирование 27.05.2006 11:57poult А может проще. Я конечно не супер сетевик.
Но если скрипт написать на чем угодно, в котором делать так
ping provider1.net -I 192.168.1.33
и
ping provider2.net -I 192.168.3.33

Нет пинга - нет канала.
Re: Два канала в Интернет, резервирование 27.05.2006 12:54sergeil poult писал(а):

> А может проще. Я конечно не супер сетевик.
> Но если скрипт написать на чем угодно, в котором делать так
> ping provider1.net -I 192.168.1.33
> и
> ping provider2.net -I 192.168.3.33
>
> Нет пинга - нет канала.

IMHO, это единственно-возможное решение, если делать "на коленках"...
А если стандартно, то регистрация автономной ситстемы (AS) и BGP...
Протоколы RIP и OSPF для этих целей не предназначены...
Re: Два канала в Интернет, резервирование 29.05.2006 02:37huan sergeil писал(а):

> Протоколы RIP и OSPF для этих целей не предназначены...
RIP не предназначен. а вот OSPF. делали как то резервирование основного канала (вервки) по радио. резерв автоматом поднимался в течении 30 секунд. строили на зебре. детали уже не помню. было это лет 5 назад
Re: Два канала в Интернет, резервирование 31.05.2006 22:42Pafnut Спасибо всем и особенно poult!
Вот такой вот скриптик получился:

#!/bin/bash

# IP адрес хоста в инете, который будем пинговать
inethost="213.180.204.11"

# Число icmp пакетов, который будут посылаться инет хосту
pcount="10"

# IP адрес DSL модема/шлюза 1
modgw1="192.168.1.1"

# IP адрес DSL модема/шлюза 2
modgw2="192.168.3.1"

# Сетевой интерфейс к которому подключен модем 1
moddev1="eth1"

# Сетевой интерфейс к которому подключен модем 2
moddev2="eth0"

# Про флаги DSL1, DSL2
# DSL1 = 1, если инет хост пингуется через 1 модем
# DSL1 = 0, если модем не пингуется или не пингуется инет хост

# DSL2 = 1, если инет хост пингуется через 2 модем
# DSL2 = 0, если модем не пингуется или не пингуется инет хост


# Определяем есть ли линк с модемами
# Тут можно прописать маршруты к модемам
modem1=$(ping -q -c 1 -i 1 -I $moddev1 $modgw1 | grep '0% packet loss')
modem2=$(ping -q -c 1 -i 1 -I $moddev2 $modgw2 | grep '0% packet loss')

if [ ! -z "$modem1" ]; then
# Связь с 1 модемом ОК
# Полагаем, что DSL1 работает
DSL1=1
else
# Нет связи с 1 модемом
DSL1=0
echo "Нет связи с 1 модемом!"
fi

if [ ! -z "$modem2" ]; then
# Связь со 2 модемом ОК
# Полагаем, что DSL2 работает
DSL2=1
else
# Нет связи со 2 модемом
DSL2=0
echo "Нет связи со 2 модемом!"
fi

ip route del $inethost

#Проверка работоспособности DSL линий

# Если связь с 1 модемом ОК, то пингуем через него инет хост
if [ $DSL1 = 1 ]; then
# Добавляем путь к инет хосту
ip route add $inethost via $modgw1 dev $moddev1
ip route flush cache
ping1=$(ping -q -c $pcount -i 1 -I $moddev1 $inethost | grep '100% packet loss')

ip route del $inethost
ip route flush cache
if [ ! -z "$ping1" ]; then
#DSL 1 - не работает
echo "DSL 1 - не работает!"
DSL1=0
fi
fi


# Если связь со 2 модемом ОК, то пингуем через него инет хост
if [ $DSL2 = 1 ]; then
# Добавляем путь к инет хосту
ip route add $inethost via $modgw2 dev $moddev2
ip route flush cache
ping2=$(ping -q -c $pcount -i 1 -I $moddev2 $inethost | grep '100% packet loss')

ip route del $inethost
ip route flush cache
if [ ! -z "$ping2" ]; then
#DSL 2 - не работает
echo "DSL 2 - не работает!"
DSL2=0
fi
fi

# Удаляем из таблицы маршрутизации шлюз по умолчанию
# Лучше использовать код который будет проверять,
# какие шлюзы по умолчанию прописаны в данный момент
ip route del default

# Проверяем какие DSL линии работают
if [ $DSL1 = 1 -a $DSL2 = 1 ]; then
# Работают обе линии,
# делаем балансировку нагрузки
echo "Работают обе DSL линии!"
ip route add default scope global nexthop via $modgw1 dev $moddev1 weight 1 nexthop via $modgw2 dev $moddev2 weight 1
else
if [ $DSL1 = 1 ]; then
# Работает только DSL1
echo "Работает только DSL1!!!"
ip route add default via $modgw1 dev $moddev1
else
if [ $DSL2 = 1 ]; then
# Работает только DSL2
echo "Работает только DSL2!!!"
ip route add default via $modgw2 dev $moddev2
else
# Обе линии не работают
DSL1=0
fi
fi
fi

# Очищаем кэш таблицы маршрутизации
ip route flush cache


p.s. таблицу маршрутизации менять перед пингами походу обязательно иначе никак чото у меня не получается =)
Re: Два канала в Интернет, резервирование 01.06.2006 09:37poult И тебе спасибо! Заберу себе скрипт. У меня тоже два канала Улыбка
Кстати, как часто планируешь запускать скрипт?
Я как погляжу у тебя часто маршруты убиваются. Это не есть хорошо.
Всетаки с ключом -I ping должен нормально работать и не надо перед пингом дергать таблицу маршрутизации.
Re: Два канала в Интернет, резервирование 01.06.2006 17:03Pafnut По поводу скрипта, нельзя использовать grep 0% packet loss, так как grep это возьмет и при 100% packet loss. Т.е. в этом скрипте када пингуются модемы надо сделать как то по-другому.


Скрипт планирую запускать с помощью cron раз в минуту /etc/crontab:

*/1 * * * * root /root/srvconf/checkwan


я так и не понял прикол ключа -I. Как я понял из своих экспериментов при пинге инет хоста, система маршрутизирует пакет, т.е. передает его на шлюз по умолчанию, и если случится такая ситуация, что
в данный момент установлен не рабочий шлюз по умолчанию (так как 2 модема) то пакеты пойдут к нерабочему шлюзу, а не туда куда -I указывает.

Под словом нерабочий я имею ввиду что у модема не работает DSL линия, а сам модем благополучно соединен с серваком.

Но чтобы во время пингования не трогать шлюзы по умолчанию (они меняются только если какая-то линия заработала или перестала работать) я перед пингом прописываю путь к инет хосту и пингую.

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

Конешно это как то замороченно получилось, я думаю ты прав, должно быть проще решения, в котором может и не придется менять маршруты вовсе. Но в моих экспериментах без изменения маршрутов ничего не получалось (( Если у тебя чтонибуть получиться напиши =)
Re: Два канала в Интернет, резервирование 01.06.2006 17:05Pafnut вот еще по теме статейка: [www.opennet.ru]
Re: Два канала в Интернет, резервирование 02.06.2006 11:07poult Pafnut писал(а):

> По поводу скрипта, нельзя использовать grep 0% packet loss, так
> как grep это возьмет и при 100% packet loss. Т.е. в этом
> скрипте када пингуются модемы надо сделать как то по-другому.
>
>
> Скрипт планирую запускать с помощью cron раз в минуту
> /etc/crontab:
>
> */1 * * * * root /root/srvconf/checkwan
>
>
> я так и не понял прикол ключа -I. Как я понял из своих
> экспериментов при пинге инет хоста, система маршрутизирует
> пакет, т.е. передает его на шлюз по умолчанию, и если случится
> такая ситуация, что
> в данный момент установлен не рабочий шлюз по умолчанию (так
> как 2 модема) то пакеты пойдут к нерабочему шлюзу, а не туда
> куда -I указывает.

Да забыл сказать про еще одну вещь:
Надо добавить в таблицу маршрутизаций такое:

echo 200 vtoroy_kanal_prosto_imya >> /etc/iproute2/rt_tables
ip rule add from 192.168.3.33 table vtoroy_kanal_prosto_imya
ip route add default via 192.168.3.1 dev eth0 table vtoroy_kanal_prosto_imya
ip route flush cache

Вот тогда -I будет работать у пинга. Иначе естесственно при стандартной маршрутизации пакеты будут уходить через дефолтовый гейтвей.




>
> Под словом нерабочий я имею ввиду что у модема не работает DSL
> линия, а сам модем благополучно соединен с серваком.
>
> Но чтобы во время пингования не трогать шлюзы по умолчанию (они
> меняются только если какая-то линия заработала или перестала
> работать) я перед пингом прописываю путь к инет хосту и
> пингую.
>
> Перед пингами менять шлюзы по умолчанию плохо, так как во время
> работы скрипта у пользователей будут глюки и дисконы. А так,
> прописывается только путь к инет хосту через выбранный шлюз и
> дальше инет хост пингуется через этот шлюз.
>
> Конешно это как то замороченно получилось, я думаю ты прав,
> должно быть проще решения, в котором может и не придется менять
> маршруты вовсе. Но в моих экспериментах без изменения маршрутов
> ничего не получалось (( Если у тебя чтонибуть получиться напиши
> =)
>

>
> Сообщение отредактировано (1 июня, 17:06)
Re: Два канала в Интернет, резервирование 02.06.2006 19:23Pafnut poult писал(а):


>
> Да забыл сказать про еще одну вещь:
> Надо добавить в таблицу маршрутизаций такое:
>
> echo 200 vtoroy_kanal_prosto_imya >> /etc/iproute2/rt_tables
> ip rule add from 192.168.3.33 table vtoroy_kanal_prosto_imya
> ip route add default via 192.168.3.1 dev eth0 table
> vtoroy_kanal_prosto_imya
> ip route flush cache
>
> Вот тогда -I будет работать у пинга. Иначе естесственно при
> стандартной маршрутизации пакеты будут уходить через дефолтовый
> гейтвей.


надо будет попробовать, спасибо =) ТЕперь мож действиетльно менять ничего не придется Поражён
Re: Два канала в Интернет, резервирование 02.06.2006 20:34Pafnut poult писал(а):

> Да забыл сказать про еще одну вещь:
> Надо добавить в таблицу маршрутизаций такое:
>
> echo 200 vtoroy_kanal_prosto_imya >> /etc/iproute2/rt_tables
> ip rule add from 192.168.3.33 table vtoroy_kanal_prosto_imya
> ip route add default via 192.168.3.1 dev eth0 table
> vtoroy_kanal_prosto_imya
> ip route flush cache
>
> Вот тогда -I будет работать у пинга. Иначе естесственно при
> стандартной маршрутизации пакеты будут уходить через дефолтовый
> гейтвей.
>
>
>

По поводу этого еще хочеться сказать, что если локальный процесс на серваке захочет обратиться к инету (допустим адрес источника 192.168.3.33) и окажется что шлюз 192.168.3.1 не работает то получится фигня!

Есть такая идея:
на каждую сетевуху подключенную к модемам завести еще по одному дополнительному IP адресу специально для пинга!

Например для eth0:

192.168.3.33
192.168.3.50 - IP только для пинга!


echo 200 vtoroy_kanal_prosto_imya >> /etc/iproute2/rt_tables
ip rule add from 192.168.3.50 table vtoroy_kanal_prosto_imya
ip route add default via 192.168.3.1 dev eth0 table
vtoroy_kanal_prosto_imya
ip route flush cache

И делаем пинг: ping -I 192.168.3.50 yandex.ru

тогда пинг будет идти через таблицу vtoroy_kanal_prosto_imya, а локальные процессы будут
выходить через рабочий шлюз по умолчанию (если такой будет ). А шлюзов у нас может быть и два (балансировка).
Re: Два канала в Интернет, резервирование 03.06.2006 18:30sergeil >
> ping2=$(ping -q -c $pcount -i 1 -I $moddev2 $inethost | grep '100% packet loss')
>
Есть более интересное решение... Hint: используйте код завершения...

man ping
#
Если ping не получает ответных пакетов, то она завершит работу с кодом выхода 1. Если для пакетов указаны count и deadline , но принято менее count пакетов по истечении времени deadline , то программа также завершит рабоут с кодов выхода 1. При других ошибках выход будет произведен с кодом 2. Иначе программа завершает работу с кодом 0. Эти значения позволяют использовать коды выхода для определения работоспособности серверов и компьютеров.
#

Я использую:

#/bin/bash
###############################################################
# Monitor two routes
###############################################################

function logIt()
{
logger -p info -t "ROUTE" "$*"
}

function msg()
{
A="$*"
}

function monitorChannel()
{

export if1ip="xx.xxx.xx.xxx"
export if1gw="xx.xxx.xx.xxy"
export if1dev="eth1"

export if2ip="yyy.yyy.yy.yyy"
export if2gw="yyy.yyy.yy.yyz"
export if2dev="eth2"

# -------------------------------------------------------
# active: 0 = no; 1 = ${if1dev}; 2 = ${if2dev} ; 3 = both
# -------------------------------------------------------
export active=3

export GroundPoint="zzz.zzz.zzz.zzz"
export tcnt=3
export wtime=5

while : ;
do
# msg "-->Wait";
sleep 15;
# msg "-->Go";

ping -n -c $tcnt -w $wtime -I ${if2ip} $GroundPoint > /dev/null
export if2rc=$?
# msg "if2rc = $if2rc"

ping -n -c $tcnt -w $wtime -I ${if1ip} $GroundPoint > /dev/null
export if1rc=$?
# msg "if1rc = $if1rc"

if [ $if1rc -eq 0 -a $if2rc -eq 0 ] ; then
if [ $active -ne 3 ] ; then
# msg "setup -> both";
[ $active -eq 0 ] || ip route del default
ip route add default equalize scope global \
nexthop via ${if2gw} dev ${if2dev} weight 1 \
nexthop via ${if1gw} dev ${if1dev} weight 1
ip route flush cache
export active=3
logIt "==>GU+LN both"
fi
elif [ $if2rc -ne 0 -a $if1rc -ne 0 ] ; then
if [ $active -ne 0 ] ; then
# msg "setup -> nothing"
ip route del default
ip route flush cache
export active=0
logIt "==>NONE"
fi
elif [ $if1rc -eq 0 ] ; then
if [ $active -ne 1 ] ; then
# msg "setup ->LN"
[ $active -eq 0 ] || ip route del default
ip route add default scope global \
nexthop via ${if1gw} dev ${if1dev}
ip route flush cache
export active=1
logIt "==>LN only"
fi
else
logIt "state=ERROR, if1rc=$if1rc, if2rc=$if2rc, active=$active"
fi
done

}

monitorChannel &
RSS-материал