Controllo del traffico Linux (tc): una guida pratica
12 min di lettura - 5 giugno 2026

Controllare la larghezza di banda, assegnare priorità al traffico e modellare il traffico in entrata e in uscita su Linux con tc. Configurazioni funzionanti di HTB, IFB, DSCP e fq_codel per server reali.
Controllo del traffico Linux (tc): una guida pratica
Il comando tc ti offre il controllo diretto su come il tuo server gestisce il traffico di rete. È possibile limitare la larghezza di banda per servizio, garantire la reattività delle sessioni interattive come SSH in caso di picchi nei trasferimenti di grandi volumi e modellare sia i flussi in uscita che quelli in entrata da un unico strumento. Questa guida illustra i concetti fondamentali, una configurazione HTB funzionante, la modellazione in ingresso con IFB, la prioritizzazione basata su DSCP e come eseguire il debug in caso di malfunzionamenti.
Come funziona tc
Ogni tc configurazione è costituita da quattro componenti:
- qdisc (disciplina di accodamento). Lo scheduler associato a un'interfaccia di rete. Decide come i pacchetti vengono accodati e rimossi dalla coda.
- Classe. Una suddivisione all’interno di un qdisc classful. Immaginatela come una corsia con un proprio limite di velocità.
- Filtro. Esamina le intestazioni dei pacchetti (indirizzi IP, porte, marcatori) e assegna ogni pacchetto a una classe.
- Azione. Cosa succede a un pacchetto una volta che soddisfa i criteri: inoltro, scarto, reindirizzamento.
Questi elementi formano un albero. I pacchetti entrano nel qdisc radice, incontrano i filtri, vengono smistati nelle classi tramite un major:minor handle e finiscono in coda in un qdisc foglia per la trasmissione.
Per qualsiasi cosa più complessa della corrispondenza basata sulla porta, contrassegnare i pacchetti con iptables o nftables nella tabella mangle, quindi utilizzare il fw filtro in tc per classificarli in base al contrassegno. È molto più scalabile rispetto all’impostazione di regole grezze u32 per ogni tipo di traffico.
Uscita vs entrata
La direzione è importante. Il kernel può mettere in buffer e ritardare i pacchetti in uscita, ed è proprio questo che consente un vero shaping. I pacchetti in entrata hanno già attraversato la linea quando li vedete, quindi potete solo controllarne il flusso (eliminandoli se superano una soglia) a meno che non li reindirizziate prima verso un dispositivo IFB.
| Caratteristica | In uscita | Ingresso |
|---|---|---|
| Direzione | In uscita | In entrata |
| Modellazione | Nativo | Richiede IFB |
| Controllo | Supportato | Supportato |
| Utilizzo tipico | QoS, condivisione della larghezza di banda, regolazione del flusso | Limitazione della velocità, mitigazione DDoS di base |
I qdisc che userete effettivamente
- HTB (Hierarchical Token Bucket). Con classi. Da utilizzare quando si desidera una larghezza di banda minima garantita per servizio con la possibilità di attingere alla capacità inutilizzata di altre classi.
- TBF (Token Bucket Filter). Senza classi. Da utilizzare quando è necessario limitare l’intera interfaccia a una singola velocità.
- fq_codel (Fair Queuing Controlled Delay). Combina l’equità per flusso con la gestione attiva delle code per eliminare il bufferbloat. È il qdisc predefinito nella maggior parte delle distribuzioni Linux a partire da systemd 217 ed è preinstallato di default su RHEL 9. Assicuratevi sempre di collegarlo come qdisc foglia sotto le classi HTB, altrimenti un singolo flusso avido potrebbe monopolizzare un’intera classe.
Configurazione di tc su un server Linux
tc è incluso nel pacchetto iproute2. Su Debian e Ubuntu, installarlo con apt-get install iproute2. Su RHEL e distribuzioni derivate, yum install iproute. È necessario disporre dei privilegi di root o di sudo.
Per prima cosa, individuate il nome corretto dell’interfaccia. Un errore nel nome dell’interfaccia è la causa più comune per cui una configurazione non produce alcun risultato:
ip link showControllate cosa è già presente sull'interfaccia, compresi i contatori in tempo reale:
tc -s qdisc show dev eth0Eliminare qualsiasi qdisc di root esistente prima di applicare una nuova configurazione, per evitare RTNETLINK answers: File exists errori:
tc qdisc del dev eth0 root 2>/dev/null || trueSe state aggiornando una regola esistente anziché partire da zero, utilizzate replace invece di add per uno scambio atomico.
L'offloading hardware come TSO e GSO raggruppa i pacchetti in modi che interferiscono con lo shaping. Disattivarli sull'interfaccia sottoposta a shaping:
sudo ethtool -K eth0 tso off gso offImposta fq_codel come qdisc predefinito a livello di sistema per le nuove interfacce:
sysctl -w net.core.default_qdisc=fq_codelPer i server molto trafficati, abbinalo all’algoritmo di controllo della congestione BBR (kernel 4.9+). Il BBR mantiene elevata la velocità di trasmissione senza far crescere le code:
sysctl -w net.ipv4.tcp_congestion_control=bbrUn'abitudine di sicurezza se si sta configurando una macchina remota tramite SSH: aprire una seconda sessione e tenere tc qdisc del dev eth0 root pronto da incollare. Una regola di filtraggio errata può bloccare l'accesso all'istante.
Regolazione del traffico in uscita con HTB
L'HTB consente di assegnare a ciascun servizio un minimo garantito (rate) e un limite massimo (ceil). La larghezza di banda inutilizzata viene destinata a chi ne ha bisogno, in ordine di priorità. Ecco una configurazione funzionante a tre livelli per un uplink da 1 Gbps.
Creare il qdisc HTB radice. Il default 30 invia qualsiasi pacchetto non classificato alla classe 1:30 anziché lasciarlo bypassare le tue regole:
tc qdisc add dev eth0 root handle 1: htb default 30Limita il throughput totale a 900 Mbps. Regola sempre la larghezza di banda leggermente al di sotto della capacità effettiva del collegamento, altrimenti si formerà una coda su un router o un modem a monte che non controlli:
tc class add dev eth0 parent 1: classid 1:1 htb rate 900mbit ceil 900mbitDefinire i livelli di servizio. I valori prio valori ottengono per primi la larghezza di banda inutilizzata:
# 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 3Aggiungere fq_codel come qdisc foglia su ciascuna classe, in modo che un singolo flusso non possa dominare il proprio livello:
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_codelOra classificare il traffico. Per una semplice corrispondenza delle porte, u32 è la soluzione più veloce:
tc filter add dev eth0 protocol ip parent 1:0 prio 1 u32 \
match ip dport 443 0xffff flowid 1:10Per qualsiasi cosa che sia stateful, contrassegnare in iptables e abbinare il contrassegno con 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:20Modellazione del traffico in entrata con IFB
Non è possibile modellare il traffico in entrata in modo nativo perché, nel momento in cui un pacchetto arriva, ha già utilizzato la larghezza di banda. La soluzione alternativa consiste nel reindirizzare il traffico in entrata verso un'interfaccia virtuale Intermediate Functional Block (IFB), dove il kernel lo tratta come traffico in uscita e consente di applicare qdisc basati su classi.
Caricare il modulo e attivare l’interfaccia:
modprobe ifb numifbs=1
ip link set dev ifb0 upAggiungere un qdisc di ingresso all’interfaccia fisica e reindirizzare tutto verso 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 ifb0Da questo momento in poi, ifb0 si comporta come qualsiasi altra interfaccia. Applicarvi l’albero HTB esattamente come fareste sul traffico in uscita:
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 1Priorità del traffico con DSCP
Il DSCP (Differentiated Services Code Point) contrassegna i pacchetti con un valore a 6 bit nel byte TOS, in modo che i tc filtri possano classificare in base al tag anziché dover cercare le porte nell’insieme delle regole. Quando si effettua la corrispondenza del DSCP in tc, sposta il valore di 2 bit verso sinistra. DSCP EF (46) diventa 0xb8. La maschera 0xfc isola i 6 bit DSCP dai 2 bit ECN.
Una mappatura predefinita ragionevole per i carichi di lavoro dei server:
| Tipo di traffico | DSCP | TOS esadecimale | Esempi |
|---|---|---|---|
| Interattivo | EF | 0xb8 | SSH, DNS, VoIP |
| Aziendale | AF41 | 0x88 | HTTP, HTTPS, API |
| In blocco | CS1 | 0x20 | Backup, FTP, aggiornamenti dei pacchetti |
| Best effort | CS0 | 0x00 | Tutto il resto |
Contrassegna i pacchetti in uscita in iptables prima che raggiungano i tuoi tc filtri:
iptables -t mangle -A OUTPUT -p tcp --dport 22 -j DSCP --set-dscp 46Quindi abbinare il tag in tc e instradalo alla classe HTB corretta:
# 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:30Monitoraggio e risoluzione dei problemi
I tre comandi che userete costantemente:
tc -s qdisc show dev eth0
tc -s class show dev eth0
tc -s filter show dev eth0Tieni d'occhio il dropped e overlimits contatori. I pacchetti persi indicano che la coda è satura; il superamento dei limiti significa che hai raggiunto il tetto massimo della classe e il kernel ha dovuto ritardare o scartare il traffico. Per una visualizzazione in tempo reale:
watch -n 1 'tc -s class show dev eth0'Aggiungi -d per i parametri interni (target, interval, quantum) e -j per l'output JSON se stai inviando i dati tramite pipe a uno stack di metriche. Abbinalo a ss -tin per visualizzare le stime RTT e le ritrasmissioni a livello di TCP.
La maggior parte degli errori rientra in un breve elenco:
| Sintomo | Probabile causa | Soluzione |
|---|---|---|
RTNETLINK answers: File exists | qdisc di root già configurato | tc qdisc del dev eth0 root prima |
| Le regole vengono applicate ma il traffico non viene limitato | Interfaccia errata oppure TSO/GSO ancora attivi | Verificare con ip link show, disabilitare gli offload con ethtool -K |
| Il filtro non trova mai corrispondenze | Sintassi errata della porta/dell'IP o allineamento della maschera | Aggiungere un'azione di contromisura e controllare il conteggio degli accessi in tc -s filter show |
| Regole scomparse dopo il riavvio | La configurazione risiede solo in memoria | Incorporare in uno script e richiamare da systemd o da un dispatcher di NetworkManager |
| Elevata latenza sul traffico prioritario | Nessun qdisc di tipo "leaf" o burst troppo basso | Collegare fq_codel alle classi leaf, aumentare burst |
Se mai dovessi ritrovarti bloccato a causa di una configurazione errata, il ripristino è semplice:
tc qdisc del dev eth0 roottc non è possibile creare larghezza di banda che non si possiede, ma su un uplink ben dimensionato fa la differenza tra prestazioni prevedibili e un server che va in crisi nel momento in cui un utente avvia un trasferimento di grandi dimensioni. Se avete bisogno della larghezza di banda grezza e della libertà di modellarla come preferite, date un'occhiata ai server dedicati di FDC.

Tutorial su iperf3: come testare la velocità di rete su Linux e Windows
Installare iperf3, eseguire test di larghezza di banda e ottimizzare i buffer TCP per ottenere risultati accurati su Linux e Windows. Vengono trattati i test UDP, bidirezionali e 10GbE+.
10 min di lettura - 7 maggio 2026
Profili ottimizzati per l’ottimizzazione del carico di lavoro dei server Linux
16 min di lettura - 9 giugno 2026

Avete domande o avete bisogno di una soluzione personalizzata?
Opzioni flessibili
Portata globale
Distribuzione immediata
Opzioni flessibili
Portata globale
Distribuzione immediata