Сказ о том, как я рулил траффиком в линуксах

Небольшие заметки из личного (и не только) опыта, рекомендации
Ответить
Аватара пользователя
Gen1us2k
Модератор
Модератор
Сообщения: 771
Зарегистрирован: 02 мар 2010, 16:13

Сказ о том, как я рулил траффиком в линуксах

Сообщение Gen1us2k » 25 ноя 2011, 10:57

Доброго всем времени суток, ага. Встала задача, настроить QoS. Кого пускать без зарезов по скоростям, кого нет. В итоге, что было сделано:
1. Поресерчил кучу дистров. pfSense, m0n0wall, smoothwall, zeroshell, untangle
2. Осознал, что untangle - то, что нужно для моей задачи
3. Осознал, что я не хочу ничего менять на шлюзе и принял решение спизди^W мигрировать решение с untangle на офисный шлюз
4. Танцы с бубном и "классами" траффика.

Лирическое отступление. Если бы на шлюзе стояла бы FreeBSD, то текущую задачу решить довольно легко. Но стоит Debian и очень лениво поднимать всё с нуля на FreeBSD.
Из моих заметок я заметил, что по дефолту с помощью tc и iptables можно шейпить только исходящий трафф. Входящий не получится. В итоге, нашел способ шейпить входящий трафф с помощью imq девайса.

Для начала надо пропатчить и пересобрать ядро, чтобы добавить поддержку IMQ. Второе - пропатчить и пересобрать iptables.
все патчи есть тут

Теперь, что у нас дано.
1. 100 мбит по кг
2. 512 кбит на внешку
допустим, нам надо не резать кг, а всему остальному выделить полосу в 128к
Маркируем пакеты в iptables

Код: Выделить всё

#!/bin/bash
iptables=$(which iptables)
wan_dev=br0
imq_dev=imq0
kg_nets=/tmp/kgnets
wget=$(which wget)

$wget -O $kg_nets http://elcat.kg/ip/kg-nets.txt

# Initializing qos chains
flush_iptables_chains()
{
  $iptables -t mangle -F qos-input
  $iptables -t mangle -F qos-output
  $iptables -t mangle -X qos-input
  $iptables -t mangle-X qos-output
}
add_iptables_chains()
{
  $iptables -t mangle -N qos-input
  $iptables -t mangle -F qos-input
  $iptables -t mangle -N qos-output
  $iptables -t mangle -F qos-output
}
iptables_qos_in()
{
  $iptables -t mangle -A PREROUTING -j qos-input
  while read line; do
    $iptables -t mangle -A qos-input -s `echo $line` -j MARK --set-mark 0x00100000/0x00700000
  done < $kg_nets
}
iptables_qos_out()
{
  $iptables -t mangle -A POSTROUTING -j qos-output
  while read line;do
    $iptables -t mangle -A qos-output -d `echo $line` -j MARK --set-mark 0x00100000/0x00700000
  done < $kg_nets
}
flush_iptables_chains
add_iptables_chains
iptables_qos_in
iptables_qos_out
$iptables -t mangle -A qos-input -j IMQ
Что мы сделали: создали 2 цепочки, qos-input и qos-output. промаркировали КГ пакеты. А еще правилом $iptables -t mangle -A qos-input -j IMQ пропускаем всё входящее через imq интерфейс

Теперь идут пляски с tc и htb.
Кусок кода, отвечающий за добавление правил tc

Код: Выделить всё

add_htb_rules(){
add_qdisc="tc qdisc add dev "
add_class="tc class add dev "
add_filtr="tc filter add dev "
SFQ="sfq perturb 10 "
# egress shaping
# создаем корень
$add_qdisc $wan_dev root handle 1: htb default 13
# создаем класс, с пропускной способностью в 100 mbit/s
$add_class $wan_dev parent 1: classid 1:1 htb rate ${KGUB}
# вешаем на него правило
$add_class $wan_dev parent 1:1 classid 1:11 htb rate $KGUR ceil $KGUL
# делим оставшееся поровну
$add_qdisc $wan_dev parent 1:11 handle 11: $SFQ
# создаем класс, с пропускной способностью в 128к
$add_class $wan_dev parent 1:1 classid 1:12 htb rate $ALLUB
$add_class $wan_dev parent 1:12 classid 1:13 htb rate $AUR ceil $AUL
$add_qdisc $wan_dev parent 1:13 handle 13: $SFQ
# добавляем фильтры
$add_filtr $wan_dev parent 1: prio 11 protocol ip u32 match mark 0x100000 0x700000 flowid 1:11 # КГ - 100 мбит
$add_filtr $wan_dev parent 1: prio 13 protocol ip u32 match mark 0x200000 0x700000 flowid 1:13 # все, что не кг - 128к


#ingress shaping
ifconfig $imq_dev up
# создаем корень
$add_qdisc $imq_dev root handle 1: htb default 13
# создаем класс, с пропускной способностью в 100 mbit/s
$add_class $imq_dev parent 1: classid 1:1 htb rate ${KGUB}
# вешаем на него правило
$add_class $imq_dev parent 1:1 classid 1:11 htb rate $KGUR ceil $KGUL
# делим оставшееся поровну
$add_qdisc $imq_dev parent 1:11 handle 11: $SFQ
# создаем класс, с пропускной способностью в 128к
$add_class $imq_dev parent 1:1 classid 1:12 htb rate $ALLUB
$add_class $imq_dev parent 1:12 classid 1:13 htb rate $AUR ceil $AUL
$add_qdisc $imq_dev parent 1:13 handle 13: $SFQ
# добавляем фильтры
$add_filtr $imq_dev parent 1: prio 11 protocol ip u32 match mark 0x100000 0x700000 flowid 1:11 # КГ - 100 мбит
$add_filtr $imq_dev parent 1: prio 13 protocol ip u32 match mark 0x200000 0x700000 flowid 1:13 # все, что не кг - 128к

}
Где $wan_dev=br0 и $imq_dev=imq0 в моем случае.

Принцип думаю понятен.
ЗЫ возможны ошибки и вопросы. Брал куски кода из скриптов
Изображение
Home: Windows Heaven
Home: Debian 6
For Servers: Debian || RHEL Based || Gentoo || FreeBSD
Аватара пользователя
Gen1us2k
Модератор
Модератор
Сообщения: 771
Зарегистрирован: 02 мар 2010, 16:13

Re: Сказ о том, как я рулил траффиком в линуксах

Сообщение Gen1us2k » 25 ноя 2011, 11:02

Задача была такая. на некоторые сервисы на внешке пускать с высшим приоритетом, поэтому вы увидите маркировку типа

$add_filtr $imq_dev parent 1: prio 13 protocol ip u32 match mark 0x200000 0x700000 flowid 1:13 # все, что не кг - 128к
Изображение
Home: Windows Heaven
Home: Debian 6
For Servers: Debian || RHEL Based || Gentoo || FreeBSD
Ответить

Вернуться в «Полезные советы»