Управление трафиком в Linux (tc): практическое руководство
12 мин чтения - 5 июня 2026 г.

Управление пропускной способностью, приоритизация трафика и регулирование входящего и исходящего трафика в Linux с помощью tc. Рабочие настройки HTB, IFB, DSCP и fq_codel для реальных серверов.
Управление трафиком в Linux (tc): практическое руководство
Команда tc позволяет напрямую контролировать, как ваш сервер обрабатывает сетевой трафик. Вы можете ограничить пропускную способность для каждого сервиса, обеспечить отзывчивость интерактивных сеансов (например, SSH) при всплесках массовой передачи данных, а также регулировать как исходящие, так и входящие потоки с помощью одного инструмента. В этом руководстве рассматриваются основные концепции, рабочая настройка HTB, регулирование входящего трафика с помощью IFB, приоритезация на основе DSCP, а также способы устранения неполадок в случае сбоев.
Как работает tc
Каждая tc конфигурация состоит из четырёх компонентов:
- qdisc (дисциплина очереди). Планировщик, привязанный к сетевому интерфейсу. Он определяет, как пакеты помещаются в очередь и извлекаются из неё.
- Класс. Подразделение внутри qdisc с поддержкой классов. Представьте себе это как полосу движения со своим собственным ограничением скорости.
- Фильтр. Проверяет заголовки пакетов (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Перед применением новой конфигурации удалите все существующие корневые 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), где ядро обрабатывает его как исходящий и позволяет применять qdisc с классами.
Загрузите модуль и активируйте интерфейс:
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.
Разумное сопоставление по умолчанию для серверных рабочих нагрузок:
| Тип трафика | DSCP | TOS (шестнадцатеричный) | Примеры |
|---|---|---|---|
| Интерактивный | EF | 0xb8 | SSH, DNS, VoIP |
| Бизнес | AF41 | 0x88 | HTTP, HTTPS, API |
| Массовая рассылка | CS1 | 0x20 | Резервное копирование, FTP, обновления пакетов |
| По возможности | CS0 | 0x00 | Все остальное |
Помечайте исходящие пакеты в 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 exists | qdisc «Root» уже настроен | 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 roottc невозможно создать пропускную способность, которой у вас нет, но на хорошо обеспеченном канале связи это определяет разницу между предсказуемой производительностью и сервером, который выходит из строя в тот момент, когда один из клиентов начинает крупную передачу данных. Если вам нужна исходная пропускная способность и свобода формировать её так, как вам удобно, обратите внимание на выделенные серверы FDC.

Руководство по iperf3: тестирование скорости сети в Linux и Windows
Установите iperf3, запустите тесты пропускной способности и настройте буферы TCP для получения точных результатов в Linux и Windows. Охватывает тестирование UDP, двунаправленное тестирование и тестирование 10GbE+.
10 мин чтения - 7 мая 2026 г.
Настроенные профили для оптимизации рабочей нагрузки серверов Linux
16 мин чтения - 9 июня 2026 г.

У вас есть вопросы или вам нужно индивидуальное решение?
Гибкие варианты
Глобальный охват
Мгновенное развертывание
Гибкие варианты
Глобальный охват
Мгновенное развертывание