Некоторое время назад меня попросили настроить простую балансировку трафика в удаленном филиале.
Работают они, бедняги, через ADSL, а отправка больших объемов писем (сканов документов) забивает у них весь обратный канал, что приводит к проблемам в работе с онлайн-офисными программами через VPN. В качестве шлюза они используют Linux (Fedora).
До этого я пару раз видел, как подобная балансировка настраивалась через ipfw на FreeBSD, и так как механизм iptables я знаю достаточно хорошо, особых проблем не ожидал.
Но покопавшись в интернете, я был неприятно удивлён, что iptables мне здесь совершенно не поможет. И знания о порядке прохождения пакетов через его таблицы и правила мне мало пригодятся.
Вам нужно изучить tc из пакета iproute2. Неожиданно для себя я потратил два дня более-менее на то, чтобы разобраться в балансировке трафика с помощью iproute2. Сначала мне попалась не самая лучшая для новичка статья про ХТБ( Здесь ).
Различные примеры из Интернета также иногда приводили в замешательство, поскольку зачастую не описывали ни конкретные опции, ни смысл их использования.
Именно поэтому я постарался собрать полученные знания в одной статье, а главное, описать все на доступном для новичков уровне.
Сразу оговорюсь: «резать» мы будем только трафик, исходящий из сетевого интерфейса.
Входящий тоже можно отрегулировать, но для этого нужны дополнительные хитрости.
Бесклассовые дисциплины
Итак, в Linux для управления трафиком каждому сетевому интерфейсу назначается дисциплина (qdisc) .Именно из этих дисциплин строится вся система управления дорожным движением.
Но вам не следует бояться; по сути, дисциплина — это всего лишь алгоритм обработки очереди сетевых пакетов.
На одном интерфейсе можно использовать несколько дисциплин, а так называемый корневая дисциплина (корневой qdisc) .
При этом каждый интерфейс имеет свою корневую дисциплину.
prio_fast
По умолчанию после загрузки системы root qdisc устанавливает алгоритм обработки пакетов типа pfifo_fast .
Мы проверяем: # tc qdisc
qdisc pfifo_fast 0: корневые группы dev eth0 3 priomap 1 2 2 2 1 2 0 0 1 1 1 1 1 1 1 1 pfifo_fast — это обычный алгоритм «Первый ввод — Первый вывод», но с некоторой приоритизацией трафика.
Дисциплина этого типа содержит три очереди FIFO с разными приоритетами обработки пакетов.
Пакеты сортируются на основе флага ToS (тип услуги) в каждом IP-пакете.
Пакет в FIFO0 имеет наивысший приоритет обработки, а в FIFO2 — наименьший.
Сам ToS требует отдельного разговора, поэтому предлагаю ограничиться тем, что операционная система сама знает, какой ToS назначить отправляемому IP-пакету.
Например, в пакетах telnet и ping ToS будет иметь разные значения.
0: — дескриптор корневой дисциплины.
Дескрипторы должны выглядеть так основной_номер: минорный_номер , но для дисциплин младшее число всегда должно быть 0, поэтому его можно опустить.
Параметр priomap 1 2 2 2 1 2 0 0 1 1 1 1 1 1 1 1 , просто указывает побитовое соответствие поля ToS каждой внутренней очереди (полосе).
Например, при ToS=4 пакет обрабатывается в очереди 1, при ToS=7 — в очереди 0. В ряде источников указано, что параметры дисциплины pfifo_fast изменить, поверьте, нельзя.
ТБФ
Теперь давайте посмотрим, как можно ограничить общую скорость исходящего трафика.Для этого присвоим корневую дисциплину интерфейса дисциплине типа TBF (фильтр сегмента токенов) .
# tc qdisc add dev eth0 root скорость tbf 180 кбит, задержка 20 мс, буфер 1540 скорость 180 кбит — устанавливает порог скорости передачи на интерфейсе.
задержка 20 мс — устанавливает максимальное время, которое пакет данных проводит в ожидании токена.
буфер 1540 — установить размер буфера токена в байтах.
В примерах пишут, что для ограничения 10Мбит/с достаточно буфера в 10Кбайт. Главное не делать его слишком маленьким, можно и побольше.
Примерная формула расчета: скорость_в_байтах/100.
Дисциплина TBF использует для своей работы механизм токенов.
Токены генерируются системой с постоянной скоростью и помещаются в буфер (корзину).
Для каждого токена, покидающего буфер, IP-пакет покидает интерфейс.
Если скорость передачи пакетов и генерации токена совпадают, процесс передачи данных происходит без задержек.
Если скорость передачи пакетов меньше скорости токена, токены начинают накапливаться в буфере и затем могут быть использованы для кратковременной передачи данных на скорости выше пороговой.
Если скорость передачи пакетов выше, то токенов будет не хватать.
Пакеты данных некоторое время ждут новых токенов, а затем начинают отбрасываться.
Две описанные дисциплины относятся к так называемым бесклассовым дисциплинам.
У них есть ряд функциональных ограничений: они подключаются только к интерфейсу (или классу Edge), плюс к ним нельзя применить пакетные фильтры.
И соответственно мою задачу по балансировке почтового трафика с их помощью решить невозможно.
Кстати, полный набор бесклассовых дисциплин несколько шире: pfifo, bfifo, sqf (обеспечивает одинаковую скорость поступления пакетов из разных потоков), esqf и т.д.
Классные дисциплины
Если дисциплины можно представить как участки водопроводных труб, то классы – это соединители (фитинги).Это может быть простой штуцер-переходник, а может быть хитрый штуцер-разветвитель с десятком изгибов.
Родителем класса может быть либо дисциплина, либо другой класс.
Дочерние классы можно присоединить к классу (объединив несколько фитингов).
Класс, не имеющий дочерних классов, называется край (класс листа) .
Здесь пакеты данных, пролетев через нашу «водопроводку», покидают систему управления трафиком и отправляются сетевым интерфейсом.
По умолчанию к любому пограничному классу прикреплена дисциплина типа fifo, и именно она определяет порядок передачи пакетов для этого класса.
Но прелесть в том, что мы можем заменить эту дисциплину на любую другую.
Если добавляется дочерний класс, данная дисциплина удаляется.
предварительно
Вернемся к задаче балансировки почтового трафика и рассмотрим классовую дисциплину.предварительно .
Он очень похож на уже описанный pfifo_fast. Но особенность этой дисциплины состоит в том, что при ее назначении автоматически создаются три класса (количество можно изменить с помощью параметраbands).
Давайте заменим корневую дисциплину интерфейса на prio. # tc qdisc добавить корневой дескриптор dev eth0 1: prio ручка 1: — установить дескриптор для этого корневого qdisc. В классных дисциплинах потом указывается при подключении занятий.
Проверка дисциплины: # tc qdisc qdisc prio 1: dev eth0bands 3 priomap 1 2 2 2 1 2 0 0 1 1 1 1 1 1 1 1 Проверяем классы: # tc -d -s class show dev eth0 класс prio 1:1 родительский 1: Отправлено 734914 байт 7875 pkt (отброшено 0, превышено 0, запрошено 0) невыполненные запросы 0b 0p 0 класс prio 1:2 родительский 1: Отправлено 1555058583 байт 8280199 пкт (отброшено 124919, превышено 26443 запроса 0) невыполненных запросов 0b 0p запросов 0 класс prio 1:3 родительский 1: Отправлено 57934378 байт 802213 пкт (отброшено 70976, превышено 284608 запросов 0) невыполненные запросы 0b 0p 0 Мы видим три класса с идентификаторами 1:1, 1:2 и 1:3, подключенные к родительской дисциплине 1: type prio (классы должны иметь общий номер major_identifier со своим родителем).
То есть мы установили на корневой «пайп» qdisc тройник, который разделяет потоки данных так же, как это делает pfifo_fast. Согласно ToS, высокоприоритетный трафик переходит в класс 1:1, обычный трафик — в класс 1:2, а совсем «мусорный» — в класс 1:3. Допустим, обратный канал ADSL обеспечивает скорость 90 Кбит/с.
Давайте разделим это на 20Кбайт/с для почты и 70Кбайт/с для всего остального.
Мы не будем специально ограничивать трафик из класса 1:1. Его пакеты всегда смогут занять как минимум всю ширину канала благодаря высокому приоритету ToS, но объем трафика в этом классе будет незначительным по сравнению с двумя другими классами.
Поэтому мы не выделяем для него отдельную полосу.
Стандартный трафик обычно попадает в класс 1:2. Подключаем дисциплинарный канал 70Кбайт/с ко второму выводу тройника: # tc qdisc add dev eth0 родительский дескриптор 1:2 10: скорость tfb 70 кбит/с, буфер 1500, задержка 50 мс Подключим к третьему пину тройника дисциплинарный пайп 20Кбайт/с: # tc qdisc add dev eth0 родительский дескриптор 1:3 20: скорость tfb 20 кбит/с, буфер 1500, задержка 50 мс Все три этих класса являются маргинальными.
И теперь остаётся только направить почтовый трафик не в класс 1:2, как это было раньше, а в класс 1:3. Это делается с помощью фильтров дисциплины класса.
# фильтр tc добавить dev eth0 родительский 1: протокол ip prio 1 u32 match ip dport 25 0xffff flowid 1:3 родитель 1: — фильтр можно только прикрепить к дисциплине и вызвать из нее.
На основании ответа фильтра дисциплина решает, в каком классе пакет будет продолжать обрабатываться.
протокол IP — определить тип сетевого протокола прио 1 — параметр меня долго смущал, так как он используется в классах и фильтрах, плюс это название дисциплины.
Здесь prio задает приоритет фильтров, фильтры с меньшим prio активируются первыми.
и32 - так называемый классификатор трафика, который может отбирать пакеты по любым его характеристикам: по IP-адресу отправителя/получателя, по порту источника/получателя, по типу протокола.
Эти условия, собственно, и указаны ниже.
соответствие ip dport 25 0xffff — устанавливает фильтр, который будет срабатывать при отправке пакетов на порт 25. 0xffff — битовая маска номера порта.
текучий 1:3 — указать, в какой класс отправляются пакеты при срабатывании этого фильтра.
Это грубо сделано, но оно выполнит свою работу.
Посмотрим на статистику прохождения пакетов: # tc -s -d qdisq show dev eth0
# tc -s -d class show dev eth0
# tc -s -d filter show dev eth0
Быстро удалить все классы, фильтры и вернуть корневой интерфейс qdisc в исходное состояние можно командой: # tc qdisc del dev eth0 root
ХТБ
С другой стороны, наш обратный канал уже слишком тонкий, чтобы зарезервировать 20 КБ/с только для отправки электронной почты.Поэтому здесь лучше использовать дисциплину класса HTB (Hierarchical Token Bucket).
Это позволяет дочерним классам заимствовать пропускную способность у родителя.
# tc qdics добавить корневой дескриптор dev eth0 1: htb по умолчанию 20 по умолчанию 20 — установить класс по умолчанию.
Он будет обрабатывать пакеты, не вошедшие в другие классы дисциплины htb. Если вы не укажете его, будет присвоено значение «по умолчанию 0», и весь неклассифицированный (нефильтрованный) трафик будет отправляться со скоростью интерфейса.
# tc class add dev eth0 родительский 1: classid 1:1 htb скорость 90 кбит/с ячейка 90 кбит/с прикрепите класс с идентификатором 1:1 к корневому qdisc. Таким образом мы ограничиваем скорость на интерфейсе до 90 КБ/с.
класс 1:1 — идентификатор класса.
скорость 90 кбит/с — установить нижний порог пропускной способности для класса.
ячейка 90 кбит/с — устанавливаем верхний порог пропускной способности для класса.
# tc class add dev eth0 родительский 1:1 classid 1:10 htb скорость 20кбит/с ячейка 70кбит/с создайте класс 1:10, дочерний класс 1:1. Тогда фильтр будет направлять на него исходящий почтовый трафик.
скорость 20 кбит/с — мы устанавливаем гарантированно нижний порог пропускной способности для класса.
ячейка 70 кбит/с — устанавливаем верхний порог пропускной способности для класса.
Если у родительского класса есть свободная пропускная способность (наличие «лишних» токенов), класс 1:10 сможет временно увеличить скорость передачи данных, до указанного лимита в 70 Кб/с.
# tc class add dev eth0 родительский 1:1 classid 1:20 htb скорость 70 кбит/с ячейка 90 кбит/с Создайте класс по умолчанию.
Весь остальной трафик попадет в него.
Таким же образом с помощью параметровrate и ceil задаем расширение пропускной способности в случае отсутствия почтового трафика.
# фильтр tc добавить dev eth0 родительский 1: протокол ip prio 1 u32 match ip dport 25 0xffff flowid 1:10 фильтр на основе u32, который направляет исходящие пакеты на порт 25 в класс 1:10. Кстати, в документации указано, что на самом деле в HTB формирование трафика происходит только в классах Edge, в нашем случае 1:10 и 1:20. Указание параметров ограничения пропускной способности в остальных классах HTB необходимо только для функционирования системы заимствований между классами.
При добавлении класса также можно указать параметр предварительно .
Он определяет приоритет класса (0 — максимальный приоритет).
Классы с более низким приоритетом не обрабатываются, пока есть данные в классах с более высоким приоритетом.
Источники: HOWTO по расширенной маршрутизации и управлению трафиком в Linux HOWTO по управлению трафиком Повесть о Linux и управлении трафиком Теги: #linux #настройка Linux #трафик #трафик #tc #iproute2 #пропускная способность
-
Ирландская Республика
19 Oct, 24 -
Реклама В Зеркалах
19 Oct, 24 -
Преемник Counter-Strike: Left 4 Dead!
19 Oct, 24 -
Версия Racios Для Iphone!
19 Oct, 24 -
Fileinfo.net Или Все О Расширениях Файлов
19 Oct, 24