Керування трафіком у Linux: практичний посібник
12 хв читання - 5 червня 2026 р.

Контролюйте пропускну здатність, визначайте пріоритети трафіку та формуйте вхід і вихід у Linux за допомогою tc. Робочі конфіги HTB, IFB, DSCP та fq_codel для реальних серверів.
Linux Traffic Control (tc): практичний посібник
Команда tc дозволяє безпосередньо керувати тим, як сервер обробляє мережевий трафік. Ви можете обмежити пропускну здатність для кожної служби, забезпечити оперативність інтерактивних сеансів, таких як SSH, під час пікових навантажень при масовій передачі даних, а також регулювати як вихідні, так і вхідні потоки за допомогою одного інструменту. Цей посібник охоплює основні концепції, робочу конфігурацію HTB, регулювання вхідного трафіку за допомогою IFB, визначення пріоритетів на основі DSCP, а також способи усунення несправностей у разі виникнення проблем.
Як працює tc
Кожна tc конфігурація складається з чотирьох рухомих частин:
- qdisc (дисципліна черги). Планувальник, приєднаний до мережевого інтерфейсу. Він визначає, як пакети ставляться в чергу та вилучаються з неї.
- Клас. Підрозділ всередині qdisc з класами. Уявіть це як смугу руху з власним обмеженням швидкості.
- Filter. Перевіряє заголовки пакетів (IP-адреси, порти, мітки) та призначає кожен пакет до певного класу.
- Дія. Що відбувається з пакетом після збігу: пересилання, відкидання, перенаправлення.
Вони утворюють дерево. Пакети надходять у кореневий qdisc, потрапляють у фільтри, сортуються за класами за допомогою major:minor ідентифікатора, і в кінцевому підсумку потрапляють у чергу на кінцевому qdisc для передачі.
Для будь-чого складнішого, ніж відповідність на основі портів, позначте пакети за допомогою iptables або nftables у таблиці mangle, а потім використовуйте fw фільтр у tc для класифікації за міткою. Це масштабується набагато краще, ніж ланцюгове застосування u32 правил для кожного типу трафіку.
Вихідний трафік проти вхідного
Напрямок має значення. Ядро може буферизувати та затримувати вихідні пакети, що й забезпечує реальне формування трафіку. Вхідні пакети вже пройшли по каналу до того, як ви їх бачите, тому ви можете лише контролювати їх (відкидати, якщо перевищено поріг), якщо тільки ви спочатку не перенаправите їх на пристрій IFB.
| Функція | Вихід | Вхід |
|---|---|---|
| Напрямок | Вихід | Вхідний |
| Формування | Вбудований | Потрібен IFB |
| Контроль | Підтримується | Підтримується |
| Типове використання | QoS, розподіл пропускної здатності, регулювання швидкості | Обмеження швидкості, базове запобігання DDoS-атакам |
Qdiscs, які ви насправді будете використовувати
- 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
Ви не можете формувати вхідний трафік на рівні ядра, оскільки на момент прибуття пакета він уже використав вашу пропускну здатність. Обхідним рішенням є перенаправлення вхідного трафіку на віртуальний інтерфейс Intermediate Functional Block (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.
Розумне стандартне зіставлення для серверних навантажень:
| Тип трафіку | 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 вже налаштований | tc qdisc del dev eth0 root перший |
| Правила застосовуються, але трафік не обмежується | Неправильний інтерфейс або TSO/GSO все ще увімкнені | Підтвердьте за допомогою ip link show, вимкніть розвантаження за допомогою ethtool -K |
| Фільтр ніколи не відповідає | Неправильний синтаксис порту/IP або вирівнювання маски | Додайте контрдію та перевірте кількість збігів у tc -s filter show |
| Правила зникають після перезавантаження | Конфігурація зберігається лише в пам'яті | Оберніть у скрипт і викликайте з systemd або диспетчера NetworkManager |
| Висока затримка пріоритетного трафіку | Відсутність leaf qdisc або занадто низький рівень спалаху | Приєднати fq_codel до класів leaf, підвищити burst |
Якщо ви коли-небудь заблокуєте себе через неправильну конфігурацію, скидання є простим:
tc qdisc del dev eth0 roottc неможливо створити пропускну здатність, якої у вас немає, але на добре забезпеченому висхідному каналі це робить різницю між передбачуваною продуктивністю та сервером, який розвалюється в той момент, коли один користувач починає великий переказ. Якщо вам потрібна необроблена пропускна здатність та свобода формувати її як завгодно, ознайомтеся з виділеними серверами FDC.

Керування трафіком у Linux: практичний посібник
Контролюйте пропускну здатність, визначайте пріоритети трафіку та формуйте вхід і вихід у Linux за допомогою tc. Робочі конфіги HTB, IFB, DSCP та fq_codel для реальних серверів.
12 хв читання - 5 червня 2026 р.
Чому важливо мати потужний і нелімітований VPS
7 хв читання - 9 травня 2025 р.

Маєте запитання або потребуєте індивідуального рішення?
Гнучкі варіанти
Глобальне охоплення
Миттєве розгортання
Гнучкі варіанти
Глобальне охоплення
Миттєве розгортання