Re: Скрипт для переключения между двумя каналами
- From
- Eugene Grosbein (2:5006/1)
- To
- Alexey Markov
- Date
- 2006-12-04T23:18:22Z
- Area
- RU.UNIX.BSD
Reply-To: eugen@grosbein.pp.ru
04 дек 2006, понедельник, в 17:47 KRAST, Alexey Markov написал(а):
AM> В общем, обычная ситуация: два канала, FreeBSD 6.2-RC1 в качестве
AM> рутера/файрвола, и острое желание клиента, чтобы при падении одного
AM> канала клиенты продолжали работать через второй.
AM> В общих чертах реализация ясна: два natd + ipfw fwd в нужном месте,
AM> но наверняка подобная схема у кого-то уже работает. В общем, если
AM> кто-нибудь поделится примером подобного скрипта - буду вам безмерно
AM> благодарен.
Если оба канала от одного провайдера, надо попросить его динамически
анонсировать маршрут в оба канала, это самое прямое решение.
Если от разных, тоже стоит попросить - вдруг дадут? Это тоже лучший
вариант.
Но если оба канала от разных и каждый дает свои адреса
и динамики не дают, то можно сделать так:
1. Пока отложить переключение и настроить просто корректно сеть:
- трансляция на выходе во внешний мир
- ipfw fwd gw1 ip from ip_prov1 to any и ipfw fwd gw2 ip from ip_prov2 to any
Это просто минимальная правильная настройка, чтобы пакеты
через шлюз первого провайдера gw1 шли только в том случае,
когда у них (по любой причине) в source IP получился адрес из блока
первого провайдера, и аналогично со вторым. В частности, это гарантирует
отсутствие проблем с антиспуфингом у провайдеров даже тогда,
когда работают оба канала. Например, первый провайдер - приоритетный
канал, но через канал второго пришел TCP-пакет на выделенный вторым
провайдером адрес и ответ на него должен уходить не в default route
через первый канал, а во второй через policy routing.
2. Теперь, когда пакеты у нас при любом раскладе уйдет верно,
мы можем просто переставлять default route на того провайдера,
который сейчас жив. В моём случае один из каналов - приоритетный,
и если он валялся и поднялся, маршрут на него должен переключиться
все равно. Вот скрипт, если проверка пачкой пингов раз в минуту устраивает,
можно запускать из крона.
#!/bin/sh
PATH=/bin:/sbin:/usr/bin:/usr/sbin
probe() {
# если еще не тестировали, добавить в список протестированных
# и протестировать, а если уже тестировали - вернуть истину
[ "$1" = "$gw2" ] && l=prov2
[ "$1" = "$gw1" ] && l=prov1
if eval [ -z \"\$$l\" ]; then
ping -q -c 10 -i 0.3 -t 3 $1 >/dev/null 2>&1
eval $l=$?
fi
eval return \"\$$l\"
}
switch_d() {
# сменить маршрут и отрапортовать
route -q delete default
route -q add default $1
echo $0: default route changed to $1
}
# в /etc/rc.conf описаны переменные:
# defaultrouter - IP адрес роутера приоритетного канала
# backupdefault - IP адрес роутера резервного канала
# gw1 и gw2 - адреса роутеров провайдеров, один равен defaultrouter,
# второй равен backupdefault, но мы не экономим переменные :-)
# тем более что defaultrouter и backupdefault определены в /etc/rc.conf
# через gw1 и gw2
. /etc/rc.conf || exit 1
gw=`route -n get default | awk '/gateway:/ { print $2}'
if [ "$gw" = '' ]; then
gw=$defaultrouter
route add default $gw
echo $0: no default route, using $gw
fi
if probe $defaultrouter; then
# defaultrouter жив - если текущий шлюз другой, переключиться на default
[ $gw = $defaultrouter ] || switch_d $defaultrouter
else
# defaultroute недоступен - если текущий шлюз это defaultrouter,
# и другой жив, то переключиться на другой,
# иначе нету смысла трепыхаться
[ $gw = $defaultrouter ] && probe $backupdefault && switch_d $backupdefault
fi
# дальше тут идет переконфигурация демонов (типа squid)
# если надо, но это уже у каждого свое.
Eugene
--
Тестоголовые кислое свое брожение приняли за душу, распарывание чрев
своих - за историю, средства, оттягивающие разложение - за цивилизацию...
--- slrn/0.9.8.0 (FreeBSD)
* Origin: Svyaz Service JSC (2:5006/1@fidonet)
SEEN-BY: 50/12 400/814 450/159 1024 461/43 132 640 469/999 4616/3 4625/8
SEEN-BY: 4641/444 5000/76 5000 5006/1 8 9 10 14 15 16 17 5007/1 5010/70
SEEN-BY: 5011/13 5012/46 5015/28 5019/26 5020/18 175 194 400 545 982 1057 1909
SEEN-BY: 5020/1922 2238 2395 2871 4441 5021/29 5025/3 5026/14 45 5027/12
SEEN-BY: 5030/1080 1957 5034/10 13 5035/3 38 5036/1 5045/7 5049/1 5051/15
SEEN-BY: 5054/1 4 8 9 11 28 35 36 37 45 66 67 70 75 84 85 5059/9 5060/88
SEEN-BY: 5061/15 5062/10 5063/3 5064/7 5066/18 5075/5 5076/1 5077/70 5080/1003
SEEN-BY: 5084/9 5085/13 5095/20 5096/18 6001/10
PATH: 5006/1 5020/400 545 5054/1 37