Introduzione
tcpdump
è un utility della riga di comando che è possibile utilizzare per acquisire e ispezionare il traffico di rete in entrata e in uscita dal sistema. È lo strumento più comunemente utilizzato dagli amministratori di rete per la risoluzione dei problemi di rete e i test di sicurezza.
Nonostante il nome, con tcpdump
, è anche possibile acquisire traffico non TCP come UDP, ARP o ICMP. I pacchetti acquisiti possono essere scritti in un file o in output standard. Una delle funzionalità più potenti del comando tcpdump
è la sua capacità di utilizzare i filtri e acquisire solo i dati che si desidera analizzare.
In questo articolo, tratteremo le basi su come usare il comando tcpdump
in Linux.
Se desideri installare Tcpdump su un server in remoto continua a leggere, altrimenti salta il primo paragrafo "Connessione al Server" e leggi il successivo.
Connessione al Server
Per accedere al server, è necessario conoscere l'indirizzo IP. Avrai anche bisogno dell'username e della password per l'autenticazione. Per connettersi al server come utente root digitare il seguente comando:
ssh root@IP_DEL_SERVER
Successivamente sarà necessario inserire la password dell'utente root.
Se non utilizzate l'utente root potete connettervi con un'altro nome utente utilizzando lo stesso comando, quindi modificare root con il vostro nome_utente:
ssh nome_utente@IP_DEL_SERVER
Successivamente vi verrà chiesto di inserire la password del vostro utente.
La porta standard per connettersi tramite ssh è la 22, se il vostro server utilizza una porta diversa, sarà necessario specificarla utilizzando il parametro -p, quindi digitare il seguente comando:
ssh nome_utente@IP_DEL_SERVER -p PORTA
Installare Tcpdump
tcpdump
è installato di default sulla maggior parte delle distribuzioni Linux e macOS. Per verificare se il comando tcpdump
è disponibile sul tipo di sistema in uso, utilizzare il seguente comando:
tcpdump --version
Se tcpdump
non è presente sul tuo sistema, il comando sopra stamperà "tcpdump: command not found". Puoi installarlo facilmente tcpdump
usando il gestore pacchetti della tua distribuzione.
Installare Tcpdump su Ubuntu e Debian
sudo apt update && sudo apt install tcpdump
Installare Tcpdump su CentOS e Fedora
sudo yum install tcpdump
Installare Tcpdump su Arch Linux
sudo pacman -S tcpdump
Quindi verificare la corretta installazione con il seguente comando:
tcpdump --version
L'output dovrebbe assomigliare a questo:
tcpdump version 4.9.3
libpcap version 1.8.1
OpenSSL 1.1.1d 10 Sep 2019
Acquisire i pacchetti con tcpdump
La sintassi generale per il comando tcpdump
è la seguente:
tcpdump [options] [expression]
- Il comando
options
consente di controllare il comportamento del comando. - Il filtro
expression
definisce quali pacchetti verranno acquisiti.
Il comando tcpdump
può essere eseguito solo da root o da utenti con privilegi sudo
. Se si tenta di eseguire il comando come utente non privilegiato, verrà visualizzato un messaggio di errore: "You don't have permission to capture on that device".
Il caso d'uso più semplice è invocare tcpdump
senza opzioni e filtri:
sudo tcpdump
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on eth0, link-type EN10MB (Ethernet), capture size 262144 bytes
21:28:50.627720 IP static.78.18.201.195.clients.your-server.de.ssh > 2-226-134-97.ip181.domain.it.65328: Flags [P.], seq 3036272519:3036272647, ack 288322885, win 1452, length 128
21:28:50.627782 IP static.78.18.201.195.clients.your-server.de.ssh > 2-226-134-97.ip181.domain.it.65328: Flags [P.], seq 128:192, ack 1, win 1452, length 64
21:28:50.627823 IP static.78.18.201.195.clients.your-server.de.ssh > 2-226-134-97.ip181.domain.it.65328: Flags [P.], seq 192:320, ack 1, win 1452, length 128
21:28:50.627863 IP static.78.18.201.195.clients.your-server.de.ssh > 2-226-134-97.ip181.domain.it.65328: Flags [P.], seq 320:384, ack 1, win 1452, length 64
...
29 packets captured
45 packets received by filter
10 packets dropped by kernel
tcpdump
continuerà a catturare i pacchetti e scrivere sull'output standard fino a quando non riceve un segnale di interruzione. Utilizzare la combinazione di tasti Ctrl+C
per inviare un segnale di interruzione e interrompere il comando.
Per un output più dettagliato, utilizzare l'opzione -v
o -vv
per un output ancora più dettagliato:
sudo tcpdump -vv
È possibile specificare il numero di pacchetti da acquisire utilizzando l'opzione -c
. Ad esempio, per acquisire solo dieci pacchetti, digitare:
sudo tcpdump -c 10
Dopo aver catturato i pacchetti, tcpdump
si fermerà.
Quando non viene specificata alcuna interfaccia, tcpdump
utilizza la prima interfaccia che trova e scarica tutti i pacchetti che attraversano tale interfaccia.
Utilizzare l'opzione -D
per stampare un elenco di tutte le interfacce di rete disponibili che tcpdump può raccogliere pacchetti da:
sudo tcpdump -D
Per ciascuna interfaccia, il comando stampa il nome dell'interfaccia, una breve descrizione e un indice (numero) associato:
1.eth0 [Up, Running]
2.any (Pseudo-device that captures on all interfaces) [Up, Running]
3.lo [Up, Running, Loopback]
4.nflog (Linux netfilter log (NFLOG) interface)
5.nfqueue (Linux netfilter queue (NFQUEUE) interface)
6.usbmon1 (USB bus number 1)
7.usbmon2 (USB bus number 2)
L'output sopra mostra che eth0
è la prima interfaccia trovata e utilizzata da tcpdump
quando non viene fornita alcuna interfaccia al comando. La seconda interfaccia any
è un dispositivo speciale che consente di acquisire tutte le interfacce attive.
Per specificare l'interfaccia su cui si desidera acquisire il traffico, richiamare il comando con l'opzione -i
seguita dal nome dell'interfaccia o dall'indice associato. Ad esempio, per acquisire tutti i pacchetti da tutte le interfacce, è necessario specificare l'interfaccia any
:
sudo tcpdump -i any
Per impostazione predefinita, tcpdump
esegue la risoluzione DNS inversa sugli indirizzi IP e traduce i numeri di porta in nomi. Utilizzare l'opzione -n
per disabilitare la traduzione:
sudo tcpdump -n
Saltare la ricerca DNS evita di generare traffico DNS e rende l'output più leggibile. Si consiglia di utilizzare questa opzione ogni volta che si invoca tcpdump
.
Invece di visualizzare l'output sullo schermo, è possibile reindirizzarlo a un file utilizzando gli operatori di reindirizzamento >
e >>
:
sudo tcpdump -n -i any > file.out
Puoi anche guardare i dati durante il salvataggio in un file usando il comando tee
:
sudo tcpdump -n -l | tee file.out
L'opzione -l
nel comando sopra permette a tcpdump
di rendere bufferizzata la linea di output. Quando questa opzione non viene utilizzata, l'output non verrà scritto sullo schermo quando viene generata una nuova riga.
Comprensione dell'output di tcpdump
tcpdump
genera informazioni per ciascun pacchetto acquisito su una nuova riga. Ogni riga include un timestamp e informazioni su quel pacchetto, a seconda del protocollo.
Il formato tipico di una riga del protocollo TCP è il seguente:
[Timestamp] [Protocol] [Src IP].[Src Port] > [Dst IP].[Dst Port]: [Flags], [Seq], [Ack], [Win Size], [Options], [Data Length]
Andiamo campo per campo e spieghiamo la seguente riga:
15:47:24.248737 IP 192.168.1.27.22 > 192.168.1.15.37445: Flags [P.], seq 201747193:201747301, ack 1226568763, win 402, options [nop,nop,TS val 1051794587 ecr 2679218230], length 108
15:47:24.248737
- Il timestamp del pacchetto acquisito è in ora locale e utilizza il seguente formato:,hours:minutes:seconds.frac
dovefrac
sono le frazioni di secondo dalla mezzanotte.IP
- Il protocollo del pacchetto. In questo caso, IP indica il protocollo Internet versione 4 (IPv4).192.168.1.27.22
- L'indirizzo IP e la porta di origine separati da un punto (.
).192.168.1.15.37445
- L'indirizzo IP e la porta di destinazione separati da un punto (.
).
Flags [P.]
- Campo Flag TCP. In questo esempio, [P.]
significa pacchetto Push Acknowledgement, utilizzato per riconoscere il pacchetto precedente e inviare dati. Altri valori tipici dei campi flag sono i seguenti:
- [.] - ACK (riconoscimento)
- [S] - SYN (Avvia connessione)
- [P] - PSH (Push Data)
- [F] - FIN (Termina connessione)
- [R] - RST (Reimposta connessione)
- [S.] - SYN-ACK (pacchetto SynAcK)
seq 201747193:201747301
- Il numero progressivo è nella notazionefirst:last
. Mostra il numero di dati contenuti nel pacchetto. Ad eccezione del primo pacchetto nel flusso di dati in cui questi numeri sono assoluti, tutti i pacchetti successivi utilizzano come posizioni di byte relative. In questo esempio, il numero è201747193:201747301
, nel senso che questo pacchetto contiene byte dal 201747193 al 201747301 del flusso di dati. Utilizzare l'opzione-S
per stampare numeri di sequenza assoluti.ack 1226568763
Il numero di riconoscimento è il numero progressivo dei dati successivi previsti dall'altra estremità di questa connessione.win 402
- Il numero della finestra è il numero di byte disponibili nel buffer di ricezione.options [nop,nop,TS val 1051794587 ecr 2679218230]
- Opzioni TCP.nop
oppure "no operation" viene utilizzato per rendere l'intestazione TCP multipla di 4 byte.TS val
è un timestamp TCP eecr
rappresenta una risposta echo. Visita la documentazione IANA per ulteriori informazioni sulle opzioni TCP.length 108
- La lunghezza dei dati del payload
Filtri tcpdump
Quando tcpdump
viene invocato senza filtri, acquisisce tutto il traffico e produce un'enorme quantità di output che rende molto difficile trovare e analizzare i pacchetti di interesse.
I filtri sono una delle funzionalità più potenti del comando tcpdump
. Consentono di catturare solo quei pacchetti che corrispondono all'espressione. Ad esempio, durante la risoluzione dei problemi relativi a un server Web è possibile utilizzare i filtri per ottenere solo il traffico HTTP.
tcpdump
utilizza la sintassi Berkeley Packet Filter (BPF) per filtrare i pacchetti acquisiti utilizzando vari parametri di lavorazione come protocolli, indirizzi IP di origine e destinazione e porte, ecc.
In questo articolo, daremo uno sguardo ad alcuni dei filtri più comuni. Per un elenco di tutti i filtri disponibili, consultare la manpage pcap-filter.
Filtro per protocollo
Per limitare l'acquisizione a un determinato protocollo, specificare il protocollo come filtro. Ad esempio, per acquisire solo il traffico UDP dovresti usare:
sudo tcpdump -n udp
Un altro modo per definire il protocollo è utilizzare il parametro proto
, seguito dal numero di protocollo. Il seguente comando filtrerà il protocollo numero 17 e produrrà lo stesso risultato di quello sopra:
sudo tcpdump -n proto 17
Per ulteriori informazioni sui numeri, consultare l'elenco dei numeri del protocollo IP.
Filtro per host
Per acquisire solo i pacchetti relativi a un host specifico utilizzare il parametro host
:
sudo tcpdump -n host 192.168.1.22
L'host può essere un indirizzo IP o un nome.
È inoltre possibile filtrare l'output su un determinato intervallo IP utilizzando il parametro net
. Ad esempio, per eseguire il dump dei soli pacchetti correlati 10.10.0.0/16
è necessario utilizzare:
sudo tcpdump -n net 10.10
Filtro per porta
Per limitare l'acquisizione solo ai pacchetti da o verso una porta specifica, utilizzare il parametro port
. Il comando seguente acquisisce i pacchetti relativi al servizio SSH (porta 22) usando questo comando:
sudo tcpdump -n port 22
Il parametro portrange
ti consente di acquisire il traffico in una serie di porte:
sudo tcpdump -n portrange 110-150
Filtro per origine e destinazione
È inoltre possibile filtrare i pacchetti in base alla porta di origine o di destinazione o host utilizzando i parametri src
, dst
, src and dst
e src or dst
.
Il seguente comando acquisisce i pacchetti provenienti dall'host con IP 192.168.1.22:
sudo tcpdump -n src host 192.168.1.22
Per trovare il traffico proveniente da qualsiasi sorgente verso la porta 80 dovrai usare:
sudo tcpdump -n dst port 80
Filtri complessi
I filtri possono essere combinati utilizzando gli operatori and
(&&
), or
(||
) e not
(!
).
Ad esempio, per acquisire tutto il traffico HTTP proveniente da un indirizzo IP di origine 192.168.1.22 dovrai usare questo comando:
sudo tcpdump -n src 192.168.1.22 and tcp port 80
Puoi anche usare le parentesi per raggruppare e creare filtri più complessi:
sudo tcpdump -n 'host 192.168.1.22 and (tcp port 80 or tcp port 443)'
Per evitare errori di analisi quando si utilizzano caratteri speciali, racchiudere i filtri tra virgolette singole.
Ecco un altro comando di esempio per acquisire tutto il traffico tranne SSH da un indirizzo IP di origine 192.168.1.22:
sudo tcpdump -n src 192.168.1.22 and not dst port 22
Ispezione dei pacchetti
Per impostazione predefinita tcpdump
, acquisisce solo le intestazioni dei pacchetti. Tuttavia, a volte potrebbe essere necessario ispezionare il contenuto dei pacchetti.
tcpdump
consente di stampare il contenuto dei pacchetti in ASCII e HEX.
L'opzione -A
consente all'utility tcpdump
di stampare ogni pacchetto in ASCII e -x
in HEX:
sudo tcpdump -n -A
Per mostrare il contenuto del pacchetto sia in HEX che in ASCII utilizzare l'opzione -X
:
sudo tcpdump -n -X
Lettura e scrittura di catture in un file
Un'altra utile caratteristica di tcpdump
è scrivere i pacchetti in un file. Ciò è utile quando si acquisiscono numerosi pacchetti o quando si desidera acquisire pacchetti per successive analisi.
Per iniziare a scrivere su un file, utilizzare l'opzione -w
seguita dal file di acquisizione dell'output:
sudo tcpdump -n -w data.pcap
Questo comando sopra salverà l'acquisizione in un file denominato data.pcap
. È possibile nominare il file come desiderato, ma è una convenzione comune utilizzare l'estensione .pcap
(packet capture).
Quando si utilizza l'opzione -w
, l'output non viene visualizzato sullo schermo. tcpdump
scrive pacchetti non elaborati e crea un file binario che non può essere letto con un normale editor di testo.
Per controllare il contenuto del file, invocare tcpdump
con l'opzione -r
:
sudo tcpdump -r data.pcap
Il file di acquisizione può anche essere ispezionato con altri strumenti di analisi dei pacchetti come Wireshark.
Quando si acquisiscono pacchetti per un lungo periodo di tempo, è possibile abilitare la rotazione dei file. tcpdump
consente di creare nuovi file o di ruotare il file di dump su un intervallo di tempo specificato o dimensioni fisse. Il seguente comando creare un file fino al raggiungimento di 200MB per poi crearne un altro fino a dieci, chiamati file.pcap0
, file.pcap1
e così via: prima di sovrascrivere i file più vecchi.
sudo tcpdump -n -W 10 -C 200 -w /tmp/file.pcap
Una volta generati dieci file, i file più vecchi verranno sovrascritti.
Si noti che è necessario eseguire tcpdump
solo durante la risoluzione dei problemi.
Se vuoi iniziare tcpdump
in un momento specifico, puoi usare un cronjob. tcpdump
non ha un'opzione per interrompersi dopo un determinato tempo. È possibile utilizzare il comando timeout
per interrompere tcpdump
dopo un periodo di tempo. Ad esempio, per uscire dopo 5 minuti dovresti usare:
sudo timeout 300 tcpdump -n -w data.pcap &
Il simbolo e commerciale (&
) alla fine del comando fa sì che il comando venga eseguito in background.
Conclusione
tcpdump
è uno strumento da riga di comando per l'analisi e la risoluzione dei problemi relativi alla rete.
Questo articolo ti ha mostrato le basi di tcpdump
dell'utilizzo e della sintassi. Per una documentazione più approfondita, visitare il sito Web tcpdump.