• Безымянный 32800

  • Тренировка кистей рук и пальцев


  • Как известно, в microdc2 отсутствует какой бы то ни было механизм ограничения скорости скачивания или раздачи. В случаях же, когда скорость ограничить все-таки нужно, в интернетах можно наткнуться на рекомендации использования утилит вроде trickle. Однако, даже не смотря на то, что рядом с этими рекомендациями часто можно найти слова о том, что "trickle ни черта не работает!!", возникает еще одна проблема: а что, если надо ограничить скорость раздачи только части диапазонов IP-адресов?

    И тут можно вспомнить о том, что в любой linux-системе присутствует встроенный QoS, имеющий много более широкую функциональность и, скорее всего, реально функционирующий. Им-то и воспользуемся.

    Сначала напишем правила для tc, создав для microdc2 новый класс трафика 1:5 с ограничением скорости до 500 кбайт/с:

    /sbin/tc qdisc add dev eth0 root handle 1: htb default 10 r2q 250
    /sbin/tc class add dev eth0 parent 1: classid 1:1 htb rate 100mbit burst 2k
    /sbin/tc class add dev eth0 parent 1:1 classid 1:5 htb rate 450kbps ceil 500kbps prio 1 burst 2k quantum 25000
    /sbin/tc class add dev eth0 parent 1:1 classid 1:10 htb rate 80mbit ceil 100mbit prio 0 burst 2k
    /sbin/tc filter add dev eth0 parent 1:0 prio 1 protocol ip handle 5 fw flowid 1:5
    /sbin/tc filter add dev eth0 parent 1:0 prio 2 protocol ip handle 10 fw flowid 1:10

    Небольшая расшифровка:

    • default 10 -- по умолчанию весь трафик относим к классу 1:10;
    • r2q 250 -- значение параметра r2q по умолчанию равно 250;
    • quantum 25000 -- для класса 1:5 указываем quantum вручную, т.к. при низком rate и r2q=250 автоматическое значение будет неприемлемым.

    К вопросу о том, что такое r2q:
    r2q is "rate to quantum" is used to calculate the quantum for each class : quantum = rate / r2q. Quantum must be 1500 < quantum < 60000. Otherwise you will get warnings from the kernel.
    Подробнее, например, здесь.

    Итак, теперь у нас есть определение разных классов трафика. Осталось только раздать указания, какой трафик к какому классу относить. Воспользуемся для этого функциональностью iptables маркировать пакеты.

    Но как только мы решим так поступить, возникает проблема: а как же определить, какие пакеты относятся к microdc2 и на которых мы хотим резать скорость, а какие - к добропорядочным приложениям, не требующим скоростных ограничений? Маркировка по destination ничего не даст - microdc2 может обращаться к каким угодно хостам. Вероятное желание маркировать пакеты по source-port (мы ведь знаем, на каком порту слушает microdc2?) также ни к чему не приведет: как оказывается, при попытках соединиться с другими пользователями DC++ microdc2 использует случайные исходящие порты, никак не связанные с listen-port. В отчаянии мы могли бы даже подумать о том, чтобы использовать iptables-модуль l7-filter. Однако, как вскоре выяснилось бы, для этого модуля необходимо пропатченное системное ядро, а к перекомпиляции и замене ядер на удаленных серверах лично я морально не готов.

    К счастью, оказывается, есть намного более простое решение. В iptables есть стандартный модуль owner, а microdc2 вполне логично будет запускать от имени какого-либо отдельного пользователя (и уж никак не от root'а). В результате мы легким движением руки можем ограничить скорость только одному пользователю, от имени которого запущен microdc2, и это никак не затронет других пользователей и другие программы, работающие на сервере.

    Пишем правила:

    /sbin/iptables -A OUTPUT -t mangle -p tcp -m owner --uid-owner microdc2 -j MARK --set-mark 5
    /sbin/iptables -A OUTPUT -t mangle -p tcp -d 10.0.0.0/8 -m mark --mark 5 -j MARK --xor-mark 5

    Комментарии:

    • Первой строкой мы ставим пометку 0x5 (соответствует правилу tc filter класса 1:5) на все пакеты, которые генерятся от пользователя microdc2;
    • Второй строкой мы снимаем поставленную ранее пометку в случае, если получатель пакета находится в подсети 10.0.0.0/8.

    Вот и всё:
    Весь исходящий трафик оказался зарезан в пределах 500 кбайт/с, за исключением исходящих соединений в сторону локальной сети.

    ЗЫ: Не забудьте добавить и правила файрвола, и правила tc куда-нибудь в автозагрузку. Автоматически при перезапуске системы они не сохраняются.











  • Безымянный 32800

  • Тренировка кистей рук и пальцев