#server-performance

Linux Traffic Control (tc): Ein praktischer Leitfaden

12 Min. Lesezeit - 5. Juni 2026

hero section cover

Bandbreite steuern, Datenverkehr priorisieren und eingehenden sowie ausgehenden Datenverkehr unter Linux mit „tc“ gestalten. Funktionierende Konfigurationen für HTB, IFB, DSCP und fq_codel für echte Server.

Linux Traffic Control (tc): Ein praktischer Leitfaden

Der Linux-Befehl tc Befehl gibt Ihnen direkte Kontrolle darüber, wie Ihr Server den Netzwerkverkehr handhabt. Sie können die Bandbreite pro Dienst begrenzen, interaktive Sitzungen wie SSH auch bei Spitzen bei Massendatenübertragungen reaktionsfähig halten und sowohl den ausgehenden als auch den eingehenden Datenfluss über ein einziges Tool steuern. Dieser Leitfaden behandelt die Kernkonzepte, eine funktionierende HTB-Konfiguration, Ingress-Shaping mit IFB, DSCP-basierte Priorisierung sowie die Fehlerbehebung, falls etwas nicht funktioniert.


 

So funktioniert tc

Jede tc Konfiguration besteht aus vier Komponenten:

  • qdisc (Queuing Discipline). Der an eine Netzwerkschnittstelle gekoppelte Scheduler. Er entscheidet, wie Pakete in die Warteschlange gestellt und aus ihr entnommen werden.
  • Klasse. Eine Unterteilung innerhalb eines klassenbasierten qdisc. Stellen Sie sich dies als eine Fahrspur mit eigener Geschwindigkeitsbegrenzung vor.
  • Filter. Überprüft Paket-Header (IP-Adressen, Ports, Markierungen) und ordnet jedes Paket einer Klasse zu.
  • Aktion. Was mit einem Paket geschieht, sobald es den Kriterien entspricht: weiterleiten, verwerfen, umleiten.

Diese bilden einen Baum. Pakete treten am Root-qdisc ein, durchlaufen Filter, werden von einem major:minor Handle in Klassen sortiert und landen schließlich in der Warteschlange eines Blatt-Qdiscs zur Übertragung.

Für alles, was komplexer ist als portbasierte Übereinstimmungen, markieren Sie Pakete mit iptables oder nftables in der Mangle-Tabelle und verwenden Sie anschließend den fw Filter in tc , um nach der Markierung zu klassifizieren. Dies skaliert weitaus besser als das Verketten von rohen u32 Regeln für jeden Verkehrstyp.

Ausgang vs. Eingang

Die Richtung spielt eine Rolle. Der Kernel kann ausgehende Pakete zwischenspeichern und verzögern, was echtes Shaping erst ermöglicht. Eingehende Pakete haben die Leitung bereits durchlaufen, wenn Sie sie sehen; daher können Sie sie nur überwachen (ab einem Schwellenwert verwerfen), es sei denn, Sie leiten sie zuvor an ein IFB-Gerät um.

FunktionAusgangIngress
RichtungAusgehendEingehend
ShapingNativErfordert IFB
PolicingUnterstütztUnterstützt
Typische VerwendungQoS, Bandbreitenaufteilung, PacingRatenbegrenzung, grundlegende DDoS-Abwehr

Die qdiscs, die Sie tatsächlich verwenden werden

  • HTB (Hierarchical Token Bucket). Klassenbasiert. Verwenden Sie diesen, wenn Sie eine garantierte Mindestbandbreite pro Dienst wünschen und dabei die Möglichkeit haben möchten, ungenutzte Kapazität von anderen Klassen auszuleihen.
  • TBF (Token Bucket Filter). Klassenlos. Verwenden Sie diesen, wenn Sie lediglich eine gesamte Schnittstelle auf eine bestimmte Rate begrenzen müssen.
  • fq_codel (Fair Queuing Controlled Delay). Kombiniert Fairness pro Datenfluss mit aktivem Warteschlangenmanagement, um Bufferbloat zu verhindern. Seit systemd 217 ist es der Standard-qdisc in den meisten Linux-Distributionen und wird standardmäßig mit RHEL 9 ausgeliefert. Fügen Sie es immer als Leaf-qdisc unter HTB-Klassen ein, da sonst ein einzelner „gieriger“ Datenfluss eine gesamte Klasse beanspruchen kann.

Einrichtung von tc auf einem Linux-Server

tc wird mit dem Paket „iproute2“ ausgeliefert. Unter Debian und Ubuntu installieren Sie es mit apt-get install iproute2. Unter RHEL und Derivaten yum install iproute. Sie benötigen Root-Rechte oder sudo.

Ermitteln Sie zunächst den korrekten Schnittstellennamen. Eine falsche Benennung der Schnittstelle ist der häufigste Grund dafür, dass eine Konfiguration stillschweigend keine Wirkung zeigt:

ip link show

Überprüfen Sie, was bereits auf der Schnittstelle vorhanden ist, einschließlich der Live-Zähler:

tc -s qdisc show dev eth0

Löschen Sie vor dem Anwenden einer neuen Konfiguration alle vorhandenen Root-Qdiscs, um RTNETLINK answers: File exists Fehler zu vermeiden:

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

Wenn Sie eine bestehende Regel aktualisieren, anstatt ganz von vorne anzufangen, verwenden Sie replace anstelle von add , um einen atomaren Austausch zu gewährleisten.

Hardware-Offloading wie TSO und GSO bündelt Pakete auf eine Weise, die das Shaping beeinträchtigt. Deaktivieren Sie diese Funktionen auf der geshapteten Schnittstelle:

sudo ethtool -K eth0 tso off gso off

Legen Sie fq_codel als systemweite Standard-qdisc für neue Schnittstellen fest:

sysctl -w net.core.default_qdisc=fq_codel

Kombinieren Sie dies bei stark ausgelasteten Servern mit dem BBR-Überlastungskontrollalgorithmus (Kernel 4.9+). BBR hält den Durchsatz hoch, ohne dass die Warteschlangen anwachsen:

sysctl -w net.ipv4.tcp_congestion_control=bbr

Eine Sicherheitsmaßnahme, wenn Sie einen Remote-Rechner über SSH konfigurieren: Öffnen Sie eine zweite Sitzung und halten Sie tc qdisc del dev eth0 root bereits zum Einfügen parat. Eine fehlerhafte Filterregel kann Sie sofort aussperren.

Gestaltung des ausgehenden Datenverkehrs mit HTB

Mit HTB können Sie jedem Dienst ein garantiertes Minimum (rate) und eine Obergrenze (ceil) zuweisen. Nicht genutzte Bandbreite wird in der Reihenfolge der Prioritäten an denjenigen weitergeleitet, der sie benötigt. Hier ist eine funktionierende dreistufige Konfiguration für einen 1-Gbit/s-Uplink.

Erstellen Sie den Root-HTB-qdisc. Der default 30 leitet jedes nicht klassifizierte Paket an die Klasse 1:30 , anstatt es Ihre Regeln umgehen zu lassen:

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

Begrenzen Sie den Gesamtdurchsatz auf 900 Mbps. Passen Sie die Bandbreite immer etwas unterhalb der tatsächlichen Verbindungskapazität an, da sich sonst eine Warteschlange auf einem vorgelagerten Router oder Modem bildet, über den Sie keine Kontrolle haben:

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

Definieren Sie die Service-Stufen. Niedrigere prio Werte erhalten zuerst die ungenutzte Bandbreite:

# 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

Fügen Sie fq_codel als Leaf-Qdisc an jede Klasse an, damit kein einzelner Datenfluss seine Stufe dominieren kann:

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

Klassifizieren Sie nun den Datenverkehr. Für einen einfachen Port-Abgleich u32 ist am schnellsten:

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

Für alles, was zustandsabhängig ist, markieren Sie in iptables und gleichen Sie die Markierung mit 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

Steuerung des eingehenden Datenverkehrs mit IFB

Eingehenden Datenverkehr lässt sich nicht nativ steuern, da ein Paket zum Zeitpunkt seines Eintreffens bereits Ihre Bandbreite beansprucht hat. Die Lösung besteht darin, den eingehenden Datenverkehr auf eine virtuelle Schnittstelle des Intermediate Functional Block (IFB) umzuleiten, wo der Kernel ihn als ausgehenden Datenverkehr behandelt und Ihnen die Anwendung von Classful-Qdiscs ermöglicht.

Laden Sie das Modul und aktivieren Sie die Schnittstelle:

modprobe ifb numifbs=1
ip link set dev ifb0 up

Fügen Sie der physischen Schnittstelle einen Ingress-Qdisc hinzu und leiten Sie den gesamten Datenverkehr um auf 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

Von hier aus ifb0 verhält sich wie jede andere Schnittstelle. Wenden Sie Ihren HTB-Baum genau so darauf an, wie Sie es beim ausgehenden Datenverkehr tun würden:

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

Priorisierung des Datenverkehrs mit DSCP

DSCP (Differentiated Services Code Point) kennzeichnet Pakete mit einem 6-Bit-Wert im TOS-Byte, sodass Ihre tc Filter können nach Tags klassifizieren, anstatt im Regelsatz nach Ports suchen zu müssen. Beim Abgleich von DSCP in tc, verschieben Sie den Wert um 2 Bits nach links. Aus DSCP EF (46) wird 0xb8. Die Maske 0xfc trennt die 6 DSCP-Bits von den 2 ECN-Bits.

Eine sinnvolle Standardzuordnung für Server-Workloads:

VerkehrstypDSCPTOS-HexBeispiele
InteraktivEF0xb8SSH, DNS, VoIP
BusinessAF410x88HTTP, HTTPS, APIs
MassenverarbeitungCS10x20Backups, FTP, Paket-Updates
Nach bestem BemühenCS00x00Alles andere

Kennzeichnen Sie ausgehende Pakete in iptables, bevor sie Ihre tc Filter gelangen:

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

Ordnen Sie das Tag anschließend in tc und leiten Sie es an die richtige HTB-Klasse weiter:

# 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

Überwachung und Fehlerbehebung

Die drei Befehle, die Sie ständig verwenden werden:

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

Beobachten Sie den dropped und overlimits Zähler im Auge. Verlorene Pakete bedeuten, dass die Warteschlange überlastet ist; Überschreitungen der Grenzwerte bedeuten, dass Sie die Obergrenze einer Klasse erreicht haben und der Kernel den Datenverkehr verzögern oder verwerfen musste. Für eine Live-Ansicht:

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

Fügen Sie -d für interne Parameter (Zielwert, Intervall, Quanten) und -j für die JSON-Ausgabe, falls Sie die Daten in einen Metrik-Stack weiterleiten. Kombinieren Sie dies mit ss -tin , um RTT-Schätzungen und Neuübertragungen auf der TCP-Ebene anzuzeigen.

Die meisten Fehler lassen sich auf eine kurze Liste zurückführen:

SymptomMögliche UrsacheBehebung
RTNETLINK answers: File existsRoot-qdisc bereits konfigurierttc qdisc del dev eth0 root zuerst
Regeln gelten, aber der Datenverkehr wird nicht begrenztFalsche Schnittstelle oder TSO/GSO noch aktiviertÜberprüfen Sie mit ip link show, deaktivieren Sie Offloads mit ethtool -K
Filter passt nieFalsche Port-/IP-Syntax oder Mask-AusrichtungFügen Sie eine Gegenmaßnahme hinzu und überprüfen Sie die Trefferanzahl in tc -s filter show
Regeln verschwinden nach dem NeustartDie Konfiguration befindet sich ausschließlich im ArbeitsspeicherIn ein Skript einbinden und über systemd oder einen NetworkManager-Dispatcher aufrufen
Hohe Latenz bei priorisiertem DatenverkehrKein Leaf-Qdisc oder zu niedrige Burst-RateAn fq_codel an Leaf-Klassen an, erhöhen burst

Sollten Sie sich jemals durch eine Fehlkonfiguration aussperren, ist das Zurücksetzen ganz einfach:

tc qdisc del dev eth0 root

tc Man kann keine Bandbreite erzeugen, die man nicht hat, aber bei einem gut dimensionierten Uplink macht dies den Unterschied zwischen vorhersehbarer Leistung und einem Server aus, der zusammenbricht, sobald ein Mandant eine große Übertragung startet. Wenn Sie die reine Bandbreite und die Freiheit benötigen, diese nach Belieben zu gestalten, werfen Sie einen Blick auf die dedizierten Server von FDC.

Blog

Diese Woche im Blickpunkt

Weitere Artikel
iperf3-Tutorial: Netzwerkgeschwindigkeit unter Linux und Windows testen
#bandwidth#server-performance

iperf3-Tutorial: Netzwerkgeschwindigkeit unter Linux und Windows testen

Installieren Sie iperf3, führen Sie Bandbreitentests durch und optimieren Sie die TCP-Puffer, um unter Linux und Windows genaue Ergebnisse zu erhalten. Behandelt werden UDP-, bidirektionale und 10GbE+-Tests.

10 Min. Lesezeit - 7. Mai 2026

#server-performance

Optimierte Profile für die Workload-Optimierung von Linux-Servern

16 Min. Lesezeit - 9. Juni 2026

Weitere Artikel
background image

Haben Sie Fragen oder benötigen Sie eine individuelle Lösung?

icon

Flexible Optionen

icon

Globale Reichweite

icon

Sofortige Bereitstellung

icon

Flexible Optionen

icon

Globale Reichweite

icon

Sofortige Bereitstellung