tcpdump è un analizzatore di pacchetti di rete open source che opera da riga di comando. Consente di intercettare, filtrare e ispezionare il traffico che transita su un’interfaccia di rete in tempo reale, oppure di salvarlo su file per un’analisi successiva.
Quando tcpdump viene avviato, pone l’interfaccia di rete selezionata in modalità promiscua (promiscuous mode): in questa modalità, la scheda di rete accetta e passa al sistema operativo tutti i frame che transitano sul segmento di rete, non solo quelli indirizzati al proprio MAC address. Il kernel cattura i pacchetti a livello del driver di rete e li trasferisce nello spazio utente tramite libpcap, dove tcpdump li elabora applicando eventuali filtri BPF (Berkeley Packet Filter).
Il BPF è il motore che gestisce i filtri e che rende tcpdump estremamente efficiente: i filtri vengono compilati e applicati direttamente nel kernel, riducendo drasticamente il numero di pacchetti copiati nello spazio utente e minimizzando l’impatto sulle prestazioni del sistema.
Per cosa si usa tcpdump
tcpdump è uno strumento trasversale, utilizzato in contesti molto diversi tra loro.
- Troubleshooting di rete
- Sicurezza informatica e analisi forense
- Debug di applicazioni
- Verifica di configurazioni firewall e routing
- Generazione di file PCAP
La sua utilità nasce da una proprietà fondamentale: mostra il traffico di rete così com’è, senza filtri applicativi, senza astrazioni, senza interpretazioni. Quello che transita sull’interfaccia è quello che si vede. Questa trasparenza lo rende prezioso ogni volta che si vuole capire cosa sta succedendo davvero, non cosa dovrebbe succedere secondo la configurazione.
Sintassi del comando
tcpdump [opzioni] [filtro BPF]Le opzioni controllano il comportamento del programma (interfaccia, output, formato), mentre il filtro BPF è l’espressione che definisce quali pacchetti catturare.
| Opzione | Descrizione |
|---|---|
| -i <iface> | Specifica l’interfaccia di rete (es. eth0, any) |
| -n | Non risolve gli indirizzi IP in nomi host |
| -nn | Non risolvere né IP né numeri di porta in nomi |
| -v, -vv, -vvv | Aumenta il livello di verbosità dell’output |
| -c <n> | Cattura esattamente n pacchetti, poi termina |
| -w <file> | Scrive i pacchetti su file .pcap |
| -r <file> | Legge pacchetti da un file .pcap |
| -s <snaplen> | Imposta la dimensione massima di cattura per pacchetto (default: 262144 byte) |
| -A | Mostra il payload in formato ASCII |
| -X | Mostra il payload in formato HEX e ASCII |
| -e | Mostra gli header Ethernet (Layer 2) |
| -q | Output sintetico (quiet mode) |
| -l | Modalità line-buffered, utile per fare pipe verso altri comandi |
Il filtro BPF (Berkeley Packet Filter) non è un semplice parametro di configurazione ma è un linguaggio per creare filtri compilati in bytecode ed eseguiti direttamente nel kernel, prima che i pacchetti raggiungano lo spazio utente. Questo significa che i pacchetti che non corrispondono al filtro vengono scartati a livello kernel (non vengono mai copiati, non consumano banda di CPU, non appaiono nell’output). Il risultato pratico è che è possibile catturare selettivamente il traffico rilevante anche su interfacce con volumi di traffico molto elevati, senza impattare le prestazioni del sistema.
Un’espressione BPF si costruisce combinando primitive e operatori logici:
- Primitive di protocollo: tcp, udp, icmp, ip, ip6, arp – selezionano i pacchetti in base al protocollo di trasporto o di rete
- Primitive di indirizzo: host 192.168.1.1, src host 10.0.0.5, dst host 8.8.8.8 – selezionano per IP sorgente o destinazione
- Primitive di porta: port 443, src port 1024, portrange 8080-8090 – selezionano per numero di porta
- Primitive di rete: net 10.0.0.0/24, src net 192.168.0.0/16 – selezionano per subnet
- Primitive di Layer 2: ether host aa:bb:cc:dd:ee:ff – selezionano per MAC address
Le primitive si combinano con gli operatori logici and, or e not (o equivalentemente &&, ||, !) per costruire espressioni arbitrariamente complesse. Quando il filtro contiene spazi o caratteri speciali come le parentesi, è buona pratica racchiuderlo tra virgolette per evitare che la shell lo interpreti prima di passarlo a tcpdump.
Esempi di utilizzo
Vediamo alcuni esempi pratici di utilizzo di tcpdump
Cattura base su un’interfaccia
# Cattura tutto il traffico sull'interfaccia eth0
sudo tcpdump -i eth0
# Cattura su qualsiasi interfaccia disponibile
sudo tcpdump -i anyIl punto di partenza per qualsiasi sessione di analisi: avviare tcpdump su un’interfaccia specifica per vedere tutto il traffico che transita in quel momento. L’opzione -i any è particolarmente comoda quando non si sa su quale interfaccia stia transitando il traffico di interesse.
Cattura per host
# Mostra solo il traffico da/verso un IP specifico
sudo tcpdump -i eth0 host 192.168.1.100
# Solo il traffico in uscita verso un IP
sudo tcpdump -i eth0 dst host 8.8.8.8
# Solo il traffico in entrata da un IP
sudo tcpdump -i eth0 src host 10.0.0.5Uno degli utilizzi più frequenti di tcpdump è isolare il traffico relativo a un singolo indirizzo IP. Specificando la direzione (src o dst) è possibile restringere ulteriormente la cattura, distinguendo le richieste in uscita dalle risposte in arrivo.
Cattura per porta e protocollo
# Traffico sulla porta 80 (HTTP)
sudo tcpdump -i eth0 port 80
# Traffico DNS (UDP porta 53)
sudo tcpdump -i eth0 udp port 53
# Traffico HTTPS
sudo tcpdump -i eth0 tcp port 443
# Traffico su un range di porte
sudo tcpdump -i eth0 portrange 8080-8090Quando il traffico di interesse è legato a un servizio specifico, filtrare per porta è il modo più diretto per isolare ciò che serve. Specificare anche il protocollo di trasporto (tcp o udp) riduce ulteriormente il rumore: una query DNS viaggia su UDP porta 53, e filtrare solo port 53 cattura entrambe le varianti. Il filtro portrange è utile in scenari dove un’applicazione usa un blocco di porte dinamiche, come i backend in un cluster di microservizi.
Cattura per protocollo di rete
# Solo pacchetti ICMP (es. ping)
sudo tcpdump -i eth0 icmp
# Solo traffico TCP
sudo tcpdump -i eth0 tcp
# Solo traffico UDP
sudo tcpdump -i eth0 udpAlcune analisi richiedono di osservare il traffico a livello di protocollo anziché di porta. Il caso più comune è l’ICMP: monitorarlo permette di verificare la raggiungibilità degli host, rilevare risposte di errore (destination unreachable, time exceeded) o individuare attività di discovery non autorizzate. Filtrare per TCP o UDP puro è utile quando si vuole una visione d’insieme di tutto il traffico di un certo tipo senza entrare nel dettaglio delle singole applicazioni.
Combinare filtri con operatori logici
# Traffico HTTP da un IP specifico
sudo tcpdump -i eth0 host 192.168.1.100 and port 80
# Traffico verso 8.8.8.8 o 8.8.4.4
sudo tcpdump -i eth0 dst host 8.8.8.8 or dst host 8.8.4.4
# Tutto il traffico TRANNE SSH
sudo tcpdump -i eth0 not port 22Gli operatori and, or e not permettono di creare espressioni arbitrariamente complesse. Escludere il traffico SSH con not port 22, ad esempio, è una pratica comune per evitare che la sessione remota inquini la cattura.
Ispezione del payload
# Mostra il contenuto dei pacchetti HTTP in ASCII
sudo tcpdump -i eth0 -A port 80
# Mostra il payload in HEX e ASCII (utile per protocolli binari)
sudo tcpdump -i eth0 -X port 5432L’opzione -A è sufficiente per traffico testuale, mentre -X aggiunge la rappresentazione esadecimale affiancata all’ASCII, indispensabile per protocolli binari.
Salvataggio e lettura di file PCAP
# Salva la cattura su file
sudo tcpdump -i eth0 -w /tmp/cattura.pcap
# Limita a 1000 pacchetti e salva
sudo tcpdump -i eth0 -c 1000 -w /tmp/cattura.pcap
# Legge e analizza un file PCAP esistente
sudo tcpdump -r /tmp/cattura.pcap
# Legge un PCAP applicando un filtro
sudo tcpdump -r /tmp/cattura.pcap port 443La cattura in tempo reale è utile per analisi immediate, ma il flusso di lavoro più solido prevede di salvare il traffico su file per analizzarlo successivamente, specialmente quando si diagnostica un problema intermittente o si raccolgono evidenze per un’analisi forense. Il formato .pcap è lo standard compatibile con Wireshark e con l’intero ecosistema di analisi del traffico di rete. L’opzione -r permette poi di applicare filtri BPF a una cattura già salvata, senza doverla ripetere: è possibile catturare tutto il traffico di un’interfaccia per un certo periodo e filtrarlo in un secondo momento, quando il problema da analizzare è già noto.
Rotazione automatica dei file di cattura
# Crea un nuovo file ogni 60 secondi
sudo tcpdump -i eth0 -G 60 -w /tmp/cattura_%Y%m%d_%H%M%S.pcapL’opzione -G abilita la rotazione facendo si che tcpdump crei automaticamente un nuovo file ogni intervallo definito. L’uso di variabili di data nel nome del file garantisce unicità e ordinamento cronologico.
Analisi del traffico DNS in tempo reale
# Mostra tutte le query e risposte DNS con dettaglio
sudo tcpdump -i eth0 -nn -vv udp port 53Il traffico DNS è tra i primi da esaminare in molti scenari di troubleshooting e sicurezza. Latenze elevate nelle risoluzioni, query verso resolver non autorizzati, risposte con TTL anomali, domini inesistenti che vengono interrogati ripetutamente sono tutti segnali visibili nel traffico DNS che difficilmente emergono dai soli log applicativi. L’opzione -vv mostra il contenuto esteso delle risposte, inclusi i record restituiti, il TTL e i flag del protocollo. L’opzione -nn evita che tcpdump provi a risolvere ulteriormente gli indirizzi IP nelle risposte, mantenendo l’output leggibile.
Rilevare tentativi di connessione su più porte (port scan)
# Mostra tutti i pacchetti TCP SYN (inizio connessione)
sudo tcpdump -i eth0 "tcp[tcpflags] & tcp-syn != 0"Filtrare i pacchetti con il flag SYN attivo permette di identificare tentativi di apertura di nuove connessioni TCP: una sequenza rapida di SYN verso porte diverse dallo stesso sorgente è il segnale caratteristico di un port scan.
Cattura con filtro su subnet
# Tutto il traffico verso la subnet 10.0.0.0/24
sudo tcpdump -i eth0 net 10.0.0.0/24
# Traffico tra due subnet
sudo tcpdump -i eth0 src net 10.0.0.0/24 and dst net 192.168.1.0/24In ambienti con più segmenti di rete o VLAN, filtrare per subnet permette di osservare i flussi tra segmenti senza catturare tutto il traffico dell’interfaccia. È utile per verificare che i flussi inter-VLAN passino attraverso i gateway previsti, che non ci siano comunicazioni dirette tra segmenti che dovrebbero essere isolati, o per isolare il traffico generato da un intero segmento durante un’analisi di sicurezza.
Pipeline con altri strumenti
# Cattura 500 pacchetti e mostra i top IP sorgente per frequenza
sudo tcpdump -i eth0 -nn -c 500 | awk '{print $3}' | sort | uniq -c | sort -rn | headtcpdump può essere combinato con strumenti Unix standard o con applicazioni remote per costruire pipeline di analisi potenti. L’opzione -l abilita il line buffering, necessario perché l’output sia disponibile in tempo reale quando viene inviato a un altro processo: senza di essa, l’output verrebbe bufferizzato e i risultati arriverebbero a blocchi.
Filtro per MAC address
# Cattura tutto il traffico da/verso un MAC address specifico
sudo tcpdump -i eth0 ether host aa:bb:cc:dd:ee:ff
# Solo i frame originati da un determinato MAC
sudo tcpdump -i eth0 ether src aa:bb:cc:dd:ee:ffIl filtro per MAC address opera su Layer 2 ed è utile in scenari specifici: identificare il traffico generato da un dispositivo di cui si conosce l’indirizzo fisico ma non l’IP, rilevare la presenza di indirizzi MAC non autorizzati su un segmento o verificare il comportamento di uno specifico dispositivo embedded o IoT che non espone log propri. A differenza del filtro per IP, il MAC address non cambia con il rinnovo del lease DHCP, rendendolo un identificatore stabile per tutta la durata dell’analisi.
Monitoraggio richieste HTTP con metodo e URL
# Estrae in tempo reale metodo HTTP e path dalle richieste
sudo tcpdump -i eth0 -nn -A -s 0 -l port 80 | grep --line-buffered -E "(GET|POST|PUT|DELETE|HEAD|OPTIONS) /"
# Mostra anche l'header Host per vedere il virtual host coinvolto
sudo tcpdump -i eth0 -nn -A -s 0 -l port 80 | grep --line-buffered -E "(GET|POST|PUT|DELETE|Host:)"In ambienti dove il traffico HTTP non è cifrato tcpdump consente di estrarre in tempo reale i metodi e gli URL delle richieste direttamente dal payload dei pacchetti, senza dover configurare un proxy o modificare l’applicazione. L’opzione -s 0 cattura il pacchetto intero senza troncare il payload, necessario per leggere le intestazioni HTTP complete. Il filtro con grep sull’output in ASCII permette di isolare solo le righe rilevanti, rendendo leggibile un flusso che altrimenti includerebbe anche il corpo delle risposte.
Due flag sono essenziali per ricevere output in tempo reale anziché a blocchi: -l su tcpdump abilita il line buffering verso la pipe, e –line-buffered su grep forza il flush riga per riga anziché ogni 4KB. Senza di essi il comando funziona, ma l’output appare solo quando i buffer si riempiono. Questi comandi catturano solo traffico HTTP non cifrato su porta 80, non mostrano nulla se il server usa HTTPS o se non ci sono richieste attive.
Verifica del three-way handshake TCP
# Mostra solo i pacchetti SYN (inizio handshake)
sudo tcpdump -i eth0 "tcp[tcpflags] == tcp-syn"
# Mostra solo i pacchetti SYN-ACK (risposta del server)
sudo tcpdump -i eth0 "tcp[tcpflags] == tcp-syn|tcp-ack"
# Mostra solo i RST (connessioni rifiutate o interrotte bruscamente)
sudo tcpdump -i eth0 "tcp[tcpflags] & tcp-rst !=0"
# Visualizza l'intero handshake verso una porta specifica
sudo tcpdump -i eth0 -nn "tcp port 443 and (tcp[tcpflags] & (tcp-syn|tcp-ack|tcp-rst) != 0)"Osservare i flag TCP permette di analizzare con precisione lo stato delle connessioni e identificare anomalie nel loro ciclo di vita. Il three-way handshake (SYN → SYN-ACK → ACK) è il punto di partenza di ogni connessione TCP: un SYN senza risposta indica che il server non è in ascolto sulla porta o che un firewall sta bloccando silenziosamente il traffico mentre un RST in risposta al SYN indica invece un rifiuto esplicito da parte dell’host di destinazione. Monitorare questi flag è essenziale durante il troubleshooting delle connessioni e per rilevare comportamenti anomali come port scan o sessioni terminate bruscamente in modo inatteso.
tcpdump vs Wireshark
tcpdump e Wireshark non sono strumenti in competizione, ma complementari.
tcpdump è lo strumento ideale ogni volta che si opera in ambienti raggiungibili solo via SSH, macchine senza interfaccia grafica, container o sistemi embedded. La sua natura a riga di comando lo rende perfettamente integrabile in script di automazione e pipeline di monitoraggio. Il motore BPF consente di definire filtri precisi direttamente al momento della cattura, limitando il volume di dati raccolti e l’impatto sulle risorse del sistema.
Wireshark eccelle invece nell’analisi offline e visuale: interfaccia grafica interattiva, decodifica automatica di centinaia di protocolli applicativi, grafici di flusso, statistiche aggregate e un linguaggio di display filter molto più espressivo rispetto al BPF.
La strategia più efficace in molti casi è combinare i due strumenti: usare tcpdump per catturare il traffico direttamente sul server, salvare il risultato in un file .pcap e poi trasferirlo in locale per analizzarlo con Wireshark.