Все названия компаний, мест, адресов, условий организации каналов связи и прочие "персонифицированные" данные, приведенные в данном тексте являются вымыслом и приведены здесь только для удобства понимания ситуации. Более того, описанный здесь пример был собран в лабораторных условиях, что называется "на столе". Однако, это не значит, что такой ситуации не может встретиться в реальности. К слову сказать, примерно подобная схема организации связи между офисами внедряется сейчас мной у одного из клиентов.
Для дальнейшего удобства, дадим интерфейсам имена и присвоим им IP-адреса. Чтобы "за деревьями не потерять леса" будем считать, что все интерфейсы до провайдеров это Ethernet-интерфейсы с маской /24 (и вообще, ситуация обкатывается "на столе", так что мы имеем полное право создать свой Интернет как нам заблагорассудится и задать ему какие угодно адреса).
| Хост | Интерфейс | Краткое имя | IP | IP | Хост | |
|---|---|---|---|---|---|---|
| Tula | 9floor | t9 | 11.2/24 | → | 11.1/24 | Inet |
| InvestCom | ti | 12.2/24 | → | 12.1/24 | ||
| LAN | tl | 8.1/24 | ||||
| pptp Sklad → Tula | ST | |||||
| Sklad | RadioNet | sr | 111.2/24 | → | 111.1/24 | Inet |
| InvestCom | si | 112.2/24 | → | 112.1/24 | ||
| LAN | sl | 9.1/24 | ||||
| pptp Sklad → Tula | ST |
Исходя из тарифных планов и прочих "вводных данных", нам задано, что в каждый конкретный момент VPN должна образовываться только между двумя внешними интерфейсами офисов Tula и Sklad. Ну например, трафик внутри сети провайдера InvestCom практически бесплатный, а между различными провайдерами стоит денег, канал от офиса Tula к провайдеру 9 Этаж очень тонкий и не надежный. Подобные "вводные данные" имеются и по отношению к тому, что является default gateway на каждом из настраиваемых хостов, (или иначе, через кого ходим в интернет в каждом из офисов).
в сухом остатке, имеем (на входе задачи) следующие комбинации организации каналов связи между офисами (в порядке уменьшения их приоритета).
А также, приоритетность линий для выхода в Интернет в офисе Tula:
... и в офисе Sklad:
В качестве граничных маршрутизаторов будем использовать компьютеры с ОС FreeBSD 6.3. Будем использовать статическую маршрутизацию. В качестве фаервола будем использовать ipfw. На внешних интерфейсах будем исползовать NAT: natd. Связь между офисами организуем с помощью Multilink PPtP канала, организованного на обоих концах с помощью mpd5.
После установки FreeBSD сразу поставим следующие приложения из пакаджей:
... из портов:
Обновляем коллекцию портов. Обновляем установленные пакеты:
portupgrade -a.
В описываемом опыте я обновление портов
сделал на более быстром компе. На слабом компьютере мне это делать
не захотелось :)
Так как нам понадобится команда fwd в ipfw, то придется пересобирать ядро, так как такого модуля ядра вроде нет :(.
Пересоберем ядро на более быстром компьютере.
Копируем ядро на более слабый комп:
cd /boot/kernel tar cf k.tar
mv /boot/kernel /boot/kernel.old mkdir /boot/kernel
Канал связи между офисами организуем с помощью Multilink PPtP состоящего из четырех возможных pptp Link-ов (см. рисунок 2). Таким образом мы защищаемся от падения любого из каналов связи до провайдеров на любой из сторон; и, даже, от некоторых вариантов одновременного падения двух каналов (о надежности получившегося канала смотри ниже).
Итак имеем на стороне Tula следующий файл
/usr/local/etc/mpd5/mpd.conf.
(чтобы не усложнять, в приведенных конфигах опущено все, что касается
управления mpd с консоли и web и все что касается сжатия и
шифрования трафика)
На стороне Sklad соответственно имеем файл /usr/local/etc/mpd5/mpd.conf.
Заметим, что так как нам не выгодно распределять трафик по всем Link-ам, в том числе и финансово, то в каждый конкретный момент (в зависимости от ситуации) активным должен быть только один из Link-ов, остальные три Link-а должны гасится (об этом см ниже).
Определим через какой интерфейс выходить в интернет в зависимости от текущего состояния каналов связи
| Состояние интерфейсов | Мощность множества вариантов | Маршрут до defaultgw через | |
|---|---|---|---|
| t9 | ti | ||
| 1 | x | 2 | t.9floor |
| 0 | 1 | 1 | t.invest |
| 0 | 0 | 1 | t.9floor |
| Состояние интерфейсов | Мощность множества вариантов | Маршрут до defaultgw через | |
|---|---|---|---|
| sr | si | ||
| 1 | x | 2 | s.radio |
| 0 | 1 | 1 | s.invest |
| 0 | 0 | 1 | s.radio |
Комментарий к предыдущим двум таблицам: какой-то defgw должен быть определен всегда, иначе не работает наш скрипт "ping-овалка" (см. ниже) (ОС не знает через какой интерфейс слать пакеты в МИР) и дело не доходит даже до ipfw.
Заметим, что в зависимости от ситуации, организация VPN может быть более выгодной совсем не по тем каналам связи, на которые настроены Default Gateway. Чтобы "исправить" это будем исправлять таблицу маршрутизации, добавляя или убирая "уточненный" маршрут до другого офиса. Определим через какие пару интерфейсов должна обеспечиваться связь между офисами (какой из Link-ов мультилинкового канала должен быть активным) в зависимости от текущего состояния каналов связи.
| Работоспособность канала | Мощность множества вариантов | "Уточненный" маршрут | ||||
|---|---|---|---|---|---|---|
| si-ti | sr-ti | sr-t9 | si-t9 | to t.invest | to t.9floor | |
| 1 | x | x | x | 8 | over si_gw | delete |
| 0 | 1 | x | x | 4 | over sr_gw | delete |
| 0 | 0 | 1 | x | 2 | delete | over sr_gw |
| 0 | 0 | 0 | 1 | 1 | delete | over si_gw |
| 0 | 0 | 0 | 0 | 1 | delete | delete |
Обратную маршрутизацию: Tula → Sklad - настраивать не надо, достаточно обеспечить то, чтобы сервисы на внешних интерфейсах хоста Tula отвечали в тот же канал связи, из которого они получают запрос. Об этом подробно написано тут. Нас, в контексте данной статьи, интересуют "правильная" маршрутизация пакетов ICMP эхо-ответ, PPtP и GRE.
Как было сказано выше, нам необходимо ограничивать количество Link-ов из которых в каждый конкретный момент времени состоит наш канал VPN. Если мы не будем ограничивать количество Link-ов PPtP между хостами, то в самой вероятностной ситуации мы получим Multilink из 4-х link-ов PPtP, конфигурация которых отображена на рисунке 3.В результате трафик VPN вместо того, чтобы сосредоточится в Link-е si-ti (а это самый выгодный для нас Link (см. вводные данные)), будет равномерно распределен по всем четырем Link-ам.
Чтобы "побороть" эту ситуацию, нами на хосте Sklad будут использоваться специальные "запретительные" наборы правил в ipfw.
На обоих хостах настраиваем скрипты /etc/rc.d/ipfw, /etc/rc.d/natd1 и /etc/rc.d/natd2 для применения NAT на двух внешних интерфейсах.
Следующие файлы используются на обоих хостах и содержат полезные функции, включаемые в другие скрипты includ-ами.
Прочие файлы используемые на обоих хостах:
Скрипты хоста Tula:
Скрипты хоста Sklad:
Скрипт set_st_vpn.sh в mpd.conf у нас прописан как скрипт, который вызывается в случае, если интерфейс VPN переходит в состояние CLOSE (т.е. по сути когда падает текущий PPtP link). Если бы интерфейсы для подключения к провайдеру интернет у нас тоже формировались демоном mpd, то аналогично можно было бы прописать в mpd.conf и скрипты set_defgw.sh
Однако нам недостаточно производить действия по определению (настройке) каналов связи только в случае падения оных. Необходимо иметь возможность реагировать и на "улучшение" ситуации (например, поднялся более дешевый канал). Для этого будем вызывать эти скрипты из cron.
На хосте Tula добавим в файл /etc/crontab:
#KMN added */1 * * * * root /AnyDir/set_defgw.sh 2> /dev/null > /dev/null
а на хосте Sklad:
#KMN added */1 * * * * root /AnyDir/set_defgw.sh 2> /dev/null > /dev/null */1 * * * * root /AnyDir/set_st_vpn.sh 2> /dev/null > /dev/null
Дольше всего вышеуказанные скрипты выполняются тогда, когда все возможные четыре канала выключены. Поэтому, если у Вас слабый компьютер, то выключите все интерфейсы и через некоторое время посмотрите не станут ли плодится процессы ping. Если станут, то это будет говорить о том, что интервал c которым запускается скрипт в crontab надо увеличить.
| Состояние интерфейсов (код Грея) | PPtP multilinks состоит из Link-ов | Ping -S 192.168.8.1 192.168.9.1 | DefGW на хосте Sklad | DefGW на хосте Tula | |||
|---|---|---|---|---|---|---|---|
| sr | si | t9 | ti | ||||
| 0 | 0 | 0 | 0 | - | 0 | 111.1 | 11.1 |
| 0 | 0 | 0 | 1 | - | 0 | 111.1 | 12.1 |
| 0 | 0 | 1 | 1 | - | 0 | 111.1 | 11.1 |
| 0 | 0 | 1 | 0 | - | 0 | 111.1 | 11.1 |
| 0 | 1 | 1 | 0 | SI_T9 | 1 | 112.1 | 11.1 |
| 0 | 1 | 1 | 1 | SI_TI | 1 | 112.1 | 11.1 |
| 0 | 1 | 0 | 1 | SI_TI | 1 | 112.1 | 12.1 |
| 0 | 1 | 0 | 0 | - | 0 | 112.1 | 11.1 |
| 1 | 1 | 0 | 0 | - | 0 | 111.1 | 11.1 |
| 1 | 1 | 0 | 1 | SI_TI | 1 | 111.1 | 12.1 |
| 1 | 1 | 1 | 1 | SI_TI | 1 | 111.1 | 11.1 |
| 1 | 1 | 1 | 0 | SR_T9 | 1 | 111.1 | 11.1 |
| 1 | 0 | 1 | 0 | SR_T9 | 1 | 111.1 | 11.1 |
| 1 | 0 | 1 | 1 | SR_TI | 1 | 111.1 | 11.1 |
| 1 | 0 | 0 | 1 | SR_TI | 1 | 111.1 | 12.1 |
| 1 | 0 | 0 | 0 | - | 0 | 111.1 | 11.1 |
Все замечательно - работает так как мы и хотели.
Посчитаем надежность нашего VPN. Да простят меня математики, за дилетанство (ну не математик я :). Если я тут сильно накосячил, то прошу сообщить ⇒ немедленно исправлю или уберу, дабы не засорять интернет :)
Допустим надежность каждого интернет-канала = 90%, т.е. вероятность сбоя одного канала p(1chann)= 0,1
В дальнейшем будем предполагать, что падение каналов это события не зависящие друг от друга.
Событие 0 "работают все четыре канала": лень считать вероятность этого события, главное, что связь VPN при этом есть всегда ⇒ вероятность сбоя VPN p(vpn)=0.
Событие 1 "лежит один канал": p(1chann)=0,1. Связь есть всегда ⇒ вероятность сбоя VPN p(vpn)=0.
Событие 2 "лежат два канала": p(2chann)=0,01. VPN не работает только в 2-х случаях из 6-ти ⇒ вероятность сбоя VPN p(vpn)=0,01/3.
Событие 3 "лежат три канала": p(3chann)=0,001. VPN никогда не работает ⇒ p(vpn)=0,001.
Событие 4 "лежат четыре канала": p(4chann)=0,0001. VPN никогда не работает ⇒ p(vpn)=0,0001.
Результирующее событие "Не работает VPN": Событие0 ∪ Событие1 ∪ Событие2 ∪ Событие3 ∪ Событие4 ⇒ p(VPN)=0,01/3+0,001+0,0001=0,0044(3).
Итого получаем, что даже при надежности каналов интернет всего 90% мы имеем VPN с вероятностью сбоя всего 0,44(3)%.
Дата документа: 11.08.09