Распределение трафика между каналами для FreeBSD
Опубликовано FreeBSD, Статьи Июль 30, 2010 MarchdЗачастую встречается ситуация, когда имеется 2 канала для выхода в Интернет. Чаще всего для увеличения отказоустойчивасти сервер подключется к 2-м каналам. При этом, один канал работает как основной а второй- в качестве запасного. Но зачастую необходимо распределить трафик между каналами (хотя бы потому, что на каждый канал имеется лимит трафика от провайдера).
Классическим решением работы по двум и более каналам является регистрация автономной системы (AS) и получение сети независимых адресов. Потом по протоколу BGP строятся маршруты прохождения трафика через один или другой канал.
Но регистрация AS и получение независимой сети адресов дело дорогое и достаточно сложное и для организации подкючения корпоративной сети не всегда оправдано. Ведь решить проблему распределения трафика между каналами можно решить с помощью свяки системы NAT и Sorce Routing (маршрутизация по источнику). Кроме того, эта связка позволяет распределить трафик не только на основе пунктов назначения, но и на основе исходных сетей.
Ниже будет показано, как распределять трафик между двумя каналми на основе OC FreeBSD.
Итак, допустим, что имеется два выхода в Интернет:
1. Через интерфейс с IP: 195.1.1.1 c шлюзом 195.1.1.254
2. Через интерфейс с IP: 212.1.1.1 c шлюзом 212.1.1.254
Трудность очевидна: в нормальном режиме (без применения динамической маршрутизации) у OC FreeBSD один шлюз “по умолчанию” (ровн как и у любой другой ОС) и все пакеты “складываются” в этот шлюз. С помощью механизма можно “обходить” шлюз по умолчанию и направлять потоки другие каналы. Для того, чтобы механизм ip forwarding заработал, необходимо включить в ядре FreeBSD опции IPFIREWALL, IP DIVERT, IPFIREWALL_FORWARD. Более подробно, как подготовить ядро, можно прочитать здесь.
После этого появиться возможность применять команду
ipfw fwd < альтернативный шлюз>, которая перенаправляет поток в обход шлюза по умолчанию и вообще статических маршрутов.
В нашем примере, для того чтобы сеть 212.1.2.0/24 “ходила” через интерфейс 212.1.1.1 нужно записать правило (или запустить команду):
ipfw add fwd 212.1.1.254 ip from 212.1.2.0/24 to any
В качестве альтернативного шлюза мы указываем шлюз второго канала.
Приведенный пример показывает как воспользоваться командой ipfw fwd но это применение для сети реальных адресов. Теперь усложним задачу и будем распределять трафик из одной сети с фиктивными адресами (что чаще всего и бывает на практике подключения корпоративных сетей).
Допустим, у нас имеется корпоратвная сеть с адресами 10.1.0.0/16, подключенная к серверу доступа.
Примем первый канал как основной. Для него нужно применить стандартную схему вывода сети в Интернет .
- Default route ставим 195.1.1.254 (route add default 195.1.1.254)
route add default 195.1.1.254 или прописать в /etc/rc.conf defaultrouter=”195.1.1.254″
- запускаем NAT на интерфейсе адреса 195.1.1.1 (например пусть это будет fxp0)
natd -a 195.1.1.1.1
- запускаем нужные правила ipfw divert… порт для NAT используем стандартный.
ipfw add 100 divert natd ip from 10.1.0.0/16 to any
ipfw add 200 divert natd ip from any to 195.1.1.1
После этого сеть 10.1.0.0 будет выходить в Интернет через канал (1).
Теперь запустим еще один демон NAT на другом порту (например 8672):
natd -a 212.1.1.1 -p 8672
Поставим задачу выпустить через альтернативный канал хост 10.1.1.100.
Для этого:
- “Завернем” трафик с хоста 10.1.1.100 в альтернативный NAT
ipfw add 20 divert 8672 ip from 10.1.1.100 to any
- И уже “свернутый” адрес проведем в алтернативный шлюз
ipfw add 50 fwd 212.1.1.254 ip from 212.1.1.1 to any
- Также не забудем “обратный” divert
ipfw add 60 divert 8672 ip from any to 212.1.1.1
Важно, чтобы эти правила шли перед правилами NAT по умолчанию (обратите внимание на нумерацию правил!).
Итак, теперь вся сеть идет через один канал а хост из этой же сети идет через другой. Гибкость написания правил ipfw позволяет задавать любую логику распределения трафика. Для этого нужно лишь вставлять правила отправки на альтернативный NAT (между правилом 20 и 50).
Например:
– отправит часть сети (подсеть класса C) в другой канал.
ipfw add 21 divert 8672 ip from 10.1.2.0/24 to any
ipfw add 21 divert 8672 tcp from 10.1.1.0/16 to any 5190 - отправит трафик ICQ в другой канал.