Linux Traffic Control (tc): практическое руководство

12 мин чтения - 5 июня 2026 г.

hero section cover
Содержание
  • Управление трафиком в Linux (tc): практическое руководство
  • Как работает tc
  • Настройка tc на сервере Linux
  • Регулирование исходящего трафика с помощью HTB
  • Формирование входящего трафика с помощью IFB
  • Приоритезация трафика с помощью DSCP
  • Мониторинг и устранение неполадок
Поделиться

Контролируйте пропускную способность, устанавливайте приоритеты трафика, формируйте входящий и исходящий трафик в Linux с помощью tc. Рабочие конфигурации HTB, IFB, DSCP и fq_codel для реальных серверов.

Управление трафиком в Linux (tc): практическое руководство

Команда tc позволяет напрямую контролировать, как ваш сервер обрабатывает сетевой трафик. Вы можете ограничить пропускную способность для каждого сервиса, обеспечить отзывчивость интерактивных сессий, таких как SSH, при всплесках массовых передач данных, а также формировать как исходящие, так и входящие потоки с помощью одного инструмента. В этом руководстве рассматриваются основные концепции, рабочая настройка HTB, формирование входящего трафика с помощью IFB, приоритезация на основе DSCP, а также способы отладки в случае сбоев.


 

Как работает tc

Каждая tc конфигурация состоит из четырех компонентов:

  • qdisc (дисциплина очереди). Планировщик, привязанный к сетевому интерфейсу. Он определяет, как пакеты помещаются в очередь и извлекаются из нее.
  • Class. Подразделение внутри qdisc с классами. Представьте себе это как полосу движения со своим собственным ограничением скорости.
  • Filter. Проверяет заголовки пакетов (IP-адреса, порты, метки) и назначает каждый пакет классу.
  • Действие. Что происходит с пакетом после сопоставления: пересылка, отбрасывание, перенаправление.

Все это образует дерево. Пакеты поступают в корневой qdisc, проходят через фильтры, сортируются по классам с помощью major:minor и в конечном итоге попадают в очередь на листьях qdisc для передачи.

Для всего, что сложнее сопоставления на основе портов, помечайте пакеты с помощью iptables или nftables в таблице mangle, а затем используйте fw фильтр в tc для классификации по метке. Это масштабируется гораздо лучше, чем цепочка необработанных u32 правил для каждого типа трафика.

Исходящий трафик против входящего

Направление имеет значение. Ядро может буферизовать и задерживать исходящие пакеты, что и обеспечивает реальное формирование трафика. Входящие пакеты уже прошли по каналу к моменту, когда вы их видите, поэтому вы можете только контролировать их (отбрасывать при превышении порога), если только вы сначала не перенаправите их на устройство IFB.

ОсобенностьИсходящийВходящий
НаправлениеИсходящийВходящий
ФормированиеВстроенныйТребуется IFB
КонтрольПоддерживаетсяПоддерживается
Типичное использованиеQoS, распределение пропускной способности, регулирование скоростиОграничение скорости, базовое противодействие DDoS-атакам

Qdisc, которые вы будете использовать

  • HTB (Hierarchical Token Bucket). С классами. Используйте его, если вам нужна гарантированная минимальная пропускная способность для каждого сервиса с возможностью заимствования неиспользуемой емкости у других классов.
  • TBF (Token Bucket Filter). Без классов. Используйте его, когда вам просто нужно ограничить весь интерфейс одной скоростью.
  • fq_codel (Fair Queuing Controlled Delay). Сочетает справедливость по потокам с активным управлением очередью для устранения переполнения буфера. Это qdisc по умолчанию в большинстве дистрибутивов Linux начиная с systemd 217 и поставляется по умолчанию в RHEL 9. Всегда подключайте его как листьевой qdisc под классами HTB, иначе один жадный поток может захватить весь класс.

Настройка tc на сервере Linux

tc поставляется с пакетом iproute2. В Debian и Ubuntu установите его с помощью apt-get install iproute2. В RHEL и производных дистрибутивах yum install iproute. Вам понадобятся права root или sudo.

Сначала определите правильное имя интерфейса. Неправильное название интерфейса — самая частая причина того, что конфигурация без предупреждения не дает результата:

ip link show

Проверьте, что уже находится на интерфейсе, включая текущие счетчики:

tc -s qdisc show dev eth0

Удалите любой существующий root qdisc перед применением новой конфигурации, чтобы избежать RTNETLINK answers: File exists ошибок:

tc qdisc del dev eth0 root 2>/dev/null || true

Если вы обновляете существующее правило, а не начинаете с нуля, используйте replace вместо add для атомарной замены.

Аппаратная разгрузка, такая как TSO и GSO, группирует пакеты таким образом, что это мешает формированию трафика. Отключите их на интерфейсе с формированием трафика:

sudo ethtool -K eth0 tso off gso off

Установите fq_codel в качестве общесистемного qdisc по умолчанию для новых интерфейсов:

sysctl -w net.core.default_qdisc=fq_codel

Для загруженных серверов сочетайте его с алгоритмом управления перегрузкой BBR (ядро 4.9+). BBR поддерживает высокую пропускную способность без увеличения очередей:

sysctl -w net.ipv4.tcp_congestion_control=bbr

Одна полезная привычка при настройке удаленного компьютера через SSH: откройте вторую сессию и держите tc qdisc del dev eth0 root готовность к вставке. Неправильное правило фильтрации может мгновенно заблокировать вам доступ.

Регулирование исходящего трафика с помощью HTB

HTB позволяет установить для каждого сервиса гарантированный минимум (rate) и максимальный объем (ceil). Неиспользованная пропускная способность распределяется между теми, кто в ней нуждается, в порядке приоритета. Вот рабочая трехуровневая конфигурация для восходящего канала 1 Гбит/с.

Создайте корневой qdisc HTB. default 30 отправляет любой неклассифицированный пакет в класс 1:30 , а не позволяет ему обойти ваши правила:

tc qdisc add dev eth0 root handle 1: htb default 30

Ограничьте общую пропускную способность на уровне 900 Мбит/с. Всегда формируйте трафик чуть ниже фактической пропускной способности канала, иначе очередь образуется на вышестоящем маршрутизаторе или модеме, которые вы не контролируете:

tc class add dev eth0 parent 1: classid 1:1 htb rate 900mbit ceil 900mbit

Определите уровни обслуживания. Более низкие prio значения получают неиспользуемую пропускную способность в первую очередь:

# High priority: web and API traffic
tc class add dev eth0 parent 1:1 classid 1:10 htb rate 500mbit ceil 900mbit prio 1
 
# Medium priority: database replication
tc class add dev eth0 parent 1:1 classid 1:20 htb rate 300mbit ceil 900mbit prio 2
 
# Low priority: bulk and backup traffic
tc class add dev eth0 parent 1:1 classid 1:30 htb rate 100mbit ceil 900mbit prio 3

Прикрепите fq_codel в качестве конечного qdisc к каждому классу, чтобы один поток не мог доминировать в своем уровне:

tc qdisc add dev eth0 parent 1:10 handle 10: fq_codel
tc qdisc add dev eth0 parent 1:20 handle 20: fq_codel
tc qdisc add dev eth0 parent 1:30 handle 30: fq_codel

Теперь классифицируйте трафик. Для простого сопоставления портов u32 самый быстрый:

tc filter add dev eth0 protocol ip parent 1:0 prio 1 u32 \
  match ip dport 443 0xffff flowid 1:10

Для всего, что зависит от состояния, помечайте в iptables и сопоставляйте метку с fw:

iptables -t mangle -A OUTPUT -p tcp --dport 5432 -j MARK --set-mark 2
tc filter add dev eth0 protocol ip parent 1:0 prio 2 handle 2 fw flowid 1:20

Формирование входящего трафика с помощью IFB

Вы не можете изначально формировать входящий трафик, потому что к моменту прибытия пакета он уже использовал вашу пропускную способность. Обходной путь заключается в перенаправлении входящего трафика на виртуальный интерфейс промежуточного функционального блока (IFB), где ядро обрабатывает его как исходящий и позволяет применять qdiscs с классами.

Загрузите модуль и активируйте интерфейс:

modprobe ifb numifbs=1
ip link set dev ifb0 up

Добавьте qdisc входящего трафика к физическому интерфейсу и перенаправьте все на ifb0:

tc qdisc add dev eth0 ingress handle ffff:
tc filter add dev eth0 parent ffff: protocol all u32 \
  match u32 0 0 action mirred egress redirect dev ifb0

Отсюда ifb0 он ведет себя как любой другой интерфейс. Примените к нему ваше дерево HTB точно так же, как вы бы сделали для исходящего трафика:

tc qdisc add dev ifb0 root handle 1: htb default 30
tc class add dev ifb0 parent 1: classid 1:1 htb rate 900mbit ceil 900mbit
tc class add dev ifb0 parent 1:1 classid 1:10 htb rate 500mbit ceil 900mbit prio 1

Приоритезация трафика с помощью DSCP

DSCP (Differentiated Services Code Point) помечает пакеты 6-битным значением в байте TOS, поэтому ваши tc фильтры могут классифицировать по тегам, а не по поиску портов в наборе правил. При сопоставлении DSCP в tc, сдвиньте значение влево на 2 бита. DSCP EF (46) становится 0xb8. Маска 0xfc изолирует 6 битов DSCP от 2 битов ECN.

Разумное сопоставление по умолчанию для серверных рабочих нагрузок:

Тип трафикаDSCPTOS (шестнадцатеричный)Примеры
ИнтерактивныйEF0xb8SSH, DNS, VoIP
БизнесAF410x88HTTP, HTTPS, API
Массовая рассылкаCS10x20Резервное копирование, FTP, обновления пакетов
По возможностиCS00x00Все остальное

Помечайте исходящие пакеты в iptables до того, как они попадут в ваши tc фильтров:

iptables -t mangle -A OUTPUT -p tcp --dport 22 -j DSCP --set-dscp 46

Затем сопоставьте тег в tc и направьте его в нужный класс HTB:

# EF (SSH, VoIP) goes to the high-priority class
tc filter add dev eth0 protocol ip parent 1:0 prio 1 u32 \
  match ip tos 0xb8 0xfc flowid 1:10
 
# AF41 (web traffic) goes to the medium class
tc filter add dev eth0 protocol ip parent 1:0 prio 2 u32 \
  match ip tos 0x88 0xfc flowid 1:20
 
# CS1 (bulk) goes to the low-priority class
tc filter add dev eth0 protocol ip parent 1:0 prio 3 u32 \
  match ip tos 0x20 0xfc flowid 1:30

Мониторинг и устранение неполадок

Три команды, которые вы будете использовать постоянно:

tc -s qdisc show dev eth0
tc -s class show dev eth0
tc -s filter show dev eth0

Следите за dropped и overlimits счетчики. Потерянные пакеты означают перегрузку очереди; превышение лимитов означает, что вы достигли верхнего предела класса, и ядро было вынуждено задержать или отбросить трафик. Для просмотра в реальном времени:

watch -n 1 'tc -s class show dev eth0'

Добавьте -d для внутренних параметров (target, interval, quantum) и -j для вывода в формате JSON, если вы направляете данные в стек метрик. Используйте вместе с ss -tin , чтобы увидеть оценки RTT и повторные передачи на уровне TCP.

Большинство сбоев можно отнести к нескольким основным типам:

СимптомВероятная причинаИсправление
RTNETLINK answers: File existsRoot qdisc уже настроенtc qdisc del dev eth0 root первый
Правила применяются, но трафик не ограничиваетсяНеверный интерфейс или TSO/GSO все еще включеныПодтвердите с помощью ip link show, отключите разгрузку с помощью ethtool -K
Фильтр никогда не совпадаетНеверный синтаксис порта/IP или выравнивание маскиДобавьте контрдействие и проверьте количество совпадений в tc -s filter show
Правила исчезают после перезагрузкиКонфигурация хранится только в памятиОберните в скрипт и вызывайте из systemd или диспетчера NetworkManager
Высокая задержка приоритетного трафикаОтсутствует qdisc leaf или слишком низкий уровень пакетной передачиПрисоедините fq_codel к классам leaf, повысить burst

Если вы когда-нибудь заблокируете себя из-за неправильной настройки, сброс прост:

tc qdisc del dev eth0 root

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

Блог

События этой недели

Другие статьи
Linux Traffic Control (tc): практическое руководство

Linux Traffic Control (tc): практическое руководство

Контролируйте пропускную способность, устанавливайте приоритеты трафика, формируйте входящий и исходящий трафик в Linux с помощью tc. Рабочие конфигурации HTB, IFB, DSCP и fq_codel для реальных серверов.

12 мин чтения - 5 июня 2026 г.

Почему важно иметь мощный и не тарифицируемый VPS

7 мин чтения - 9 мая 2025 г.

Другие статьи
background image

У вас есть вопросы или вам нужно индивидуальное решение?

icon

Гибкие варианты

icon

Глобальный охват

icon

Мгновенное развертывание

icon

Гибкие варианты

icon

Глобальный охват

icon

Мгновенное развертывание