Controllo del traffico (tc) di Linux: una guida pratica

12 min di lettura - 5 giugno 2026

hero section cover
Indice
  • Controllo del traffico Linux (tc): una guida pratica
  • Come funziona tc
  • Configurazione di tc su un server Linux
  • Modellare il traffico in uscita con HTB
  • Modellare il traffico in entrata con IFB
  • Priorità del traffico con DSCP
  • Monitoraggio e risoluzione dei problemi
Condividi

Controllare la larghezza di banda, assegnare priorità al traffico e modellare l'ingresso e l'uscita su Linux con tc. Configurazione 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, mantenere reattive le sessioni interattive come SSH quando i trasferimenti in blocco raggiungono picchi elevati e modellare sia i flussi in uscita che quelli in entrata da un unico strumento. Questa guida tratta i concetti fondamentali, una configurazione HTB funzionante, l'ingress shaping 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 parti mobili:

  • qdisc (queuing discipline). Lo scheduler collegato a un'interfaccia di rete. Decide come i pacchetti vengono inseriti e rimossi dalla coda.
  • Classe. Una suddivisione all'interno di un qdisc classful. Pensatela come una corsia con un proprio limite di velocità.
  • Filtro. Esamina le intestazioni dei pacchetti (IP, porte, marcatori) e assegna ogni pacchetto a una classe.
  • Azione. Cosa succede a un pacchetto una volta che viene abbinato: inoltro, eliminazione, reindirizzamento.

Questi elementi formano un albero. I pacchetti entrano nel qdisc radice, incontrano i filtri, vengono ordinati in 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 classificare in base al contrassegno. È molto più scalabile rispetto al concatenare regole grezze u32 per ogni tipo di traffico.

Uscita vs entrata

La direzione è importante. Il kernel può bufferizzare e ritardare i pacchetti in uscita, ed è questo che consente un vero shaping. I pacchetti in entrata hanno già attraversato la linea quando li vedete, quindi potete solo controllarli (eliminarli se superano una soglia) a meno che non li reindirizziate prima verso un dispositivo IFB.

CaratteristicaUscitaIngresso
DirezioneIn uscitaIn entrata
ModellazioneNativoRichiede IFB
ControlloSupportatoSupportato
Uso tipicoQoS, condivisione della larghezza di banda, regolazione della velocità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 prendere in prestito capacità inutilizzata da 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 su RHEL 9. Collegatelo sempre come qdisc foglia sotto le classi HTB, altrimenti un singolo flusso avido può monopolizzare un'intera classe.

Configurazione di tc su un server Linux

tc viene fornito con il pacchetto iproute2. Su Debian e Ubuntu, installarlo con apt-get install iproute2. Su RHEL e derivati, yum install iproute. È necessario avere i privilegi di root o sudo.

Ottenere prima il nome corretto dell'interfaccia. Un nome errato dell'interfaccia è il motivo più comune per cui una configurazione non produce alcun risultato:

ip link show

Controlla cosa c'è già sull'interfaccia, compresi i contatori in tempo reale:

tc -s qdisc show dev eth0

Cancella 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 stai aggiornando una regola esistente invece di partire da zero, usa replace invece di add per uno swap 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+). BBR mantiene alto il throughput senza far crescere le code:

sysctl -w net.ipv4.tcp_congestion_control=bbr

Un'abitudine di sicurezza se si sta configurando un dispositivo remoto tramite SSH: aprire una seconda sessione e avere tc qdisc del dev eth0 root pronto per l'incollaggio. Una regola di filtro errata può bloccarti all'istante.

Modellare il traffico in uscita con HTB

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 di base. 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 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

Aggiungi 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 è 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

Modellare il traffico in entrata con IFB

Non è possibile modellare nativamente il traffico in entrata 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 di classe.

Caricare il modulo e attivare l'interfaccia:

modprobe ifb numifbs=1
ip link set dev ifb0 up

Aggiungere un qdisc in ingresso all'interfaccia fisica e reindirizzare tutto a 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 punto in poi, ifb0 si comporta come qualsiasi altra interfaccia. Applica il tuo albero HTB esattamente come faresti 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é cercare le porte in tutto il set di regole. Quando si abbina il DSCP in tc, sposta il valore a sinistra di 2 bit. 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
BusinessAF410x88HTTP, HTTPS, API
BulkCS10x20Backup, 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 userai costantemente:

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

Guarda il dropped e overlimits . I pacchetti persi indicano che la coda è satura; i superamenti dei limiti indicano che hai raggiunto il limite massimo della classe e che il kernel ha dovuto ritardare o eliminare 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 a uno stack di metriche. Abbinalo a ss -tin per vedere 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 si applicano ma il traffico non è limitatoInterfaccia errata, oppure TSO/GSO ancora attiviVerifica con ip link show, disabilitare gli offload con ethtool -K
Il filtro non trova mai corrispondenzeSintassi porta/IP errata o allineamento della mascheraAggiungere una contro-azione e controllare il conteggio degli accessi in tc -s filter show
Regole scomparse dopo il riavvioLa configurazione risiede solo in memoriaInserire in uno script e richiamare da systemd o da un dispatcher di NetworkManager
Elevata latenza sul traffico prioritarioNessun qdisc leaf, o burst troppo bassoCollegare fq_codel alle classi leaf, aumentare burst

Se mai dovessi bloccarti a causa di una configurazione errata, il ripristino è semplice:

tc qdisc del dev eth0 root

tc non puoi creare larghezza di banda che non hai, ma su un uplink ben dimensionato fa la differenza tra prestazioni prevedibili e un server che va in tilt nel momento in cui un utente avvia un trasferimento di grandi dimensioni. Se hai bisogno della larghezza di banda grezza e della libertà di modellarla come preferisci, dai un'occhiata ai server dedicati di FDC.

Blog

In primo piano questa settimana

Altri articoli
Controllo del traffico (tc) di Linux: una guida pratica

Controllo del traffico (tc) di Linux: una guida pratica

Controllare la larghezza di banda, assegnare priorità al traffico e modellare l'ingresso e l'uscita su Linux con tc. Configurazione di HTB, IFB, DSCP e fq_codel per server reali.

12 min di lettura - 5 giugno 2026

Perché è importante avere un VPS potente e senza contatore

7 min di lettura - 9 maggio 2025

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