Объединение пропускной способности двух интернет каналов и простая отказоустойчивость

    Есть у меня своя домашняя сеть, с linux сервером, и подключена она к интернет с помощью беспроводного соединения — на крыше антена и роутер, к серверу подключено витой парой. Все вобщем то неплохо, канал с гарантированой полосой в обоих направлениях, постоянный IP адрес, довольно надежный — падает редко. Но вот есть у него один минус — цена кусается.
    Ценовая политика провайдера построена так, что для того, чтоб увеличить скорость в два раза — платить тоже надо в два раза больше. А скорости хочется больше! И надежности тоже — как то во время сильных заморозков роутеру стало «холодно» и интернета вечером и ночью небыло.
    Поэтому задумал я провести домой второй интернет-канал, выбар пал на одного известного на Украине провайдера, предоставляющего доступ по ADSL. У него и тарифы недорогие и модем ADSL стоит недорого. Так я и сделал, подключился, воткнул ADLS модем в свич — все работает. Но от старого доброго беспроводного канала отказываться мне нехотелось, поэтому задумал я сделать так, чтоб интернет трафик шел сразу по обеим каналам, так, чтоб я мог воспользоваться суммарной пропускной способностью. Да еще и чтоб при падении одного канала всю нагрузку на себя брал другой.



    После поиска в интернете я выснил, что есть как минимум два решения:

    — на уровне файрвола раскидывать TCP сессии по разным интерфейсам. Недостатки — сайты, которые имею привязку сессий к IP адресу перестанут работать, так как последовательные запросы от одного пользователя могут приходить по разным каналам и с разных IP.
    — на уровне маршрутизации раскидывать маршруты через разные интерфейсы. Проблем перового решения небудет, так как маршруты кешируются и последующие обращения к одному адресу будут идти через один и тот же интерфейс. Но балансировка будет не такая точная, и качая с одного сервера даже в несколько потоков не удастся достигнуть суммарной скорости двух каналов.

    Я выбрал для себя балансировку с помощью маршрутизации, так как мне была очень важна стабильная работа всех сайтов, ну и эта функциональность уже была в моем ядре, а файрвол пришлось бы патчить.

    Итак, приступим!

    Для начала определим переменные:
    $ cat /etc/balance/vars

    1. #!/bin/bash
    2.  
    3. # LAN interface
    4. IF0="eth1"
    5.  
    6. # WAN interface 1
    7. IF1="eth0"
    8.  
    9. # WAN interface 2
    10. IF2="ppp0"
    11.  
    12. IP1="194.9.xx.xx"
    13. IP2="`ip addr show $IF2 | grep inet | awk '{print $2}'`"
    14.  
    15. # gateway 1
    16. P1="194.9.xx.xx"
    17. # gateway 2
    18. P2="195.5.xx.xx"
    19.  
    20. # LAN netmask
    21. P0_NET="192.168.0.0/24"
    22. # WAN1 netmask
    23. P1_NET="194.9.xx.xx/xx"
    24. # WAN2 netmask
    25. P2_NET="195.5.xx.xx/xx"
    26.  
    27.  
    28. TBL1="provider1"
    29. TBL2="provider2"
    30.  
    31. # Realtive weight of channels bandwidth
    32. W1="2"
    33. 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

    1. #!/bin/bash
    2.  
    3. . /etc/balance/vars
    4.  
    5. echo "1" > /proc/sys/net/ipv4/ip_forward
    6.  
    7.  
    8. ip route add $P1_NET dev $IF1 src $IP1 table $TBL1 > /dev/null 2>&1
    9. ip route add default via $P1 table $TBL1 > /dev/null 2>&1
    10. ip route add $P2_NET dev $IF2 src $IP2 table $TBL2 > /dev/null 2>&1
    11. ip route add default via $P2 table $TBL2 > /dev/null 2>&1
    12.  
    13. ip route add $P1_NET dev $IF1 src $IP1 > /dev/null 2>&1
    14. ip route add $P2_NET dev $IF2 src $IP2
    15.  
    16. ip route add default via $P1 > /dev/null 2>&1
    17.  
    18. ip rule add from $IP1 table $TBL1 > /dev/null 2>&1
    19. ip rule add from $IP2 table $TBL2 > /dev/null 2>&1
    20.  
    21.  
    22. ip route add $P0_NET   dev $IF0 table $TBL1 > /dev/null 2>&1
    23. ip route add $P2_NET   dev $IF2 table $TBL1 > /dev/null 2>&1
    24. ip route add 127.0.0.0/8 dev lo  table $TBL1 > /dev/null 2>&1
    25. ip route add $P0_NET   dev $IF0 table $TBL2 > /dev/null 2>&1
    26. ip route add $P1_NET   dev $IF1 table $TBL2 > /dev/null 2>&1
    27. ip route add 127.0.0.0/8 dev lo  table $TBL2 > /dev/null 2>&1
    28.  
    29. iptables -t nat -F POSTROUTING 
    30. iptables -t nat -A POSTROUTING -s $P0_NET -o $IF1 -j MASQUERADE       
    31. iptables -t nat -A POSTROUTING -s $P0_NET -o $IF2 -j MASQUERADE


    Этот набор команд обеспечивает маршрутизацию ответов через интерфейс, на котором был получен запрос, а так же маскарадинг а обоих интерфейсах.

    Теперь напишем скрипт, который будет определять, работатет ли тот или иной канал и соответственно менять записи шлюза по умолчанию.

    $ cat /etc/balance/check.sh

    1. #!/bin/bash
    2.  
    3. . /etc/balance/vars
    4.  
    5. OLDIF1=0
    6. OLDIF2=0
    7.  
    8. . /etc/balance/routing.sh
    9. while true; do
    10.  
    11.  
    12. ping -c 3 -s 100 $P1 -I $IF1 > /dev/null
    13. if [ $? -ne 0 ]; then
    14.   echo "Failed IF1!"
    15.   NEWIF1=0
    16. else
    17.   NEWIF1=1
    18. fi
    19.  
    20. ping -c 3 -s 100 $P2 -I $IF2 > /dev/null
    21. if [ $? -ne 0 ]; then
    22.   echo "Failed IF2!"
    23.   NEWIF2=0
    24. else
    25.   NEWIF2=1
    26. fi
    27.  
    28. if (( ($NEWIF1!=$OLDIF1) || ($NEWIF2!=$OLDIF2) )); then
    29.   echo "Changing routes"
    30.  
    31.   if (( ($NEWIF1==1) && ($NEWIF2==1) )); then
    32.   echo "Both channels"
    33.   ip route delete default
    34.   ip route add default scope global nexthop via $P1 dev $IF1 weight $W1 \
    35.     nexthop via $P2 dev $IF2 weight $W2 
    36.   elif (( ($NEWIF1==1) && ($NEWIF2==0) )); then
    37.   echo "First channel"
    38.   ip route delete default
    39.   ip route add default via $P1 dev $IF1
    40.   elif (( ($NEWIF1==0) && ($NEWIF2==1) )); then
    41.   echo "Second channel"
    42.   ip route delete default
    43.   ip route add default via $P2 dev $IF2
    44.   fi
    45.   
    46. else
    47.   echo "Not changed"
    48. fi
    49.  
    50. OLDIF1=$NEWIF1
    51. OLDIF2=$NEWIF2
    52. sleep 3
    53. 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, остальные скрипты практически не требуют настройки.
    Метки:
    Поделиться публикацией
    Комментарии 106
    • +2
      \\ Тоесть через первый канал пойдет в два раза больше трафика, чем через первый.
      Ошиблись.
      • 0
        Спасибо, исправил
      • 0
        У меня еще используются следующие правила (подглядел в каком-то мануале;). На любителя.

        # Silently Drop Stealth Scans
        # All of the bits are cleared
        iptables -A INPUT -p icmp --icmp-type timestamp-request -j DROP
        iptables -A INPUT -p tcp --tcp-flags ALL NONE -j DROP
        # SYN and FIN are both set
        iptables -A INPUT -p tcp --tcp-flags SYN,FIN SYN,FIN -j DROP
        # SYN and RST are both set
        iptables -A INPUT -p tcp --tcp-flags SYN,RST SYN,RST -j DROP
        # FIN and RST are both set
        iptables -A INPUT -p tcp --tcp-flags FIN,RST FIN,RST -j DROP
        # FIN is the only bit set, without the expected accompanying ACK
        iptables -A INPUT -p tcp --tcp-flags ACK,FIN FIN -j DROP
        # PSH is the only bit set, without the expected accompanying ACK
        iptables -A INPUT -p tcp --tcp-flags ACK,PSH PSH -j DROP
        # URG is the only bit set, without the expected accompanying ACK
        iptables -A INPUT -p tcp --tcp-flags ACK,URG URG -j DROP
        • 0
          А зачем старый канал, если уже есть ADSL?
          • 0
            Потому что ADSL у нас для домашних пользователей — до 4 mbps download, а upload всего 512 kbps, а старый добрый беспроводный канал — симметричный, честные 2 mbps. К тому же постоянный реальный IP, чем я пользуюсь, чтобы хостить у себя на сервере пару страничек.
            • 0
              Как резервный.
              • +5
                АДСЛ «одного известного на Украине провайдера» имеет (при куче положительных моментов в виде цен, доступности почти в любой деревне и относительной стабильности) пару отрицательных моментов в духе «если уж упало в пятницу — до понедельника работать не будет», «если коннектишься вечером в час пик — можно по полчаса ждать выделения IP-адреса, потому как их не хватает» и т.д. Так что пусть будет.
                • +1
                  В точку! :-)
                  • 0
                    Как всё запушено…
                    • –4
                      Ниразу не в точку )
                      Я уже год абонент этого провайдера и проблем с коннектом нет. Бывают моменты, когда что-то не работает… Не без этого!

                      Но чтобы все выходные не было инета или чтобы пол дня коннектиться — такого не было ниразу.

                      ///
                      А по поводу поста — для домашнего пользователя доступна скорость до 8 мбит/с, а отдача — 1 мбит/с.
                      • 0
                        Да, сорри, неучел недавнего изменения тарифных планов…
                        • 0
                          у нас, как минимум, два больших adsl провайдеров. вы про какой?
                          • +1
                            Я видимо чего-то пропустил, а какой второй?
                            • +1
                              укртелеком и фарлеп (вега телеком)
                              • +2
                                Не могу сказать, что Фарлеп очень большой провайдер :)

                                З.Ы. опять заминусуете? )
                                • 0
                                  Ну покрывает крупные города… до ут далеко, наверное, но все-же

                                  Эээээ… про какие минуса идет речь?
                          • +1
                            у меня в городе сельского типа как раз так и работает. При чем будешь звонить в понедельник ругаться типа все выходные небыло инета — они: щас работает? я: да. Они: так в чем проблема. Вот и все. После таких разговоров хочется побить им окна.
                            • 0
                              я кстати не про крупного провайдера. У крупного пока портов нет, жду.
                          • 0
                            неделю линию поднять не могли. подняли. проработала 2,5 дня. сегодня опять упала. Трубку не берут(прячутся наверное).
                            Меня скоро с работы уволят
                            • 0
                              У нас на Кавказе то же самое. Один раз они даже на Новый год нас без проводной связи оставили 10 дней. Общие проблемы… Как у классика — дураки и коммуникационные линии.
                            • 0
                              Он видимо шире
                              • 0
                                Резерв, да и видимо он тоже анлимитный — чтобы скорость была побыстрее чем на одном.
                              • –1
                                А теперь все тоже самое, но для Вендузятников. Кто поможет?
                                • +1
                                  Можно поставить аппаратный девайс, из «подешевле» DLink выпускает. А можно поставить Linux-маршрутизатор на самом убитом железе перед Windows машиной для объединения каналов. У меня все это крутится на Celeron 300 MHz, 256 MB RAM
                                  • 0
                                    А если подключена витая пара, которую свич делит на три канала ( 13 + 2х5 мегабит, 3 статики внешних) оно работать будет?
                                    • 0
                                      Думаю нет, объеденить три канала свичем не получится, желательно иметь три сетевых карты, куда это все будет воткнуто. Хотя… может какими извращениями может удастся и с одной сетевухой.
                                      • 0
                                        Извращения называются Vlan-ами.
                                        Проблема лишь в том, что нужно будет знать номера вланов, хотя сниффером вычислить их не представляет сложности.
                                      • +1
                                        Неуправляемый свич не умеет маршрутизировать, соотв. ничего «делить» он не будет :)

                                        Нужен маршрутизатор либо управляемый коммутатор (с VLAN-ами и load balancing-ом).
                                        • 0
                                          имеете виду Вланы? Тогда работать будет как описано в статье.
                                        • 0
                                          Пользовался ASUS RX3042H для этих целей. Балансировка, failover все работает отлично. Стоит 4000р
                                        • НЛО прилетело и опубликовало эту надпись здесь
                                          • +1
                                            Kerio WinRoute Firewall не ниже 6.5
                                          • +1
                                            Правильный ответ был третий — BGP
                                            • +1
                                              чем поможет BGP без создания AS?
                                              • 0
                                                Private AS?
                                                • 0
                                                  а подробнее?

                                                  Private AS они ж для роутинга в рамках одного провайдера. Интернет о них ничо не знает
                                                  • 0
                                                    можно использовать провайдеров чисто как транспорт до хоста в инете, можно попросить провайдеров согласовать эту AS, можно попросить провайдера одолжить реальную AS, можно самому приобрести AS, можно еще кучу возможностей изыскать, было бы желание.
                                                    • НЛО прилетело и опубликовало эту надпись здесь
                                                      • 0
                                                        Как это может произойти?

                                                        Мне кажется что мало внедрения BGP у клиентов с двумя каналами, т.к. это как правило не требуется малому и среднему бизнесам, а не по каким-то иным техническим причинам. Как правило все ISP идут навстречу.
                                                        • 0
                                                          Каждая AS — это запись в памяти маршрутизатора. Каждого, у которого full-view.

                                                          Память маршрутизаторов — конечна, число AS уже и сейчас крайне велико. Зачастую, слабый маршрутник просто не вытягивает full-view.

                                                          А теперь представьте, что AS — в 10 раз больше… :)
                                                          • 0
                                                            будут ставить в железо не 1 гиг а 32 гига — думаю это не существенная причина для загибания интернета. :)
                                                            • 0
                                                              ну и потом если бы это дело активно использовалось, то можно было бы огромне количество задач решать в private as — прокидывая MPLS между провайдерами например.
                                              • 0
                                                Вы еще сперва с провайдерами договоритесь. Которые априори предоставляют услуги для физических лиц, подразумевая при этом традиционный home use. По крайней мере у нас так.
                                                • 0
                                                  я бы дома вообще не заморачивался такими проблемами, и в любом случае можно было бы договорится — и договаривался когда подключал квартиры-офисы (через физиков), просто стоило денег.
                                              • 0
                                                >> Тоесть через первый канал пойдет в два раза больше трафика,
                                                в два раза больше tcp-сессий
                                                • 0
                                                  Да, надо понимать, что такая балансировка весьма приблизительна.

                                                  >>в два раза больше tcp-сессий
                                                  даже еще более грубо — 2/3 итернета будут открываться через один канал, 1/3 — через другой
                                                  но для торрентов (а это согласитесь основная нагрузка) такой балансировки хватает
                                                  • 0
                                                    эм, я не знаю достаточно вам это или нет. «4» это приблизительно «5», но все же это «4» :)
                                                    • 0
                                                      грубо говоря если с 1 пиром образовалась сессия на 2 гига, это значит статистика будет 2гига-0гигов
                                                • +1
                                                  для балансировки честно скажу — жутко кривое решение с огромной кучей невразумительных последствий. И сессии в http — далеко не единственная проблема. btw wtf with UDP?
                                                  • +1
                                                    Предложите более кошерное, будет интересно послушать. Да, варианты «купить...» или «зарегистрировать..» и пр. прошу не предлогать — рассматривается домашняя сеть.
                                                    • 0
                                                      домой я не стал бы два канала подводить, хотя вероятно имел бы один как запасной.

                                                      Я бы лучше договорился с провайдером на нужную мне скорость. Все равно должно получится дешевле чем у двух провайдеров покупать два канала.
                                                      • 0
                                                        tc
                                                        • 0
                                                          бондинг?
                                                          • 0
                                                            бондинг в данном случае невозможен, разве что сквозь шлюз в инете.
                                                        • 0
                                                          Да, та часть с одновременной работой двух каналов нежизнеспособна. Проверено и не раз.
                                                          Пинг до шлюза — то еще приближение.
                                                          А про UDP — просто, один влево, два вправа, и не «важно», что у них src будет разный. %)
                                                          • 0
                                                            угу, а это большинство voip как минимум
                                                            • 0
                                                              игрушки еще там всякие
                                                              • 0
                                                                С UDP, игрушками и VOIP все просто замечательно! Все это уже работает у меня дома без всяких проблема
                                                                • 0
                                                                  с разных ip-адресов?
                                                                  • 0
                                                                    да, два провайдера, два IP адреса. Все пакеты на один хост в каждый промежуток времени идут только с одного адреса
                                                              • 0
                                                                эм… я тут посмотрел еще раз — соединения(tcp) не отслеживаются, мне кажется будет следующее:
                                                                >> SYN (src A)
                                                                << SYN+ACK (dst A)
                                                                >> ACK (src B)
                                                                << RST (dst A)
                                                                т.е. в пределах сессии пакеты будут отпускаться с разных источников.
                                                                • 0
                                                                  решение о том, через какой канал пойдет пакет принимается на уровне маршрутизации. и без разницы, какой протокол — TCP или UDP — все пакеты к одному хосту пойдут через тот же канал
                                                                  • 0
                                                                    какое дело маршрутизации в данном случае до TCP? У маршрутизации есть пакет, который нужно взять с одного(в данном случае) интерфейса и поставить на другой, причем вы абсолютно однозначно ставите веса, что определяет какой пакет(по факту прибытия) куда пойдет.
                                                                    • 0
                                                                      для объединения каналов тут используется multipath routing — тоесть пакет к серверу A пойдет через один интерфейс, а к серверу B через другой. Через какой интерфейс пойдет пакет к серверу определяется случайно, с учетом весов, и маршрут кешируется, тоесть все последющие пакеты к серверу А идут через тот же интерфейс
                                                                      • 0
                                                                        да, теперь понятно, по сути просто ip route weight. но тогда какой смысл в такой балансировке, просто некая автоматическая случайная разброска путей маршрутизации. Это же нельзя назвать балансировкой.
                                                                        • 0
                                                                          было бы не плохо написать об этом вначале статьи — о методике такого «балансинга».
                                                                        • 0
                                                                          маршрут скешируется и для двух интерфейсов, так ведь?
                                                                          • 0
                                                                            там короче так, приходит ip пакет, роутер смотри на dst, не находит в кеш-таблице такой, и с условием веса кидает на тот или иной интерфейс и отправляет, а dst записывает в кеш, и поэтому все последующие пакеты с 1 белым хостом будут роутится через один gw, пока запись в кеше не протухнет.

                                                                            Т.е. вся процедура проходит не выше сетевого уровня.
                                                                            • 0
                                                                              Надо в очередной раз затестить, посмотреть. Оно работало, но с маркированием пакетов.
                                                                              • 0
                                                                                не, тут другое, пакеты не маркируются.
                                                                                роутер просто помнит что куда отправлял
                                                                  • 0
                                                                    С статье скорее всего это «опущено», по дефолту в iptables стоит пропускать established, просто забыли об этом упомянуть :)
                                                                    • 0
                                                                      -m tcp -p tcp -m state --state ESTABLISHED,RELATED
                                                                      тогда, и только тогда.
                                                            • 0
                                                              Есть еще готовая сборка — Endian Firewall, позволяет это сделать. И многое другое. Очень хорошая штука, мы в студии ее используем.
                                                              • +1
                                                                А как такое на винде провернуть?
                                                                • 0
                                                                  актуальный вопрос для тех не очень близко знаком с изнанкой TCP/IP
                                                                  • 0
                                                                    Раз попробовал. Есть ADSL через раутер раздаваемый по квартире. Воткнул WiFi сетевую, подключился к чей-то сети. И начал наблюдать, что получится. Периодически обрубая то там интернет, то там. Как-то это работало. Какой софт по какому маршруту идет я так и не понял. Но если скажем LAN «лежит» то браузер идет по WiFi, но так на нем и остается. Если выключить WiFi при работающем LAN — браузер не «переключится». Но если его закрыть и запустить по новой — он будет пользоваться тем, что в тот момент работает.

                                                                    ps. Сейчас купил LinkSys — он с альтернативной прошивкой умеет делать то, что тут описано. Но пока руки не дошли разобраться и настроить.
                                                                    • 0
                                                                      Kerio WinRoute Firewall не ниже 6.5 — выше было
                                                                      • 0
                                                                        но там принцип немного иной
                                                                      • 0
                                                                        дешево(бесплатно) но сердито — 3proxy ( 3proxy.ru/howtor.asp#ROUNDROBIN )
                                                                      • 0
                                                                        Большое спасибо. Не сколько за решение, сколько за идею. У нас несколько иная специфика, но ход мысли уловил.
                                                                        • 0
                                                                          Немного не в тему, но:
                                                                          Есть ли возможность для win машины, объеденить два wifi соединения в один? (скорость хочется увеличить, в квартире два wifi роутера, с разными провайдерами)
                                                                          • 0
                                                                            да, поставить маршрутизатор, свою AS, bgp и пиринг с провайдерами.
                                                                            • 0
                                                                              Маршрутизатор — дорого, но можно заменить на OpenBSD + OpenBGPD.

                                                                              AS — public-as вам не дадут в RIPE. Сейчас зарегистрировать систему и получить адресное пространство не просто, а для сетей с планируемым числом адресов менее 512 на практике — практически не возможно.

                                                                              Пиринг с вами ни один серьезный оператор не подпишет, зачем ему это? Телекомы ничего не делают просто так.
                                                                          • 0
                                                                            >>по обеим каналам
                                                                            по обоим каналам
                                                                            • +2
                                                                              спасибо, добавил в мемориз=)
                                                                              • 0
                                                                                Уважаемый, а не подскажите как сделать подобную, но чуть другую вещь.

                                                                                Есть серевер под Linux с двумя белыми IP-адресами. Один — основной для этой машины
                                                                                К нему через VPN цепляется машина, которая получает серый адрес (или как вариант второй белый адрес).
                                                                                Далее необходимо все запросы в инет от этой машины NAT-ить на айпишник сервера, но в то же время, все запросы, пришедшие на второй айпишник натить на эту, подключенную через VPN машинку, и чтобы на коннекты, установленные со второго белого айпишника к ней, она отвечала через него же, а не через NAT.

                                                                                Сижу и думаю… в ядре вроде все есть… conntrack, чтобы отслеживать коннекты, множественные таблицы маршрутизации чтобы гибко рулить коннектами… а вот какими командами заставить сервер делать то, что мне нужно — не знаю.
                                                                                • 0
                                                                                  метить пакеты fwmark, и на основе меток в iproute 2 пускать на разные таблицы
                                                                                  • 0
                                                                                    У меня когда возникла необходимость на одном из iface's делать нат один в один нескольких адресов iptables перестал пускать пакеты по правилам
                                                                                    iptables -A bad_tcp_packets -p tcp --tcp-flags SYN,ACK SYN,ACK -m state --state NEW -j REJECT --reject-with tcp-reset
                                                                                    iptables -A bad_tcp_packets -p tcp! --syn -m state --state NEW -j DROP

                                                                                    Оказалось, что conntrack в данном случае не совсем корректно работал :)
                                                                                    В случае попытки установить соединение с 80.93.57.207 получал следующее:
                                                                                    tcp 6 119 SYN_SENT src=80.93.57.207 dst=10.9.8.203 sport=80 dport=2088 [UNREPLIED] src=10.9.8.203 dst=80.93.57.207 sport=2088 dport=80 use=1
                                                                                    tcp 6 119 SYN_SENT src=192.168.168.203 dst=80.93.57.207 sport=2088 dport=80 [UNREPLIED] src=80.93.57.207 dst=192.168.168.203 sport=80 dport=2088 use=1

                                                                                    С тех пор недоверие есть к iproute2 ;)
                                                                                    Но статья таки полезна :)
                                                                                • –1
                                                                                  Только мне кажется что никаого объединения двух каналов тут не нарисовано

                                                                                  я понимаю что железный вариан решения не спортивен — но может кому нить пригодится? 8))

                                                                                  DI-LB604 Маршрутизатор Express EtherNetwork 4-х портовый c функцией распределения нагрузки — Цена: 3532.29 руб.

                                                                                  зы — если гуглить на «распределение нагрузки» можно найти и за 50 баксов железку
                                                                                  • 0
                                                                                    Понятно, что можно заплатить N баксов и купить железку для чего угодно…
                                                                                    Для тех, кто не верит — вот картинка

                                                                                    Вверху два объединяемях канала (2 и 1 mbps), внизу — график загрузки общего совместного канала (с разбивкой по классам HTB). Как видно загрузка достигает почти 3 mbps
                                                                                    • 0
                                                                                      я не о том работают ли оба канала — 8)

                                                                                      запустите на скачивание по http файл побольше — уроните один канал — потом поднимите — уроните второй
                                                                                      если всё «без разрывов» вы в шоколаде

                                                                                      8)
                                                                                      • 0
                                                                                        так небывает ) да и ненадо это мне например. Большие файлы по HTTP некачаю уже пару лет, торренты с таким обрывами справляются очень легко, чего еще хотеть )))
                                                                                        • 0
                                                                                          Подозреваю, что в домашних условиях, без собственной AS такого и с указанной железкой не добиться.
                                                                                        • 0
                                                                                          мм а что за плагин ггенерировал нижный график… хотелось бы его у себя тоже поднять
                                                                                          • +1
                                                                                            Плагин собственной разработки, визуализирует разбиений трафика на классы шейпера, про него, а так же про шейпинг в линукс планирую в скором времени статью тоже написать

                                                                                            а пока этот плагин можно скачать с сайта munin
                                                                                            • 0
                                                                                              хех полезный плагин… у меня тока чисто статистика по нетфлоу считается, для зашейпленных юзверей…
                                                                                      • 0
                                                                                        Спасибо. У нас в офисе adsl падал постоянно, точнее само ppp соединение, приходилось ifdown; ifup делать, скорее всего из-за китайского модема. Я давно хотел написать скрипт, который сам бы поднимал канал при падении, но всё руки не доходили, да и bash я не так хорошо знаю. В общем спасибо вам за скрипт check.sh.
                                                                                        • +2
                                                                                          Поделюсь своим скриптом. Проверка каналов, на 3 прова. Писалось оч. давно, для тех-же целей.
                                                                                          Основная мысль — пинг 3-х популярных сайтов через шлюзы прова. если потери больше % — канал мертв,- запускаем скрипт переключения.
                                                                                          (сам скрипт есть, но стыдно показывать)

                                                                                          Выкладываю, чтоб умные люди взяли полезные куски и довели до ума )

                                                                                          Если кому интересно — пишите.

                                                                                          #!/bin/sh
                                                                                          PATH="/bin:/sbin:/usr/bin"

                                                                                          # Говорить вместо делать
                                                                                          DEBUG=«0»

                                                                                          # Отчитываться о действиях
                                                                                          REPORT=«0»

                                                                                          # какие хосты пинговать
                                                                                          HOSTS_UP='www.ukr.net www.ya.ru google.ua'

                                                                                          # параметр вызова скрипта переключения, если все ок.
                                                                                          NORM_PROV=multiway

                                                                                          # наш адресс, наш шлюз, хост прова за шлюзом (DNS например) и имя прова (параметр для вызова скрипта)
                                                                                          IP1=«192.168.0.2»
                                                                                          GW1=«192.168.0.1»
                                                                                          H1=«192.168.1.1»
                                                                                          ISP1_name=LOCALNET
                                                                                          DEV1=eth2

                                                                                          #IP2=""
                                                                                          #GW2=""
                                                                                          #H2=""
                                                                                          #ISP2_name=comcom
                                                                                          #DEV2=eth3

                                                                                          #IP3=""
                                                                                          #GW3=""
                                                                                          #H3=""
                                                                                          #ISP3_name=spacegate
                                                                                          #DEV3=pentanet0

                                                                                          # Пингуем 10 раз, если больше 3 потери — плохой канал
                                                                                          PING_COUNT=10
                                                                                          PING_MAX_LOSS=3
                                                                                          PING_OPT="-c$PING_COUNT -s5 -W5 -i1 "

                                                                                          LOGTO="/var/log/switch.log"
                                                                                          dt=`date +"%h %d %X "`

                                                                                          norm=0
                                                                                          prov=`ip rule show | grep «30000» | awk '{print $5}'`
                                                                                          [ $DEBUG = «1» ] && echo «Prov now — $prov»

                                                                                          if [ ${prov} = ${NORM_PROV} ]; then
                                                                                          ISP1_route=0
                                                                                          ISP2_route=0
                                                                                          ISP3_route=0

                                                                                          [ $DEBUG = «1» ] && echo «Route string — `ip route show table $NORM_PROV | grep „dev“ | awk '{print $3}'`»

                                                                                          for def_r in `ip route show table $NORM_PROV | grep «dev» | awk '{print $3}'`; do
                                                                                          [ $DEBUG = «1» ] && echo «Route — $def_r»
                                                                                          if [ ${def_r} = ${GW1} ]; then
                                                                                          ISP1_route=1
                                                                                          [ $DEBUG = «1» ] && echo «Route via curently $ISP1_name on»
                                                                                          fi
                                                                                          if [ ${def_r} = ${GW2} ]; then
                                                                                          ISP2_route=1
                                                                                          [ $DEBUG = «1» ] && echo «Route via curently $ISP2_name on»
                                                                                          fi
                                                                                          if [ ${def_r} = ${GW3} ]; then
                                                                                          ISP3_route=1
                                                                                          [ $DEBUG = «1» ] && echo «Route via curently $ISP3_name on»
                                                                                          fi
                                                                                          done
                                                                                          route_now="${ISP1_route}-${ISP2_route}-${ISP3_route}"
                                                                                          [ $DEBUG = «1» ] && echo «Routes ON $ISP1_name=$ISP1_route; $ISP2_name=$ISP2_route; $ISP3_name=$ISP3_route;»

                                                                                          fi

                                                                                          ISP1_stat=0
                                                                                          ISP2_stat=0
                                                                                          ISP3_stat=0

                                                                                          ### Ping ISP1
                                                                                          for HOST_UP in $HOSTS_UP; do
                                                                                          [ $DEBUG = «1» ] && echo «Executing: ping $PING_OPT -I $IP1 $HOST_UP»
                                                                                          status1=`ping $PING_OPT -I $IP1 $HOST_UP | grep «packet loss»| awk '{print $1-$4}'`
                                                                                          if [ $status1 -lt $PING_MAX_LOSS ]; then
                                                                                          # ISP1 works
                                                                                          ISP1_stat=1
                                                                                          [ $DEBUG = «1» ] && echo "$ISP1_name ok, PacketLoss = $status1"
                                                                                          else
                                                                                          # ISP1_stat=0
                                                                                          if [ ${LOGTO} != 0 ]; then
                                                                                          echo ${dt} "${H1} via ${GW1} — ${status1} packet lost of ${PING_COUNT}" >> ${LOGTO}
                                                                                          fi
                                                                                          [ $DEBUG = «1» ] && echo "$ISP1_name NOT ok, PacketLoss = $status1 of ${PING_COUNT}"
                                                                                          fi

                                                                                          ### Ping ISP2
                                                                                          [ $DEBUG = «1» ] && echo «Executing: ping $PING_OPT -I $IP2 $HOST_UP»
                                                                                          status2=`ping $PING_OPT -I $IP2 $HOST_UP | grep «packet loss»| awk '{print $1-$4}'`
                                                                                          if [ $status2 -lt $PING_MAX_LOSS ]; then
                                                                                          # ISP2 works
                                                                                          ISP2_stat=1
                                                                                          [ $DEBUG = «1» ] && echo "$ISP2_name ok, PacketLoss = $status2"
                                                                                          else
                                                                                          # ISP2_stat=0
                                                                                          if [ ${LOGTO} != 0 ]; then
                                                                                          echo ${dt} "${H2} via ${GW2} — ${status2} packet lost of ${PING_COUNT}" >> ${LOGTO}
                                                                                          fi
                                                                                          [ $DEBUG = «1» ] && echo "$ISP2_name NOT ok, PacketLoss = $status2 of ${PING_COUNT}"
                                                                                          fi

                                                                                          ### Ping ISP3
                                                                                          [ $DEBUG = «1» ] && echo «Executing: ping $PING_OPT -I $IP3 $HOST_UP»
                                                                                          status3=`ping $PING_OPT -I $IP3 $HOST_UP | grep «packet loss»| awk '{print $1-$4}'`
                                                                                          if [ $status3 -lt $PING_MAX_LOSS ]; then
                                                                                          # ISP3 works
                                                                                          ISP3_stat=1
                                                                                          [ $DEBUG = «1» ] && echo "$ISP3_name ok, PacketLoss = $status3"
                                                                                          else
                                                                                          ISP3_stat=0
                                                                                          if [ ${LOGTO} != 0 ]; then
                                                                                          echo ${dt} "${H3} via ${GW3} — ${status3} packet lost of ${PING_COUNT}" >> ${LOGTO}
                                                                                          fi
                                                                                          [ $DEBUG = «1» ] && echo "$ISP3_name NOT ok, PacketLoss = $status3 of ${PING_COUNT}"
                                                                                          fi

                                                                                          done

                                                                                          #########

                                                                                          [ $DEBUG = «1» ] && echo «stat1 ${ISP1_stat}; stat2 ${ISP2_stat}; stat3 ${ISP3_stat}»
                                                                                          [ $DEBUG = «1» ] && echo «route1 $ISP1_route; route2 $ISP2_route; route3 $ISP3_route;»

                                                                                          ########### Now, make decision for routing.
                                                                                          case "${ISP1_stat}" in
                                                                                          1)
                                                                                          [ $DEBUG = «1» ] && echo «1»
                                                                                          if [[ ${route_now} != «1-0-0» ]]; then
                                                                                          [ $REPORT = «1» ] && echo "$dt ALL became ALIVE..."
                                                                                          [ $DEBUG = «1» ] || /wrk/route.sh norm
                                                                                          # [ $DEBUG = «1» ] || ip ro flush cache
                                                                                          # [ $DEBUG = «1» ] || /wrk/sat softrestart
                                                                                          [ $DEBUG = «1» ] && echo «Default NORM»
                                                                                          else
                                                                                          [ $DEBUG = «1» ] && echo «Already OK»
                                                                                          fi;
                                                                                          ;;

                                                                                          0)
                                                                                          [ $DEBUG = «1» ] && echo «0»
                                                                                          if [[ ${route_now} != «0-0-1» ]]; then
                                                                                          [ $REPORT = «1» ] && echo "$dt $ISP1_name died, turning off."
                                                                                          [ $DEBUG = «1» ] || /wrk/route.sh itl
                                                                                          [ $DEBUG = «1» ] || ip ro flush cache
                                                                                          # [ $DEBUG = «1» ] || /wrk/sat softrestart
                                                                                          [ $DEBUG = «1» ] && echo «Default via $ISP2_name & $ISP3_name»
                                                                                          else
                                                                                          [ $DEBUG = «1» ] && echo «Already default route via $ISP2_name & $ISP3_name. Nothing changes.»
                                                                                          fi;
                                                                                          ;;

                                                                                          *)
                                                                                          [ $REPORT = «1» ] && echo «Route Restart.»
                                                                                          [ $DEBUG = «1» ] || /wrk/route.sh restart &

                                                                                          exit 1
                                                                                          esac
                                                                                          #if [ ${ISP1_stat} -eq 1 -a ${ISP2_stat} -eq 0 ]; then
                                                                                          #if [ ${ISP3_stat} -eq 1 ]; then
                                                                                          # echo "$ISP3_name suck"
                                                                                          # /wrk/sat restart
                                                                                          #fi

                                                                                          exit 0
                                                                                          • 0
                                                                                            Огромное спасибо за мануал, поднял у себя двух PPPoE провайдеров описанным способом. Всё работает, но возникла беда с автостартом всей этой системы.

                                                                                            Добавил в crontab для рута:
                                                                                            @reboot /etc/balance/check.sh

                                                                                            После загрузки системы проверяю и вижу:
                                                                                            # ps ax | grep che
                                                                                            1261 ? Ss 0:00 /bin/sh -c /etc/balance/check.sh
                                                                                            1262 ? S 0:00 /bin/bash /etc/balance/check.sh


                                                                                            И интернет на самой машине есть (и на IF1, и на IF2 — всё хорошо), но на IF0 — не раздаётся.

                                                                                            Но стоит мне сделать руками в консоли то, что, казалось бы, уже сделал cron:
                                                                                            # /etc/balance/check.sh

                                                                                            И я сначала вижу такое сообщение:
                                                                                            RTNETLINK answers: File exists

                                                                                            А дальше начинается уже вывод скрипта («Both channels» и пр.) и, что самое главное, на IF0 появляется интернет.

                                                                                            Предположил, что скрипт выполняется слишком «рано» (маскарадить ещё нечего в момент его выполнения), поставил такое в кронтабе:
                                                                                            5 23 * * * /etc/balance/check.sh

                                                                                            И перезапустил машину почти ровно в 23 часа. Вывод перенаправил в файл.

                                                                                            Глянул в 23:10 — в лог скрипт писать начал вовремя, т.е. запустился скрипт своевременно, но интернет не раздаётся. После запуска руками в консоли — всё снова ок.

                                                                                            Подскажите, пожалуйста, в чём магия? А в идеале подскажите правильный способ того, как стартовать всё это хозяйство при загрузке и автоматически перезапускать, если скрипт вдруг когда-то помрёт.
                                                                                            • 0
                                                                                              я стартую скрипт из /etc/rc.local
                                                                                              за год работы еще ни разу скрипт не помирал, там собственно ломаться нечему, поэтому для автоматического перезапуска ничего не придумывал
                                                                                            • +1
                                                                                              Есть еще способ с помощью стандартных средств без скриптов — Ubuntu Bonding.
                                                                                              • 0
                                                                                                Пытался найти подробную информацию про бонинг, так и не понял, будет ли оно работать если две линки от двух разных провайдеров, с разными IP, шлюзами и тд. Вы его на практике использовали? Расскажите подробнее ваши впечатления пожалуйста
                                                                                                • 0
                                                                                                  Bonding для увеличения пропускной способности а не для объединения разных ip. Тоесть если гигабитная сетевуха не справляется с потоком, ставим вторую и делаем bonding, будет 2 гигабитный канал, у обеих сетевух будет один и тотже ip.
                                                                                                • 0
                                                                                                  У этого метода есть большая проблема при настройках по умолчанию. Описал ее тут habrahabr.ru/post/267339
                                                                                                  • 0
                                                                                                    Отличный пост. Попробую сделать подобное на FreeBSD.

                                                                                                    Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.