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

При работе с несколькими провайдерами (чаще всего двумя), существует одна очень неприятная проблема. Это некоторые сайты (интернет банки, вконтакте и т.д.) которые начинают сбоить. Сбои происходят из за специфики работы этих сайтов. Есть 2 способа разбалансировать трафик на 2 канала от разных провайдеров не имея при этом автономной системы (AS), это балансировка по пакетам (с помощью iptable), либо балансировка по подключениям (с помощью пакета iproute2). Я использую балансировку с помощью iproute2.

Данные способы балансировки нагрузки и отказоустойчивости замечательно работали еще несколько лет назад, когда интернет был молод и прост, но с увеличением монстроидальных сайтов с АВТОРИЗАЦИЕЙ (это очень важно), данные методы вызывают проблемы. Рассмотрим для примера вконтакте. Авторизация происходит на одном ip, после авторизации пользователя перекидывает, на основной сайт, который имеет другой ip (на самом деле у вконтакте чуть меньше десятка под сетей ip адресов, то есть ip у вконтакте сотни). Далее при перемещению по сайту, вас то и дело перекидывает с одного адреса на другой, и в этот момент, вылезает косяк балансировки — вас выкидывает на страницу авторизации. Это происходит по причине того, что после авторизации между пользователем и сайтом, создается сессия, одним из параметров которой является ваш ip. В один из моментов времени, при очередном переходе пользователя в какой то раздел сайта, имеющего другой ip (например пользователь начал смотреть видео), ваш скрипт балансировки перекидывает работу с этим ip на другой канал. При этом для вконтакте, сессия уже не верна, ведь ip сменился, и пользователя выкидывает на страницу авторизации. Подобно может случатся с множеством крупных сайтов, а так же с интернет банками.

Единственным решением данной проблемы (на сколько я знаю), является заранее заданные маршруты для таких сложных сайтов (то есть железная работа таких сайтов, только через один из каналов). Это создает определенные неудобства, ведь надо выяснить все ip сайта, сделать маршруты, и загрузить их. Именно для упрощения этой задачи, и был написан этот скрипт. Первоначально надо вписать в переменные данные ваших провайдеров (гейты, таблицы маршрутизации). После запуска скрипт спрашивает адрес сайта, а затем предлагает выбрать канал, через который этот сайт будет работать. Можно либо записывать маршруты в файл, либо применять их на лету.

Еще данный скрипт, можно использовать для создания маршрутов к ресурсам, которые быстрее работают через одного из провайдеров (к примеру являются его внутрисетевыми).

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

#!/bin/bash

# Скрипт получает все ip адреса введенного сайта,
# и делает на основе полученных ip правила маршрутизации.
# Скрипт рассчитан на маршрутизацию на 2 канала на основе пакета iproute2.

###############################Переменные################################################

ROOT_UID=0
E_NOTROOT=67

# Наименование первого и второго провайдера через пробел.
PROV1=»Орион»
PROV2=»Растр»

# Файл в котором хранятся маршруты, для авто запуска, если такого файла нет,
# он будет создан.
LIST=»/home/1.rout»

# Гейт (устройство) и таблица маршрутизации через которые работает первый провайдер.
GT1=»eth1″
TB1=»provider1″

# Гейт (устройство) и таблица маршрутизации через которые работает второй провайдер.
GT2=»ppp0″
TB2=»provider2″

###############################Переменные################################################

# Проверка запуска скрипта под root.
if [ «$UID» -ne «$ROOT_UID» ]
then
echo «Для работы сценария требуются права root.»
exit $E_NOTROOT
fi

echo «Введите имя сайта, без http:// и www»

read NAME

IP=»`host -t a $NAME | awk ‘{print $4}’`»

# Более сложный вариант получения IP, не помню зачем я его делал, первый вариант работает так же и короче.
# IP=»`dig $NAME | grep -v .$NAME | sed ‘/ *;/d; /^ *$/d’ | awk ‘{print $5}’`»

# Проверка на наполнение переменной только ip адресам.
# Если вводимого сайта нет, переменная будет отлична от нуля.
N=»`host -t a $NAME | awk ‘{print $4}’ | grep -c ‘^[a-z]’`»
# Можно использовать для проверки, но как то мало в этом смысла. case «$N» in

for Y in $N
do
if [ $Y = 0 ]; then
echo «Переменная IP наполнена»
else
echo «Ошибка наполнения переменной IP. В переменной $N, проверьте адрес сайта. »
exit 0
fi
done
clear

echo «Через какой канал пускать сайт?»

# Меню выбора канала.
OPTIONS=»`echo $PROV1` `echo $PROV2`»
select opt in $OPTIONS; do
if [ «$opt» = «$PROV1» ]; then
for X in $IP
do

# Если раскоментировать строчку ниже, маршруты
# будут применяться сразу же. (Не сохранятся после перезагрузки.)
# ip route add $X dev $GT1 table $TB1

# Выводит на экран записанные маршруты.
echo «ip route add $X dev $GT1 table $TB1»

# Записывает полученные маршруты в файл
# и делает над каждым комментарий с именем сайта.
echo «### $NAME ###» >>$LIST
echo «ip route add $X dev $GT1 table $TB1» >>$LIST
done
exit
elif [ «$opt» = «$PROV2» ]; then
for X in $IP
do

# Если раскоментировать строчку ниже, маршруты
# будут применяться сразу же. (Не сохранятся после перезагрузки.)
#ip route add $X dev $GT2 table $TB2

# Выводит на экран записанные маршруты.
echo «ip route add $X dev $GT2 table $TB2»

# Записывает полученные маршруты в файл
# и делает над каждым комментарий с именем сайта.
echo «### $NAME ###» >>$LIST
echo «ip route add $X dev $GT2 table $TB2» >>$LIST
done
exit
else
clear
echo «Некорректный выбор. Для повтора нажмите Enter.»
fi
done
exit

Смотрите так же:

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *

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