Четыре модема, один выход: строим пул с балансировкой на Linux
Когда один диалап-модем не тянет офис - ставим четыре и балансируем трафик на Linux. Работало отлично, пока провайдер не поменял маршрутизацию и маршруты по умолчанию не начали конфликтовать.
аналоговый диалап - основной способ подключения офисов к интернету
У клиента - офис человек на двадцать пять, один диалап-канал 33.6 кбит/с и постоянные жалобы что интернет «лагает». Выделенку в этом районе не дают, ADSL тоже нет. Что делать? Ставить несколько модемов и делать из них пул.
Идея не новая - провайдеры так организуют входящие линии уже лет пять. Мы решили сделать то же самое на стороне клиента: четыре аналоговых модема, четыре телефонных линии, один Linux-шлюз, который раскидывает трафик по ним.
Железо. Взяли четыре модема Zyxel Omni 56K - у них репутация была приличная, хотя стоили дороже Acorp. Повесили на COM-порты через PCI-плату расширения (на обычной материнке COM-портов на такое количество не хватает). Шлюз - обычный Pentium II со 128 мегабайтами RAM и несколькими сетевыми картами, на нём Debian Potato.
Подключение. Каждый модем набирает провайдера и получает своё ppp-соединение: ppp0, ppp1, ppp2, ppp3. Каждый через /etc/ppp/peers/ настроен со своим конфигом - отдельный файл на каждое соединение, отдельный скрипт автодозвона на случай обрыва. Главная боль здесь - это провайдерские пулы номеров: иногда один номер отвечал занято, иногда соединение устанавливалось на 24 кбит вместо 33.6. Написали небольшой shell-скрипт, который проверяет что все четыре ppp-сессии живы и при падении любой перезапускает.
Балансировка. Здесь начинается интересная часть. В ядре Linux есть multipath routing - можно прописать несколько маршрутов по умолчанию с разными весами, и ядро будет распределять пакеты между ними. Примерно вот так:
ip route add default \
nexthop dev ppp0 weight 1 \
nexthop dev ppp1 weight 1 \
nexthop dev ppp2 weight 1 \
nexthop dev ppp3 weight 1
Ядро тогда было 2.4, multipath там поддерживался. Балансировка не per-connection, а per-packet - то есть пакеты одного TCP-соединения могут уйти через разные интерфейсы. Это создаёт проблему: некоторые серверы на такое реагировали плохо, особенно те, где серверная сторона привязывалась к IP клиента. Для веба в большинстве случаев всё работало нормально, а вот FTP-сессии иногда разваливались.
Обошли частично через fwmark: почте и FTP прописали фиксированный маршрут через ppp0, весь остальной трафик шёл через multipath. Не идеально, но приемлемо.
Что получили в итоге. Суммарная пропускная способность - четыре канала по 33-36 кбит, итого около 130-140 кбит/с в хороших условиях. На практике меньше, потому что не все линии одновременно держат максимальную скорость, и overhead протоколов тоже съедает часть. Но по ощущениям офис это почувствовал сразу - страницы открывались заметно быстрее, почта ходила без задержек.
Где всё сломалось. Примерно через три недели провайдер поменял у себя маршрутизацию - перенёс клиентов на другой блок адресов. Технически ничего страшного, нам прислали письмо с новыми параметрами. Но когда новые ppp-сессии поднялись, у каждого интерфейса оказался разный gateway из нового диапазона.
В старой конфигурации маршруты по умолчанию через ppp-интерфейсы добавляет pppd сам через директиву defaultroute. С четырьмя соединениями это превратилось в кашу: каждый pppd при поднятии пытался прописать свой маршрут по умолчанию, они конфликтовали, последний выигрывал, а multipath-конфиг уже не работал так как надо. Скрипт автодозвона всё это усугублял - при перезапуске сессии маршруты перетасовывались в непредсказуемом порядке.
Добавили nodefaultroute в конфиги pppd и взяли управление маршрутами полностью на себя: отдельный скрипт проверяет состояние всех четырёх сессий и перестраивает таблицу маршрутов при изменениях. Стало надёжнее, но скрипт получился не самый изящный.
Что стоит помнить. Если делаете NAT через Linux-шлюз и добавляете к нему несколько каналов - отключайте defaultroute в pppd и управляйте маршрутами вручную. Иначе при любом изменении на стороне провайдера получите состояние гонки в таблице маршрутизации, и диагностировать это в три часа ночи по телефону очень весело.
Конфигурация работает, клиент доволен. Но при первой возможности поставим нормальный ADSL-канал - администрировать четыре аналоговые линии это отдельное удовольствие, которое быстро надоедает.
- Списали дорогой маршрутизатор - поставили старый ПК с Linux · 27 февраля 2001
- Переводим шлюз на iptables: две подсети, маскарадинг и первый нормальный конфиг · 14 февраля 2001