![]() |
Здравствуйте, гость ( Вход | Регистрация )
Этот раздел предназначен для публикации различных статей мануалов и руководств по Ubuntu Linux. Иногда просто сталкиваешься с похожими задачами в тех или иных местах, и, как это не печально, когда что-то забыл приходится каждый раз спрашивать Яндекс / Google, поэтому этот подраздел это всего лишь попытка сделать некоторый сборник решений для наиболее часто возникающих задач, чтобы впоследствие можно было обращаться сюда.
![]() ![]() |
![]() |
![]()
Сообщение
#1
|
|
![]() Администратор ![]() ![]() ![]() ![]() ![]() Группа: Главные администраторы Сообщений: 14349 Регистрация: 12.10.2007 Из: Twilight Zone Пользователь №: 1 ![]() |
Объединение пропускной способности двух интернет каналов и простая отказоустойчивость
(с) http://habrahabr.ru/blogs/linux/54748/ Есть у меня своя домашняя сеть, с linux сервером, и подключена она к интернет с помощью беспроводного соединения — на крыше антена и роутер, к серверу подключено витой парой. Все вобщем то неплохо, канал с гарантированой полосой в обоих направлениях, постоянный IP адрес, довольно надежный — падает редко. Но вот есть у него один минус — цена кусается. Ценовая политика провайдера построена так, что для того, чтоб увеличить скорость в два раза — платить тоже надо в два раза больше. А скорости хочется больше! И надежности тоже — как то во время сильных заморозков роутеру стало «холодно» и интернета вечером и ночью небыло. Поэтому задумал я провести домой второй интернет-канал, выбар пал на одного известного на Украине провайдера, предоставляющего доступ по ADSL. У него и тарифы недорогие и модем ADSL стоит недорого. Так я и сделал, подключился, воткнул ADLS модем в свич — все работает. Но от старого доброго беспроводного канала отказываться мне нехотелось, поэтому задумал я сделать так, чтоб интернет трафик шел сразу по обеим каналам, так, чтоб я мог воспользоваться суммарной пропускной способностью. Да еще и чтоб при падении одного канала всю нагрузку на себя брал другой. После поиска в интернете я выснил, что есть как минимум два решения: — на уровне файрвола раскидывать TCP сессии по разным интерфейсам. Недостатки — сайты, которые имею привязку сессий к IP адресу перестанут работать, так как последовательные запросы от одного пользователя могут приходить по разным каналам и с разных IP. — на уровне маршрутизации раскидывать маршруты через разные интерфейсы. Проблем перового решения небудет, так как маршруты кешируются и последующие обращения к одному адресу будут идти через один и тот же интерфейс. Но балансировка будет не такая точная, и качая с одного сервера даже в несколько потоков не удастся достигнуть суммарной скорости двух каналов. Я выбрал для себя балансировку с помощью маршрутизации, так как мне была очень важна стабильная работа всех сайтов, ну и эта функциональность уже была в моем ядре, а файрвол пришлось бы патчить. Итак, приступим! Для начала определим переменные: $ cat /etc/balance/vars Код #!/bin/bash # LAN interface IF0="eth1" # WAN interface 1 IF1="eth0" # WAN interface 2 IF2="ppp0" IP1="194.9.xx.xx" IP2="`ip addr show $IF2 | grep inet | awk '{print $2}'`" # gateway 1 P1="194.9.xx.xx" # gateway 2 P2="195.5.xx.xx" # LAN netmask P0_NET="192.168.0.0/24" # WAN1 netmask P1_NET="194.9.xx.xx/xx" # WAN2 netmask P2_NET="195.5.xx.xx/xx" TBL1="provider1" TBL2="provider2" # Realtive weight of channels bandwidth W1="2" W2="1" Добавим в файл /etc/iproute2/rt_tables две дополнительные таблицы маршрутизации: echo "1 provider1" >> /etc/iproute2/rt_tables echo "2 provider2" >> /etc/iproute2/rt_tables Теперь напишем скрипт, который будет прописывать все необходимые маршруты и правила файрвола: cat /etc/balance/routing.sh Код #!/bin/bash . /etc/balance/vars echo "1" > /proc/sys/net/ipv4/ip_forward ip route add $P1_NET dev $IF1 src $IP1 table $TBL1 > /dev/null 2>&1 ip route add default via $P1 table $TBL1 > /dev/null 2>&1 ip route add $P2_NET dev $IF2 src $IP2 table $TBL2 > /dev/null 2>&1 ip route add default via $P2 table $TBL2 > /dev/null 2>&1 ip route add $P1_NET dev $IF1 src $IP1 > /dev/null 2>&1 ip route add $P2_NET dev $IF2 src $IP2 ip route add default via $P1 > /dev/null 2>&1 ip rule add from $IP1 table $TBL1 > /dev/null 2>&1 ip rule add from $IP2 table $TBL2 > /dev/null 2>&1 ip route add $P0_NET dev $IF0 table $TBL1 > /dev/null 2>&1 ip route add $P2_NET dev $IF2 table $TBL1 > /dev/null 2>&1 ip route add 127.0.0.0/8 dev lo table $TBL1 > /dev/null 2>&1 ip route add $P0_NET dev $IF0 table $TBL2 > /dev/null 2>&1 ip route add $P1_NET dev $IF1 table $TBL2 > /dev/null 2>&1 ip route add 127.0.0.0/8 dev lo table $TBL2 > /dev/null 2>&1 iptables -t nat -F POSTROUTING iptables -t nat -A POSTROUTING -s $P0_NET -o $IF1 -j MASQUERADE iptables -t nat -A POSTROUTING -s $P0_NET -o $IF2 -j MASQUERADE Этот набор команд обеспечивает маршрутизацию ответов через интерфейс, на котором был получен запрос, а так же маскарадинг а обоих интерфейсах. Теперь напишем скрипт, который будет определять, работатет ли тот или иной канал и соответственно менять записи шлюза по умолчанию. $ cat /etc/balance/check.sh Код #!/bin/bash . /etc/balance/vars OLDIF1=0 OLDIF2=0 . /etc/balance/routing.sh while true; do ping -c 3 -s 100 $P1 -I $IF1 > /dev/null if [ $? -ne 0 ]; then echo "Failed IF1!" NEWIF1=0 else NEWIF1=1 fi ping -c 3 -s 100 $P2 -I $IF2 > /dev/null if [ $? -ne 0 ]; then echo "Failed IF2!" NEWIF2=0 else NEWIF2=1 fi if (( ($NEWIF1!=$OLDIF1) || ($NEWIF2!=$OLDIF2) )); then echo "Changing routes" if (( ($NEWIF1==1) && ($NEWIF2==1) )); then echo "Both channels" ip route delete default ip route add default scope global nexthop via $P1 dev $IF1 weight $W1 \ nexthop via $P2 dev $IF2 weight $W2 elif (( ($NEWIF1==1) && ($NEWIF2==0) )); then echo "First channel" ip route delete default ip route add default via $P1 dev $IF1 elif (( ($NEWIF1==0) && ($NEWIF2==1) )); then echo "Second channel" ip route delete default ip route add default via $P2 dev $IF2 fi else echo "Not changed" fi OLDIF1=$NEWIF1 OLDIF2=$NEWIF2 sleep 3 done Работу канала проверяем пингуя шлюз, и если нет ответа на 3 пинга подряд — мы считаем, что канал упал, и соответственно исключаем его из таблицы маршрутизации. Таким образом, если работают оба канала: $ ip route 195.5.xx.xx dev ppp0 proto kernel scope link src 95.133.xx.xx 194.9.xx.xx/xx dev eth0 proto kernel scope link src 194.9.xx.xx 192.168.0.0/24 dev eth1 proto kernel scope link src 192.168.0.75 default nexthop via 194.9.xx.xx dev eth0 weight 2 nexthop via 195.5.xx.xx dev ppp0 weight 1 Итого имеем два default gw, первый с весом 2 и второй с весом 1. Тоесть через первый канал пойдет в два раза больше трафика, чем через второй. Для того, чтобы кастомизировать эти скрипты под ваши нужды необходимо настроить значения в файле vars, остальные скрипты практически не требуют настройки. -------------------- |
|
|
![]() ![]() |
Текстовая версия | Сейчас: 20.4.2025, 3:32 | |
|