#server-performance

Controllo del traffico Linux (tc): una guida pratica

12 min di lettura - 5 giugno 2026

hero section cover

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.

CaratteristicaIn uscitaIngresso
DirezioneIn uscitaIn entrata
ModellazioneNativoRichiede IFB
ControlloSupportatoSupportato
Utilizzo tipicoQoS, condivisione della larghezza di banda, regolazione del flussoLimitazione 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 show

Controllate cosa è già presente sull'interfaccia, compresi i contatori in tempo reale:

tc -s qdisc show dev eth0

Eliminare 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 || true

Se 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 off

Imposta fq_codel come qdisc predefinito a livello di sistema per le nuove interfacce:

sysctl -w net.core.default_qdisc=fq_codel

Per 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=bbr

Un'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 30

Limita 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 900mbit

Definire 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 3

Aggiungere 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_codel

Ora 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:10

Per 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:20

Modellazione 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 up

Aggiungere 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 ifb0

Da 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 1

Priorità 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 trafficoDSCPTOS esadecimaleEsempi
InterattivoEF0xb8SSH, DNS, VoIP
AziendaleAF410x88HTTP, HTTPS, API
In bloccoCS10x20Backup, FTP, aggiornamenti dei pacchetti
Best effortCS00x00Tutto 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 46

Quindi 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:30

Monitoraggio 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 eth0

Tieni 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:

SintomoProbabile causaSoluzione
RTNETLINK answers: File existsqdisc di root già configuratotc qdisc del dev eth0 root prima
Le regole vengono applicate ma il traffico non viene limitatoInterfaccia errata oppure TSO/GSO ancora attiviVerificare con ip link show, disabilitare gli offload con ethtool -K
Il filtro non trova mai corrispondenzeSintassi errata della porta/dell'IP o allineamento della mascheraAggiungere un'azione di contromisura e controllare il conteggio degli accessi in tc -s filter show
Regole scomparse dopo il riavvioLa configurazione risiede solo in memoriaIncorporare in uno script e richiamare da systemd o da un dispatcher di NetworkManager
Elevata latenza sul traffico prioritarioNessun qdisc di tipo "leaf" o burst troppo bassoCollegare 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 root

tc 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.

Blog

In primo piano questa settimana

Altri articoli
Tutorial su iperf3: come testare la velocità di rete su Linux e Windows
#bandwidth#server-performance

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

Altri articoli
background image

Avete domande o avete bisogno di una soluzione personalizzata?

icon

Opzioni flessibili

icon

Portata globale

icon

Distribuzione immediata

icon

Opzioni flessibili

icon

Portata globale

icon

Distribuzione immediata