IP-Балансировка: объединяем несколько интернет-каналов в один Сравнение версий

Различия

Здесь показаны различия между двумя версиями данной страницы.

Ссылка на это сравнение

Предыдущая версия справа и слева Предыдущая версия
Следующая версия
Предыдущая версия
wiki:ip_balancing [2009/11/20 05:56]
ubuntarubuntarQui quaerit, reperit
wiki:ip_balancing [2011/10/05 21:15] (текущий)
AndreiBAAndreiBAAndreiBAФигня случается...
Строка 1: Строка 1:
-====== ​FIXME IP-Балансировка:​ объединяем несколько интернет каналов в один ======+====== IP-Балансировка:​ объединяем несколько интернет-каналов в один ======
  
----- 
  
 ===== Цели и средства ===== ===== Цели и средства =====
-  * Имеется два или более каналов интернет,​работающие на разных интерфейсах +  * Имеется два или более каналов интернет,​ работающие на разных интерфейсах 
-  * Необходимо объединить эти каналы,​увеличив общую скорость интернет,​что может быть полезно для программ,​создающих множественные подключения (Transmission,​aMule и т.д.) +  * Необходимо объединить эти каналы,​ увеличив общую скорость интернет,​ что может быть полезно для программ,​ создающих множественные подключения (Transmission,​ aMule и т.д.) 
-  * В руководстве предлагается 3 способа это сделать.Два из них не требуют дополнительного программного обеспечения,​третий предполагает использование пакета patch-o-matic-ng (последний способ не проверен автором данного руководства)+  * В руководстве предлагается 3 способа это сделать. Два из них не требуют дополнительного программного обеспечения,​ третий предполагает использование пакета patch-o-matic-ng (последний способ не проверен автором данного руководства)
  
 ---- ----
 +
 ===== Способ 1 ===== ===== Способ 1 =====
   - Настройка **iproute2** : Создать в **/​etc/​iproute2/​rt_tables** две таблицы для каждого из провайдеров:​ <code bash>​sudo nano /​etc/​iproute2/​rt_tables</​code><​file>#​   - Настройка **iproute2** : Создать в **/​etc/​iproute2/​rt_tables** две таблицы для каждого из провайдеров:​ <code bash>​sudo nano /​etc/​iproute2/​rt_tables</​code><​file>#​
Строка 22: Строка 22:
 #​1 inr.ruhep #​1 inr.ruhep
 101 FreeNet 101 FreeNet
-102 Wireless</​file>​+102 NLine</​file>​
   - Создать файл /​etc/​routing/​FreeNet.list в него можно дописывать адреса путь к которым будет идти четко через основного провайдера.   - Создать файл /​etc/​routing/​FreeNet.list в него можно дописывать адреса путь к которым будет идти четко через основного провайдера.
   - Создать и запустить данный скрипт,​предварительно отредактировав переменные:​ <code bash>#​!/​bin/​sh   - Создать и запустить данный скрипт,​предварительно отредактировав переменные:​ <code bash>#​!/​bin/​sh
Строка 150: Строка 150:
 W1="​2"​ W1="​2"​
 W2="​1"</​code>​ W2="​1"</​code>​
-  - Добавим в файл /​etc/​iproute2/​rt_tables две дополнительные таблицы маршрутизации:<​code bash>​echo "​1 ​provider1" >> /etc/iproute2/rt_tables +  - Добавим в файл /​etc/​iproute2/​rt_tables две дополнительные таблицы маршрутизации:<​code bash>sudo nano /​etc/​iproute2/​rt_tables</​code><​file>#​ 
-echo "​2 ​provider2" >> /etc/iproute2/rt_tables</​code>​ +# reserved values 
-<note warning>​ведутся работы</​note>+
 +255 local 
 +254 main 
 +253 default 
 +0 unspec 
 +
 +# local 
 +
 +#​1 inr.ruhep 
 +1 provider1 
 +2 provider2</​file>​ 
 +  - Теперь напишем скрипт,​ который будет прописывать все необходимые маршруты и правила файрвола:<​code bash>​sudo nano /​etc/​balance/​routing.sh</​code><​code bash>#​!/​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</​code>​Этот набор команд обеспечивает маршрутизацию ответов через интерфейс,​ на котором был получен запрос,​ а так же маскарадинг на обоих интерфейсах. 
 +  - Теперь напишем скрипт,​ который будет определять,​ работатет ли тот или иной канал и соответственно менять записи шлюза по умолчанию.<​code bash>​sudo nano /etc/balance/check.sh</​code><​code bash>#​!/​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</​code>​Работу канала проверяем пингуя шлюз, и если нет ответа на 3 пинга подряд — мы считаем,​ что канал упал, и соответственно исключаем его из таблицы маршрутизации.Таким образом,​ если работают оба канала:<​code bash>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</​code>​Итого имеем два шлюза, первый с весом 2 и второй с весом 1. Тоесть через первый канал пойдет в два раза больше трафика,​ чем через второй.Для того, чтобы изменить эти скрипты под ваши нужды необходимо настроить значения в файле vars, остальные скрипты практически не требуют настройки. 
 + 
 +---- 
 +===== Способ 3 ===== 
 +В следующем примере понадобится пропатченное ядро Linux с поддержкой **ROUTE** и модулей **nth** или **random**.Эти модули предоставляются пакетом patch-o-matic-ng,​который нужно скачать с репозитория [[http://​www.netfilter.org/​downloads.html#​svn|subversion]] .О том,​как пропатчить ядро и установить требуемый пакет,​смотрите прилагающуюся документацию к нему. 
 + 
 +==== Установка ==== 
 +В следующем примере будем считать,​что имеется три разных интефейса:​ 
 +    * eth0: Проводное соединение,​ 192.168.1.0/​24,​ шлюз 192.168.1.1,​ канал по умолчанию. 
 +    * eth1: Беспроводное соединение 1, 172.16.0.0/​16,​ шлюз 172.16.0.1 
 +    * rausb0: Бесроводное соединение 2, 192.168.0.0/​24,​ шлюз 192.168.0.1  
 +Мы будем использовать **connmark** для привязки соединений к конкретному интерфейсу,​чтобы определённые пакеты были жёстко привязаны к интерфейсу и шли только через него.Балансировка может быть сделана с помощью модуля nth ,а также random.Мы рассмотрим оба случая,​Вы выбирайте тот,​который вам больше нравится. 
 +  * Сначала общие команды для обоих методов:<​code bash># FIXME (тут нужен точный перевод) 
 +# prevent incoming packets on masqueraded connections from being dropped  
 +# as "martians"​ due to the destination address being translated before the 
 +# rp_filter check is performed 
 +echo 0 /​proc/​sys/​net/​ipv4/​conf/​eth1/​rp_filter 
 +echo 0 > /proc/sys/net/​ipv4/​conf/​rausb0/​rp_filter 
 + 
 +# FIXME (тут нужен точный перевод) 
 +# Load protocol-specific connection tracking modules so that new connections 
 +# associated with existing connections have state "​RELATED"​ and inherit the 
 +# same connmark. 
 +modprobe ip_conntrack_ftp 
 + 
 +# Маскарадинг для исходящих соединений на второстепенных интерфейсах 
 +iptables -t nat -A POSTROUTING -o eth1   -s ! 172.16.0.0/​16 ​ -m state --state NEW,RELATED -j MASQUERADE 
 +iptables -t nat -A POSTROUTING -o rausb0 -s ! 192.168.0.0/​24 -m state --state NEW,RELATED -j MASQUERADE 
 + 
 +# Создаём цепочку,​обрабатывающую новые исходящие соединения 
 +iptables -t mangle -N NEW_OUT_CONN 
 + 
 +# Пропустить соединения,​которые мы хотим,​чтобы шли всегда через проводное соединение 
 +iptables -t mangle -A NEW_OUT_CONN -d 192.168.1.0/​24 -j RETURN 
 +iptables -t mangle -A NEW_OUT_CONN -p tcp -m multiport --destination-ports 21,​22,​80,​443,​6667 -j RETURN 
 +iptables -t mangle -A NEW_OUT_CONN -p udp --dport 53 -j RETURN 
 + 
 +# новые исходящие соединения проходят через вышеуказанную цепочку правил 
 +iptables -t mangle -A OUTPUT -o eth0 -m state --state NEW -j NEW_OUT_CONN 
 + 
 +# шлём пакеты через выбранный интерфейс 
 +iptables -t mangle -A OUTPUT -m connmark --mark 2 -j ROUTE --gw 172.16.0.1 --continue 
 +iptables -t mangle -A OUTPUT -m connmark --mark 3 -j ROUTE --gw 192.168.0.1 --continue</​code>​ 
 +  * Метод с помощью **random**:<code bash># 34%  от времени идём через канал по умолчанию 
 +iptables -t mangle -A NEW_OUT_CONN -j CONNMARK --set-mark 0 
 +iptables -t mangle -A NEW_OUT_CONN -m random --average 34 -j RETURN 
 + 
 +# примерно 33% от времени идём через eth1 (50% от оставшейся вероятности) 
 +iptables -t mangle -A NEW_OUT_CONN -j CONNMARK --set-mark 2 
 +iptables -t mangle -A NEW_OUT_CONN -m random --average 50 -j RETURN 
 + 
 +# иначе (примерно 33% от времени) идём через rausb0 
 +iptables -t mangle -A NEW_OUT_CONN -j CONNMARK --set-mark 3</​code>​ 
 +  *  Метод с помощью **nth**:<​code bash># Каждое первое из трёх соединений идёт через канал по умолчанию 
 +iptables -t mangle -A NEW_OUT_CONN -j CONNMARK --set-mark 0 
 +iptables -t mangle -A NEW_OUT_CONN -m nth --counter 1 --every 3 --packet 0 -j RETURN 
 + 
 +# Каждое второе из трёх соединений идёт через eth1 
 +iptables -t mangle -A NEW_OUT_CONN -j CONNMARK --set-mark 2 
 +iptables -t mangle -A NEW_OUT_CONN -m nth --counter 1 --every 3 --packet 1 -j RETURN 
 + 
 +# Каждое третье из трёх соединений идёт rausb0 
 +iptables -t mangle -A NEW_OUT_CONN -j CONNMARK --set-mark 3 
 +iptables -t mangle -A NEW_OUT_CONN -m nth --counter 1 --every 3 --packet 2 -j RETURN</​code>​ 
 +  * Предусмотрим случай,​когда один из интерфейсов перестаёт ​работать (на Debian-системах нужно положить этот скрипт в папку **/​etc/​network/​if-down.d/​** и сделать его исполняемым (**chmod +x**)):<code bash>#!/bin/sh 
 + 
 +if [ "​$IFACE"​ = "​eth1"​ ]; then 
 +  iptables -t mangle -D OUTPUT -m connmark --mark 2 -j ROUTE --gw 172.16.0.1 --continue 2>/dev/null 
 +fi 
 + 
 +if [ "​$IFACE"​ = "​rausb0"​ ]; then 
 +  iptables -t mangle -D OUTPUT -m connmark --mark 3 -j ROUTE --gw 192.168.0.1 --continue 2>/​dev/​null 
 +fi 
 + 
 +exit 0</​code>​ 
 +  * Теперь скрипт в случае,​если интерфейс заработал снова (на Debian-системах нужно положить этот скрипт в папку **/​etc/​network/​if-up.d/​** и сделать его исполняемым (**chmod +x**)): <code bash>#​!/​bin/​sh 
 + 
 +if [ "​$IFACE"​ = "​eth1"​ ]; then 
 +  iptables -t mangle -A OUTPUT -m connmark --mark 2 -j ROUTE --gw 172.16.0.1 --continue 2>/​dev/​null 
 +fi 
 + 
 +if [ "​$IFACE"​ = "​rausb0"​ ]; then 
 +  iptables -t mangle -A OUTPUT -m connmark --mark 3 -j ROUTE --gw 192.168.0.1 --continue 2>/​dev/​null 
 +fi 
 + 
 +exit 0</​code>​ 
 + 
 +---- 
 +===== Ссылки ===== 
 +Оригиналы статей:​ 
 +  - http://​forum.0day.kiev.ua/​index.php?​showtopic=129574 
 +  - http://​habrahabr.ru/​blogs/​linux/​54748/​ 
 +  - http://​tetro.net/​misc/​multilink.html
  
 +===== Обсуждение =====
 +Для обсуждения проблем,​связанных с данным руководством,​предлагаем Вам создать тему на форуме http://​forum.ubuntu.ru (не забудьте,​пожалуйста,​обновить данную статью и добавить тут ссылку на обсуждение)
  
-{{tag> howto}}+{{tag> howto ip-balancing балансировка маршрутизация patch-o-matic-ng Администрирование Server Linux_на_предприятии ​}}