Информация
На главную Главная

Мой t-cards.ru
Войти Войти
Зарегистрироваться Регистрация

Разное
Форум Форум
Вернуться Форумы на t-cards.ru> Hard"n"Soft
Логин
Пароль
Регистрация Участники Поиск >> FAQ


Сообщения в теме: ""Стрим - бери от жизни все!" или "Linux advanced r..."
11.01.2007 12:06
Admin

Регистрация: 05.10.2005
Проживание: Москва
Сообщения: 272
По умолчанию"Стрим - бери от жизни все!" или "Linux advanced routing дубль 2"

Поставили перед нами такую задачу - при наличии нескольких каналов в интернет разделять по ним нагрузку. Причем не просто разделять по протоколам, типа веб-трафик туды, а почту сюды, а каждое соединение с чередованием пакетов по разным интерфейсам.
Я где-то про это писал, что роутить пакеты можно по маркам от iptables, подробно на этом останавливаться не буду, лишь в общих чертах опишу подводные камни
1. Казалось бы, достаточно каждое новое соединение маркировать путем -j MARK , ан нет, никто не застрахован от того, что последующие пакеты в этом TCP-соединении не пойдут через другой интерфейс, а это недопустимо.
Для этого я нашел в ядре такое действие, как -j CONNMARK - маркирует все соединение! Отлично, будет иметь в виду. Далее.
2. Теперь надо найти средство, позволяющее чередовать пакеты... С этим сложнее, искал долго, есть для iptables такой матч как -m nth, позволяющий чередовать, однако не мог найти патч на ядро 2.6.14 нормальный, а встроенной опции нету. И тут - о щастье - в ядре 2.6.18 обнаружилась опция "statistic" match support! Она включает в себя nth и random. Поясню. Nth позволяет маркировать каждый n-ный пакет, random - путем случайного выбора (но еще можно задавать вероятность). Отлично, это работает, теперь далее.
3. Надо заставить ip route видеть марки, которые мы даем пакетам. Оказалось, что он не видит марки от CONNMARK... Есть над чем подумать! Надо, значит, дополнительно эту TCP-сессию еще промаркировать путем MARK, и предварительно для этого надо проверить, чтоб на пакете стоял connmark.
Опять же в 2.6.18 нашел - m connmark для iptables, супер! Теперь мы такие коненкты промаркируем.
4. Далее дело техники - засунуть пакеты из цепочки OUTPUT (для случая, когда пакеты уходят со шлюза) и цепочки PREROUTING (для транзитных пакетов) в дополнительную цепочку, где будет происходить их маркирование. Но PREROUTING только в интерфейсов, смотрящих в локальную сеть. Это есть.
5. Подсунуть для ip route эти марки.
6. И последнее - все эти манипуляции обернем в rc-скрипт формата gentoo, чтоб поднять/остановить этот роутинг можно было.

Теперь собственно правила, скрипт, требования и т.д...
11.01.2007 12:06
Admin

Регистрация: 05.10.2005
Проживание: Москва
Сообщения: 272
По умолчанию"Стрим - бери от жизни все!" или "Linux advanced routing дубль 2"

Требования - iptables версии 1.3.6 или выше, ядро 2.6.18, пакет iproute2.

Опции, какие необходимо включить в ядре:

<*> "CONNMARK" target support
<*> "MARK" target support

<*> "connmark" connection mark match support
<*> "statistic" match support

<*> Packet mangling

[*] IP: advanced router
[*] IP: policy routing
[*] IP: use netfilter MARK value as routing key

Файл конфига и стартовый скрипт:

# /etc/conf.d/routing
IPTABLES="/sbin/iptables"
#GW="192.168.29.1"
DEVS_INT="eth0 eth1"
DEVS_EXT="ppp1 ppp2 ppp3"
NO_DEST="192.168.0.0/16"



# /etc/init.d/routing
#!/sbin/runscript

opts="start stop restart info"

depend() {
need net
}

info() {
einfo "[iptables]"
$IPTABLES -t mangle -nxvL routing 2> /dev/null
$IPTABLES -t mangle -nxvL routing_n 2> /dev/null
einfo "[rules]"
ip rule list |grep fwmark
einfo "[routes]"

i=1
for d in ${DEVS_EXT}
do
ip route list table $i
i=`expr $i + 1`
done

}
stop() {
ebegin "Stopping advanced router"
$IPTABLES -t mangle -D OUTPUT -j routing 2> /dev/null > /dev/null
for d in ${DEVS_INT}
do
$IPTABLES -t mangle -D PREROUTING -i $d -j routing 2> /dev/null > /dev/null
done
$IPTABLES -t mangle -F routing 2> /dev/null > /dev/null
$IPTABLES -t mangle -X routing 2> /dev/null > /dev/null

$IPTABLES -t mangle -F routing_n 2> /dev/null > /dev/null
$IPTABLES -t mangle -X routing_n 2> /dev/null > /dev/null

i=1
for d in ${DEVS_EXT}
do
ip route del table $i
ip rule del table $i
i=`expr $i + 1`
done

eend
}
start() {
ebegin "Starting advanced router"

$IPTABLES -t mangle -N routing
$IPTABLES -t mangle -N routing_n

#Add user rules here!####
$IPTABLES -t mangle -A routing -m state --state NEW,RELATED -j routing_n
###########################

$IPTABLES -t mangle -I OUTPUT -j routing
for d in ${DEVS_INT}
do
$IPTABLES -t mangle -I PREROUTING -i $d -j routing
done

#Get number of external interfaces
devs=0
for d in ${DEVS_EXT}
do
devs=`expr $devs + 1`
done
####################################

for d in ${NO_DEST}
do
$IPTABLES -t mangle -A routing_n -d $d -j RETURN
done

i=1
for d in ${DEVS_EXT}
do
#Routing marks
$IPTABLES -t mangle -A routing -m connmark --mark $i -j MARK --set-mark $i
$IPTABLES -t mangle -A routing_n -m statistic --mode=nth --every $devs --packet `expr $i - 1` -j CONNMARK --set-mark $i
##############

#Routing rules and routes ##
ip rule add fwmark $i table $i
if [ ! -z $GW ]; then
ip route add default via $GW dev $d table $i
fi

if [ -z $GW ]; then
ip route add default dev $d table $i
fi
#################

i=`expr $i + 1`
done
eend
}
11.01.2007 12:06
Admin

Регистрация: 05.10.2005
Проживание: Москва
Сообщения: 272
По умолчанию"Стрим - бери от жизни все!" или "Linux advanced routing дубль 2"

Что мы имеем в итоге - новые открывающиеся соединения (состояния NEW или RELATED) распределяются по указанным в конфиге интерфейсам (в данном случае - ppp1 ppp2 ppp3)
Побочное применение данной технологии можно найти в следующем:
Есть известный домашний канал Стрим, там предположим есть безлимитный канал на 1 Мбит. Так вот они разрешают поднимать несколько соединений! Поднимаем 6 коннектов, указываем их в конфиге, нагрузка распределяются по всем интерфейсам (например, если качать флешгетом в 6 потоков, либо пользовать bittorrent), и на Стриме имеем безлимитку на 6 Мбит
28.02.2007 14:41
Admin

Регистрация: 19.04.2006
Проживание: Калуга
Сообщения: 57
По умолчанию"Стрим - бери от жизни все!" или "Linux advanced routing дубль 2"

надо подчеркнуть -- за ТЕ ЖЕ ДЕНЬГИ ! )))