Linux verkeerscontrole (tc): een praktische gids
12 min lezen - 5 juni 2026

Regel bandbreedte, prioriteer verkeer en geef vorm aan ingress en egress op Linux met tc. Werkende HTB, IFB, DSCP en fq_codel configuratie voor echte servers.
Linux Traffic Control (tc): een praktische gids
Het tc commando geeft u directe controle over hoe uw server het netwerkverkeer afhandelt. U kunt de bandbreedte per service beperken, interactieve sessies zoals SSH responsief houden wanneer bulkverkeer piekt, en zowel uitgaande als inkomende stromen regelen vanuit één enkele tool. Deze gids behandelt de kernconcepten, een werkende HTB-configuratie, ingangsstromen regelen met IFB, DSCP-gebaseerde prioritering, en hoe u fouten kunt opsporen wanneer er iets misgaat.
Hoe tc werkt
Elke tc opstelling bestaat uit vier onderdelen:
- qdisc (queuing discipline). De scheduler die aan een netwerkinterface is gekoppeld. Deze bepaalt hoe pakketten in de wachtrij worden geplaatst en eruit worden gehaald.
- Class. Een onderverdeling binnen een classful qdisc. Zie het als een rijstrook met een eigen snelheidslimiet.
- Filter. Controleert pakketheaders (IP's, poorten, markeringen) en wijst elk pakket toe aan een klasse.
- Actie. Wat er met een pakket gebeurt zodra het overeenkomt: doorsturen, verwijderen, omleiden.
Deze vormen een boomstructuur. Pakketten komen binnen bij de root-qdisc, passeren filters, worden door een major:minor handle en komen uiteindelijk in de wachtrij van een leaf-qdisc terecht voor verzending.
Voor alles wat complexer is dan op poorten gebaseerde matching, markeer je pakketten met iptables of nftables in de mangle-tabel, en gebruik je vervolgens het fw filter in tc om op markering te classificeren. Dit schaalbaar veel beter dan het koppelen van ruwe u32 regels voor elk type verkeer.
Uitgaand versus inkomend
De richting is van belang. De kernel kan uitgaande pakketten bufferen en vertragen, wat echte shaping mogelijk maakt. Inkomende pakketten zijn al over de kabel gegaan tegen de tijd dat je ze ziet, dus je kunt ze alleen controleren (drogen boven een drempel) tenzij je ze eerst omleidt naar een IFB-apparaat.
| Functie | Uitgaand | Ingang |
|---|---|---|
| Richting | Uitgaand | Inkomend |
| Shaping | Native | Vereist IFB |
| Policing | Ondersteund | Ondersteund |
| Typisch gebruik | QoS, bandbreedteverdeling, pacing | Snelheidsbeperking, basis DDoS-beperking |
De qdiscs die u daadwerkelijk zult gebruiken
- HTB (Hierarchical Token Bucket). Classful. Gebruik dit wanneer u gegarandeerde minimale bandbreedte per service wilt met de mogelijkheid om ongebruikte capaciteit van andere klassen te lenen.
- TBF (Token Bucket Filter). Klassevrij. Gebruik dit wanneer u gewoon een hele interface op één snelheid wilt begrenzen.
- fq_codel (Fair Queuing Controlled Delay). Combineert fairness per flow met actief wachtrijbeheer om bufferbloat te voorkomen. Dit is sinds systemd 217 de standaard qdisc in de meeste Linux-distributies en wordt standaard meegeleverd met RHEL 9. Sluit deze altijd aan als een leaf qdisc onder HTB-klassen, anders kan één enkele gulzige flow een hele klasse in beslag nemen.
tc instellen op een Linux-server
tc wordt meegeleverd met het iproute2-pakket. Installeer het op Debian en Ubuntu met apt-get install iproute2. Op RHEL en afgeleiden yum install iproute. U hebt root-toegang of sudo nodig.
Zorg eerst dat u de juiste interfacenaam hebt. Een verkeerde naam voor de interface is de meest voorkomende reden waarom een configuratie stilzwijgend niets doet:
ip link showControleer wat er al op de interface staat, inclusief live tellers:
tc -s qdisc show dev eth0Wis alle bestaande root-qdiscs voordat je een nieuwe configuratie toepast, om RTNETLINK answers: File exists fouten te voorkomen:
tc qdisc del dev eth0 root 2>/dev/null || trueAls je een bestaande regel bijwerkt in plaats van helemaal opnieuw te beginnen, gebruik dan replace in plaats van add voor een atomaire swap.
Hardware-offloading zoals TSO en GSO bundelt pakketten op manieren die shaping verstoren. Schakel ze uit op de shaped interface:
sudo ethtool -K eth0 tso off gso offStel fq_codel in als de systeembrede standaard qdisc voor nieuwe interfaces:
sysctl -w net.core.default_qdisc=fq_codelCombineer dit voor drukke servers met het BBR-congestiebeheersingsalgoritme (kernel 4.9+). BBR houdt de doorvoer hoog zonder dat de wachtrijen groeien:
sysctl -w net.ipv4.tcp_congestion_control=bbrEen veilige gewoonte als u een externe box via SSH configureert: open een tweede sessie en zorg dat tc qdisc del dev eth0 root klaar om te plakken. Een verkeerde filterregel kan je onmiddellijk buitensluiten.
Uitgaand verkeer vormgeven met HTB
Met HTB kunt u elke dienst een gegarandeerd minimum (rate) en een maximum (ceil). Ongebruikte bandbreedte gaat naar degene die deze nodig heeft, in volgorde van prioriteit. Hier volgt een werkende drielaagse opstelling voor een 1 Gbps-uplink.
Maak de root HTB-qdisc aan. De default 30 stuurt elk niet-geclassificeerd pakket naar klasse 1:30 in plaats van het je regels te laten omzeilen:
tc qdisc add dev eth0 root handle 1: htb default 30Beperk de totale doorvoer tot 900 Mbps. Shape altijd iets onder de werkelijke linkcapaciteit, anders vormt zich een wachtrij op een upstream router of modem waar je geen controle over hebt:
tc class add dev eth0 parent 1: classid 1:1 htb rate 900mbit ceil 900mbitDefinieer de servicelagen. Lagere prio waarden krijgen als eerste ongebruikte bandbreedte:
# 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 3Voeg fq_codel als de leaf-qdisc aan elke klasse, zodat één enkele stroom zijn tier niet kan domineren:
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_codelClassificeer nu het verkeer. Voor eenvoudige poortmatching u32 is het snelst:
tc filter add dev eth0 protocol ip parent 1:0 prio 1 u32 \
match ip dport 443 0xffff flowid 1:10Voor alles wat stateful is, markeer in iptables en match de markering met 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:20Inkomend verkeer vormgeven met IFB
U kunt inkomend verkeer niet native shapen, omdat het op het moment dat een pakket aankomt al uw bandbreedte heeft gebruikt. De oplossing is om inkomend verkeer om te leiden naar een virtuele interface van het Intermediate Functional Block (IFB), waar de kernel het behandelt als uitgaand verkeer en u classful qdiscs kunt toepassen.
Laad de module en start de interface op:
modprobe ifb numifbs=1
ip link set dev ifb0 upVoeg een ingangs-qdisc toe aan de fysieke interface en leid alles om naar 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 ifb0Vanaf hier ifb0 gedraagt zich als elke andere interface. Pas je HTB-boom erop toe, precies zoals je dat bij uitgaand verkeer zou doen:
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 1Verkeer prioriteren met DSCP
DSCP (Differentiated Services Code Point) markeert pakketten met een 6-bits waarde in de TOS-byte, zodat uw tc filters kunnen classificeren op basis van de tag in plaats van poorten te moeten doorzoeken in de regelset. Bij het matchen van DSCP in tc, verschuif de waarde dan 2 bits naar links. DSCP EF (46) wordt 0xb8. Het masker 0xfc isoleert de 6 DSCP-bits van de 2 ECN-bits.
Een verstandige standaardtoewijzing voor serverworkloads:
| Verkeerstype | DSCP | TOS hex | Voorbeelden |
|---|---|---|---|
| Interactief | EF | 0xb8 | SSH, DNS, VoIP |
| Zakelijk | AF41 | 0x88 | HTTP, HTTPS, API's |
| Bulk | CS1 | 0x20 | Back-ups, FTP, pakketupdates |
| Best effort | CS0 | 0x00 | Al het overige |
Markeer uitgaande pakketten in iptables voordat ze je tc filters:
iptables -t mangle -A OUTPUT -p tcp --dport 22 -j DSCP --set-dscp 46Koppel vervolgens de tag in tc en routeer het naar de juiste HTB-klasse:
# 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:30Monitoring en probleemoplossing
De drie commando's die je voortdurend zult gebruiken:
tc -s qdisc show dev eth0
tc -s class show dev eth0
tc -s filter show dev eth0Houd de dropped en overlimits tellers. Verloren pakketten betekenen dat de wachtrij verzadigd is; overschrijdingen betekenen dat je een klasse-limiet hebt bereikt en dat de kernel het verkeer moest vertragen of afwerpen. Voor een live weergave:
watch -n 1 'tc -s class show dev eth0'Voeg -d voor interne parameters (target, interval, quantum) en -j voor JSON-uitvoer als je naar een metrics-stack pipet. Combineer dit met ss -tin om RTT-schattingen en hertransmissies op de TCP-laag te zien.
De meeste storingen vallen onder een korte lijst:
| Symptoom | Waarschijnlijke oorzaak | Oplossing |
|---|---|---|
RTNETLINK answers: File exists | Root qdisc is al geconfigureerd | tc qdisc del dev eth0 root eerste |
| Regels zijn van toepassing, maar het verkeer wordt niet beperkt | Verkeerde interface, of TSO/GSO nog steeds ingeschakeld | Bevestig met ip link show, schakel offloads uit met ethtool -K |
| Filter komt nooit overeen | Verkeerde poort/IP-syntaxis of mask-uitlijning | Voeg een tegenmaatregel toe en controleer het aantal treffers in tc -s filter show |
| Regels verdwenen na herstart | Configuratie staat alleen in het geheugen | Verpak in een script en roep aan vanuit systemd of een NetworkManager-dispatcher |
| Hoge latentie bij prioritair verkeer | Geen leaf-qdisc, of burst te laag | Koppel fq_codel aan leaf-klassen, verhoog burst |
Als je jezelf ooit buitensluit door een verkeerde configuratie, is het resetten eenvoudig:
tc qdisc del dev eth0 roottc je kunt geen bandbreedte creëren die je niet hebt, maar op een goed geconfigureerde uplink maakt het het verschil tussen voorspelbare prestaties en een server die instort op het moment dat één gebruiker een grote overdracht start. Als je de ruwe bandbreedte nodig hebt en de vrijheid om deze naar eigen wens te vormen, kijk dan eens naar de dedicated servers van FDC.

Linux verkeerscontrole (tc): een praktische gids
Regel bandbreedte, prioriteer verkeer en geef vorm aan ingress en egress op Linux met tc. Werkende HTB, IFB, DSCP en fq_codel configuratie voor echte servers.
12 min lezen - 5 juni 2026
Waarom het belangrijk is om een krachtige en unmetered VPS te hebben
7 min lezen - 9 mei 2025

Hebt u vragen of wilt u een oplossing op maat?
Flexibele opties
Wereldwijd bereik
Directe inzet
Flexibele opties
Wereldwijd bereik
Directe inzet