Linux Traffic Control (tc): praktyczny przewodnik

12 min czytania - 5 czerwca 2026

hero section cover
Spis treści
  • Kontrola ruchu w systemie Linux (tc): praktyczny przewodnik
  • Jak działa tc
  • Konfiguracja tc na serwerze z systemem Linux
  • Kształtowanie ruchu wychodzącego za pomocą HTB
  • Kształtowanie ruchu przychodzącego za pomocą IFB
  • Priorytetyzacja ruchu za pomocą DSCP
  • Monitorowanie i rozwiązywanie problemów
Udostępnij

Kontroluj przepustowość, ustalaj priorytety ruchu oraz kształtuj ruch przychodzący i wychodzący w systemie Linux za pomocą tc. Działająca konfiguracja HTB, IFB, DSCP i fq_codel dla rzeczywistych serwerów.

Kontrola ruchu w systemie Linux (tc): praktyczny przewodnik

Polecenie tc pozwala na bezpośrednią kontrolę nad sposobem, w jaki serwer obsługuje ruch sieciowy. Możesz ograniczyć przepustowość dla poszczególnych usług, zapewnić responsywność sesji interaktywnych, takich jak SSH, w przypadku gwałtownego wzrostu transferu masowego oraz kształtować przepływ zarówno wychodzący, jak i przychodzący za pomocą jednego narzędzia. Niniejszy przewodnik obejmuje podstawowe pojęcia, działającą konfigurację HTB, kształtowanie ruchu przychodzącego za pomocą IFB, ustalanie priorytetów oparte na DSCP oraz sposoby debugowania w przypadku awarii.


 

Jak działa tc

Każda tc konfiguracja składa się z czterech ruchomych elementów:

  • qdisc (dyscyplina kolejkowania). Harmonogram przypisany do interfejsu sieciowego. Decyduje o tym, w jaki sposób pakiety są umieszczane w kolejce i z niej usuwane.
  • Klasa. Podział wewnątrz qdisc z podziałem na klasy. Pomyśl o tym jak o pasie ruchu z własnym ograniczeniem prędkości.
  • Filtr. Sprawdza nagłówki pakietów (adresy IP, porty, oznaczenia) i przypisuje każdy pakiet do klasy.
  • Akcja. Co dzieje się z pakietem po dopasowaniu: przekazanie, odrzucenie, przekierowanie.

Tworzą one drzewo. Pakiety wchodzą do qdiscu korzeniowego, trafiają do filtrów, są sortowane do klas przez major:minor identyfikatora i trafiają do kolejki w qdisc liścia w celu transmisji.

W przypadku operacji bardziej złożonych niż dopasowanie oparte na porcie, należy oznaczyć pakiety za pomocą iptables lub nftables w tabeli mangle, a następnie użyć fw filtru w tc w celu klasyfikacji według oznaczenia. Skaluje się to znacznie lepiej niż łańcuchowanie surowych u32 dla każdego typu ruchu.

Ruch wychodzący a ruch przychodzący

Kierunek ma znaczenie. Jądro może buforować i opóźniać pakiety wychodzące, co umożliwia rzeczywiste kształtowanie ruchu. Pakiety przychodzące przeszły już przez łącze, zanim je zobaczysz, więc możesz je jedynie kontrolować (odrzucać powyżej progu), chyba że najpierw przekierujesz je do urządzenia IFB.

FunkcjaWyjścieWchodzące
KierunekWychodzącePrzychodzące
KształtowanieNatywnyWymaga IFB
PolicingObsługiwaneObsługiwane
Typowe zastosowanieQoS, współdzielenie przepustowości, regulacja przepustowościOgraniczanie przepustowości, podstawowa ochrona przed atakami DDoS

Qdisc, z których faktycznie będziesz korzystać

  • HTB (Hierarchical Token Bucket). Klasowe. Używaj go, gdy chcesz zagwarantować minimalną przepustowość dla każdej usługi z możliwością pożyczenia niewykorzystanej przepustowości z innych klas.
  • TBF (Token Bucket Filter). Bezklasowy. Używaj go, gdy chcesz po prostu ograniczyć cały interfejs do jednej prędkości.
  • fq_codel (Fair Queuing Controlled Delay). Łączy sprawiedliwość przepływu z aktywnym zarządzaniem kolejką, aby wyeliminować bufferbloat. Jest to domyślny qdisc w większości dystrybucji Linuksa od wersji systemd 217 i jest dostarczany jako domyślny w RHEL 9. Zawsze dołączaj go jako qdisc liściowy pod klasami HTB, w przeciwnym razie pojedynczy chciwy przepływ może zająć całą klasę.

Konfiguracja tc na serwerze z systemem Linux

tc jest dostarczany wraz z pakietem iproute2. W systemach Debian i Ubuntu należy go zainstalować za pomocą apt-get install iproute2. W systemie RHEL i jego pochodnych yum install iproute. Potrzebne będą uprawnienia roota lub sudo.

Najpierw sprawdź poprawną nazwę interfejsu. Błędne nazwanie interfejsu jest najczęstszą przyczyną, dla której konfiguracja po cichu nie działa:

ip link show

Sprawdź, co już znajduje się na interfejsie, w tym aktualne liczniki:

tc -s qdisc show dev eth0

Przed zastosowaniem nowej konfiguracji usuń wszelkie istniejące qdisc typu root, aby uniknąć RTNETLINK answers: File exists błędów:

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

Jeśli aktualizujesz istniejącą regułę, a nie zaczynasz od zera, użyj replace zamiast add , aby uzyskać atomową zamianę.

Odciążanie sprzętowe, takie jak TSO i GSO, grupuje pakiety w sposób, który zakłóca kształtowanie ruchu. Wyłącz je na interfejsie, na którym stosowane jest kształtowanie:

sudo ethtool -K eth0 tso off gso off

Ustaw fq_codel jako domyślny qdisc dla nowych interfejsów w całym systemie:

sysctl -w net.core.default_qdisc=fq_codel

W przypadku obciążonych serwerów połącz to z algorytmem kontroli przeciążenia BBR (jądro 4.9+). BBR utrzymuje wysoką przepustowość bez wydłużania kolejek:

sysctl -w net.ipv4.tcp_congestion_control=bbr

Jednym z bezpiecznych nawyków podczas konfiguracji zdalnego urządzenia przez SSH jest: otwarcie drugiej sesji i przygotowanie tc qdisc del dev eth0 root gotowy do wklejenia. Zła reguła filtrująca może natychmiast zablokować dostęp.

Kształtowanie ruchu wychodzącego za pomocą HTB

HTB pozwala przypisać każdej usłudze gwarantowaną wartość minimalną (rate) oraz limit maksymalny (ceil). Niewykorzystana przepustowość trafia do tego, kto jej potrzebuje, w kolejności według priorytetów. Oto działająca konfiguracja trójwarstwowa dla łącza uplink o przepustowości 1 Gb/s.

Utwórz główny qdisc HTB. default 30 wysyła każdy niesklasyfikowany pakiet do klasy 1:30 zamiast pozwolić mu ominąć twoje reguły:

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

Ogranicz całkowitą przepustowość do 900 Mb/s. Zawsze kształtuj przepustowość nieco poniżej rzeczywistej przepustowości łącza, w przeciwnym razie kolejka utworzy się na routerze lub modemie upstream, nad którym nie masz kontroli:

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

Zdefiniuj poziomy usług. Niższe prio wartości otrzymują niewykorzystaną przepustowość jako pierwsze:

# 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

Dołącz fq_codel jako qdisc liścia w każdej klasie, aby pojedynczy strumień nie mógł zdominować swojej klasy:

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

Teraz sklasyfikuj ruch. W przypadku prostego dopasowywania portów u32 jest najszybsze:

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

W przypadku wszystkiego, co jest stanowe, oznacz w iptables i dopasuj oznaczenie do 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

Kształtowanie ruchu przychodzącego za pomocą IFB

Nie można natywnie kształtować ruchu przychodzącego, ponieważ w momencie dotarcia pakietu wykorzystał on już przepustowość. Rozwiązaniem jest przekierowanie ruchu przychodzącego do wirtualnego interfejsu Intermediate Functional Block (IFB), gdzie jądro traktuje go jako ruch wychodzący i pozwala na zastosowanie klasowych qdisców.

Załaduj moduł i uruchom interfejs:

modprobe ifb numifbs=1
ip link set dev ifb0 up

Dodaj qdisc ruchu przychodzącego do interfejsu fizycznego i przekieruj wszystko do 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

Od tego momentu ifb0 zachowuje się jak każdy inny interfejs. Zastosuj do niego drzewo HTB dokładnie tak, jak w przypadku ruchu wychodzącego:

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

Priorytetyzacja ruchu za pomocą DSCP

DSCP (Differentiated Services Code Point) oznacza pakiety 6-bitową wartością w bajcie TOS, dzięki czemu tc filtry mogą klasyfikować na podstawie tagu, zamiast przeszukiwać porty w całym zestawie reguł. Podczas dopasowywania DSCP w tc, przesuń wartość w lewo o 2 bity. DSCP EF (46) staje się 0xb8. Maska 0xfc izoluje 6 bitów DSCP od 2 bitów ECN.

Rozsądne domyślne przyporządkowanie dla obciążeń serwerowych:

Typ ruchuDSCPTOS (szesnastkowo)Przykłady
InteraktywnyEF0xb8SSH, DNS, VoIP
BiznesAF410x88HTTP, HTTPS, API
HurtoweCS10x20Kopie zapasowe, FTP, aktualizacje pakietów
Najlepsze staraniaCS00x00Wszystko inne

Oznacz pakiety wychodzące w iptables, zanim trafią do twoich tc filtry:

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

Następnie dopasuj tag w tc i przekieruj go do odpowiedniej klasy 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

Monitorowanie i rozwiązywanie problemów

Trzy polecenia, z których będziesz korzystać na co dzień:

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

Obserwuj dropped i overlimits liczników. Utracone pakiety oznaczają, że kolejka jest przepełniona; przekroczenie limitów oznacza, że osiągnąłeś pułap klasy i jądro musiało opóźnić lub odrzucić ruch. Aby uzyskać widok na żywo:

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

Dodaj -d dla parametrów wewnętrznych (target, interval, quantum) oraz -j dla wyjścia JSON, jeśli przekierowujesz dane do stosu metrycznego. Połącz to z ss -tin , aby zobaczyć szacunki RTT i retransmisje na warstwie TCP.

Większość awarii mieści się w krótkiej liście:

ObjawPrawdopodobna przyczynaRozwiązanie
RTNETLINK answers: File existsDyskretny mechanizm root już skonfigurowanytc qdisc del dev eth0 root pierwsze
Reguły mają zastosowanie, ale ruch nie jest ograniczanyNieprawidłowy interfejs lub TSO/GSO nadal włączonePotwierdź za pomocą ip link show, wyłącz odciążanie za pomocą ethtool -K
Filtr nigdy nie pasujeNieprawidłowa składnia portu/adresu IP lub wyrównanie maskiDodaj działanie przeciwdziałające i sprawdź liczbę trafień w tc -s filter show
Zasady znikają po ponownym uruchomieniuKonfiguracja znajduje się wyłącznie w pamięciZapakuj w skrypt i wywołaj z systemd lub dyspozytora NetworkManager
Duże opóźnienia w ruchu priorytetowymBrak qdisc typu leaf lub zbyt niski limit burstDołącz fq_codel do klas liściowych, podnieś burst

Jeśli kiedykolwiek zablokujesz się przez błędną konfigurację, reset jest prosty:

tc qdisc del dev eth0 root

tc nie da się wyczarować przepustowości, której nie masz, ale w przypadku dobrze skonfigurowanego łącza uplink stanowi to różnicę między przewidywalną wydajnością a serwerem, który się załamuje w momencie, gdy jeden z użytkowników rozpocznie duży transfer. Jeśli potrzebujesz surowej przepustowości i swobody kształtowania jej tak, jak chcesz, zapoznaj się z serwerami dedykowanymi FDC.

Blog

Polecane w tym tygodniu

Więcej artykułów
Linux Traffic Control (tc): praktyczny przewodnik

Linux Traffic Control (tc): praktyczny przewodnik

Kontroluj przepustowość, ustalaj priorytety ruchu oraz kształtuj ruch przychodzący i wychodzący w systemie Linux za pomocą tc. Działająca konfiguracja HTB, IFB, DSCP i fq_codel dla rzeczywistych serwerów.

12 min czytania - 5 czerwca 2026

Dlaczego ważne jest posiadanie wydajnego i niezmierzonego serwera VPS?

7 min czytania - 9 maja 2025

Więcej artykułów
background image

Masz pytania lub potrzebujesz niestandardowego rozwiązania?

icon

Elastyczne opcje

icon

Globalny zasięg

icon

Natychmiastowe wdrożenie

icon

Elastyczne opcje

icon

Globalny zasięg

icon

Natychmiastowe wdrożenie