Skip to main content
  1. Blog/

Cosa succede davvero sulla rete mentre il tuo codice gira

·4 mins
Alessio Barnini
Author
Alessio Barnini
Table of Contents

TL;DR
  • Prima di ogni richiesta HTTP il kernel fa un handshake in 3 pacchetti: SYN → SYN+ACK → ACK
  • I flag TCP ([S], [S.], [.], [P.], [R], [F]) si leggono tutti in tcpdump in tempo reale
  • RST = chiusura brusca (porta chiusa, firewall, crash) - molti RST consecutivi sono segnale sospetto
  • I log applicativi non vedono un SYN scan - serve tcpdump a livello di rete
$ history
  • tcpdump -i any -n 'host api.example.com'
  • tcpdump -i any -n 'tcp and port 443'
  • tcpdump 'tcp[tcpflags] & tcp-syn != 0'

Stai costruendo un'API. Il client manda una richiesta, il server risponde. Funziona. Ma cosa succede esattamente tra il momento in cui scrivi fetch("https://api.example.com/data") e quello in cui arriva la risposta?

Apri tcpdump e guarda:

sudo tcpdump -i any -n 'host api.example.com'
192.168.1.10 > 93.184.216.34.443: Flags [S]     # il tuo client
93.184.216.34.443 > 192.168.1.10: Flags [S.]    # il server risponde
192.168.1.10 > 93.184.216.34.443: Flags [.]     # connessione aperta
192.168.1.10 > 93.184.216.34.443: Flags [P.]    # qui partono i dati
93.184.216.34.443 > 192.168.1.10: Flags [.]     # server conferma ricezione

Tre pacchetti prima che un singolo byte di payload si muova. Questo è il TCP handshake.

Guida al TCP Handshake: Cosa vede tcpdump

Come funziona
#

TCP è un protocollo orientato alla connessione: prima di trasmettere dati, le due macchine negoziano. Questo garantisce che entrambi siano pronti e che i pacchetti arrivino nell'ordine corretto.

La negoziazione usa i flag TCP - bit nell'header del pacchetto che dichiarano l'intenzione di quel pacchetto:

FlagSimbolo tcpdumpSignificato
SYN[S]Voglio aprire una connessione
SYN+ACK[S.]Ok, sono pronto - e tu?
ACK[.]Ho ricevuto il tuo pacchetto
PSH[P.]Manda i dati subito, non aspettare il buffer
RST[R]Chiusura brusca - porta chiusa, firewall, o errore
FIN[F]Ho finito di mandare - chiudiamo in modo ordinato

Dal punto di vista del tuo codice, il handshake avviene dentro la syscall connect() - prima ancora che il tuo fetch() possa scrivere la prima riga HTTP.

Il three-way handshake
#

Client                        Server
  |                              |
  |  -------- [S] SYN ------->   |   "voglio connettermi"
  |                              |
  |  <------- [S.] SYN+ACK ----  |   "ok, sono pronto. e tu?"
  |                              |
  |  -------- [.] ACK ------->   |   "confermato, partiamo"
  |                              |
  |       CONNESSIONE APERTA     |
  |                              |
  |  -------- [P.] dati ------>  |   qui iniziano i dati veri
  |                              |
  |  <------- [.] ACK ---------- |   "ricevuto"

Il terzo pacchetto [.] è solo ACK - lunghezza zero, nessun dato. I dati viaggiano solo dopo che la connessione è stabilita.

Chiudere una connessione: FIN vs RST
#

Quando la comunicazione finisce ci sono due strade - e dal punto di vista della sicurezza sono molto diverse:

FIN - chiusura elegante:

Client           Server
  |  -- [F.] -->  |    "ho finito di mandare"
  |  <-- [.] ---  |    "ricevuto"
  |  <-- [F.] --  |    "anch'io ho finito"
  |  -- [.] --->  |    "ok, ciao"
  connessione chiusa correttamente

RST - chiusura brusca:

Server           Client
  |  -- [R] --->  |    connessione tagliata immediatamente

RST significa: porta chiusa, firewall che blocca, servizio che crasha, oppure qualcuno che sta facendo un port scan.

Molti FIN   → traffico normale, sessioni che chiudono correttamente
Molti RST   → segnale sospetto:
              - port scan in corso
              - servizio instabile che crasha
              - firewall che blocca connessioni
              - SYN flood in atto

Cosa vedi con tcpdump
#

Filtra per host o porta per non annegare nell'output:

# Tutto il traffico verso un host specifico
sudo tcpdump -i any -n 'host api.example.com'

# Solo TCP, porta 443 (HTTPS)
sudo tcpdump -i any -n 'tcp and port 443'

# Solo i pacchetti SYN - chi si sta connettendo
sudo tcpdump -i any -n 'tcp[tcpflags] & tcp-syn != 0'

Ogni riga corrisponde a un pacchetto. I flag sono dentro le parentesi quadre. L'ordine in cui appaiono è l'ordine reale in cui viaggiano sulla rete.

Il lato sicurezza: riconoscere un port scan
#

Un nmap -sS (SYN scan) produce un pattern riconoscibile in tcpdump:

14:30:45.000 IP 10.0.0.50 > 10.0.0.3.22:   Flags [S.]   → porta aperta
14:30:45.001 IP 10.0.0.50 > 10.0.0.3.23:   Flags [R.]   → porta chiusa
14:30:45.001 IP 10.0.0.50 > 10.0.0.3.80:   Flags [R.]   → porta chiusa
14:30:45.002 IP 10.0.0.50 > 10.0.0.3.443:  Flags [S.]   → porta aperta
14:30:45.002 IP 10.0.0.50 > 10.0.0.3.3306: Flags [R.]   → porta chiusa

Segnali: stesso IP verso molte porte in rapida sequenza, mix di [S.] e [R.] come risposta, nessun [.] di completamento.

La cosa importante: auth.log e i log SSH sono vuoti - il SYN scan non completa mai il handshake, quindi il servizio non registra nulla. tcpdump a livello di rete vede tutto. I log applicativi da soli non bastano.

exit 0
#

Il TCP handshake è il livello sotto il tuo codice - avviene prima che HTTP, TLS, o il tuo JSON si muovano di un millimetro. Capire i flag cambia come leggi gli errori di rete: un timeout è diverso da un RST, un FIN è diverso da un drop silenzioso.

La prossima volta che un'API non risponde, apri tcpdump. I flag raccontano esattamente cosa è successo.

Related