Объединение нескольких каналов Интернет и простейшая балансировка нагрузки. В наше время без Интернета практически никак не обойтись, и чем выше
скорость передачи данных, чем шире канал - тем лучше )
Имея в своем распоряжении всего одну выделеную линию xDSL-115kbp/s я
смог построить небольшую домашнюю сеть,
и дал возможность своим пользователям узнать кто же такой этот WWW.
Но прошло время, и моя выделенка начала потихоньку захлебываться от
того количества запросов, которое неустанно генерировали пользователи
сети.
Что делать?
Безвыходных ситуаций как известно практически не бывает, ну а в данном
случае ответ очевиден - нужен второй, а может и третий канал. Провести
выделенку в наше время проблем особо не составит. У меня на это ушло
меньше недели.
Ну а что дальше?
Как раздавать Интернет с двух каналов?
Просто спаять вместе четыре провода - слишком просто, чтобы быть
правдой. Вот тут мы и имеем несколько реальных направлений для
изысканий.
- Разделить поровну пользователей и использовать два сервера
доступа. Но по каким критериям делить пользователей, и где гарантия,
что пользователи одного канала не начнут интенсивно что-то скачивать
из Интернета, в то время как пользователи второго канала вообще ничего
не будут делать? Этот метод меня изначально не устраивал, и
соответственно рассмотрен не будет.
- Попытаться собрать оба канала в одном сервере и, хотя бы
приблизительно, сбалансировать нагрузку на них. Это, как мне кажеться,
как раз то, что доктор прописал. Но и тут есть несколько вариантов
решения. Самый простой, с помощью Iproute2, на данную тему в Интернете
можно найти несколько вариантов решения. Немного сложнее будет сделать
все это через Iptables, рассмотрим этот вариант более подробно.
Подготовка:
Для реализации этого коварного плана нам понадобиться немного
поработать.
Нам нужно ядро версии Linux 2.6.14.2 которое можно найти на сайте
http://kernel.org , Iptables v.1.3.4 и патчи из набора
"patch-o-matic-ng" которые добавляют поддержку ROUTE, nth и random для
Iptables. Патчи и iptables вы можете найти здесь
http://www.netfilter.org/downloads.html#ftp Описывать процесс
наложения патчей и сборки ядра я думаю нет необходимости.
Установки:
Итак начнем самое интерессное, но сначала определимся с тем, что
имеем.
В силу сложившихся обстоятельств инетернет поступает на сервер с двух
роутеров расстояние между которыми около 1км.
Поэтому была выделена маленькая подсеть именно для транспортировки
трафика на сервер.
Конфигурация компьютера который все это обьединяет вместе.
-eth0 - интерфейс с адресом 192.168.1.1/24 (направленный во внутрь сети).
-eth1 - интерфейс с адресом 192.168.0.1/29 (направленный в транспортную подсеть).
-192.168.0.2/29 и 192.168.0.3/29 - адреса шлюзов.
-192.168.1.2/24 - адрес прокси сервера, который раздает инет пользователям.
Настройки Iptables:
Создаем новую цепочку правил:
iptables -t mangle -N NEW_OUT_CONN
Загоняем все новые соединения в созданную цепочку:
iptables -t mangle -A FORWARD -i eth0 -o eth1 -m state --state NEW -j NEW_OUT_CONN
Далее указываем каким пакетам через какой шлюз уходить:
iptables -t mangle -A POSTROUTING -o eth1 -m connmark --mark 0 -j ROUTE
--gw 192.168.0.2 --continue
iptables -t mangle -A POSTROUTING -o eth1 -m connmark --mark 1 -j ROUTE
--gw 192.168.0.3 --continue
Ну и самое интерессное, маркировка пакетов с использованием NTH
метода:
iptables -t mangle -A NEW_OUT_CONN -j CONNMARK --set-mark 0
iptables -t mangle -A NEW_OUT_CONN -m nth --counter 1 --every 2 --packet 0 -j RETURN
iptables -t mangle -A NEW_OUT_CONN -j CONNMARK --set-mark 1
iptables -t mangle -A NEW_OUT_CONN -m nth --counter 1 --every 2 --packet 1 -j RETURN
В завершении замаскируем уходящие пакеты и перекроем доступ всем кому
ходить сюда не положено:
iptables -t nat -A POSTROUTING -s 192.168.1.2 -o eth+ -j SNAT --to-source 192.168.0.1 iptables -t nat -P POSTROUTING DROP
Вот так все работает у меня.
Для общего развития приведу пример реализации метода RANDOM:
iptables -t mangle -A NEW_OUT_CONN -j CONNMARK --set-mark 0
iptables -t mangle -A NEW_OUT_CONN -m random --average 50 -j RETURN
iptables -t mangle -A NEW_OUT_CONN -j CONNMARK --set-mark 1
Я не утверждаю, что NTH единственно правильный метод, но меня он
устраивает.
В конечном итоге вам решать каким вариантом удобнее пользоваться.
Удачи.