Perché registrare il traffico di un hotspot?

Perché dietro il NAT tutti gli ospiti hanno lo stesso indirizzo pubblico. Se un giorno arriva una richiesta dell’autorità su un certo indirizzo a una certa ora, senza un registro non c’è modo di risalire al dispositivo. Il registro serve a collegare ora, indirizzo privato, MAC e destinazione.

⚠️ Attenzione: il registro contiene dati personali. Quali dati tenere, per quanto tempo e come proteggerli dipende dagli obblighi del gestore: va deciso con un consulente, non con un howto.

Nell’esempio la rete degli ospiti è 172.16.0.0/22 sul bridge bridge-hs, come nell’howto su come creare un hotspot WiFi con MikroTik. Sostituisci rete e nomi con i tuoi.

Schema: ospiti dell'hotspot, router MikroTik che registra le connessioni e invia syslog e IPFIX al server di log 10.6.0.50
Ogni connessione nuova degli ospiti finisce nel log, con l’ora giusta, e il router la manda a un server esterno.

Passo 1: il router ha l’ora giusta?

Un registro con l’ora sbagliata vale quanto un registro vuoto: la richiesta dice “alle 21:14”, e tu devi trovare proprio quella riga. Prima di tutto, quindi, l’orologio:

/system ntp client set enabled=yes
/system ntp client servers add address=pool.ntp.org
/system clock set time-zone-name=Europe/Rome

Controlla che il client NTP sia sincronizzato:

/system ntp client print

Passo 2: come registro le connessioni?

Con una regola nella chain forward che registra solo il primo pacchetto di ogni connessione, non tutti i pacchetti: altrimenti il log esplode.

/ip firewall filter add chain=forward src-address=172.16.0.0/22 connection-state=new \
    action=log log-prefix="HS" comment="Log connessioni hotspot" place-before=0

action=log scrive la riga e lascia proseguire il pacchetto alle regole successive: non blocca niente. place-before=0 la mette in cima, prima delle regole che accettano il traffico in forward.

Una riga reale, presa dal mio laboratorio:

firewall,info HS forward: in:bridge-lan out:ether5, connection-state:new src-mac 50:00:00:1E:00:00, proto TCP (SYN), 192.168.88.199:44928->104.20.21.8:80, len 60

Ci sono tutti gli elementi: interfacce, MAC del client, protocollo, indirizzo e porta di origine, indirizzo e porta di destinazione. Data e ora le aggiunge il sistema di log.

Passo 3: dove salvo il log?

Non nella memoria del router: si cancella a ogni riavvio e tiene poche migliaia di righe. Il posto giusto è un server syslog esterno. Nell’esempio è 10.6.0.50, un server nella rete del mio laboratorio: metti l’indirizzo del tuo server syslog.

/system logging action add name=sysloghs target=remote remote=10.6.0.50 remote-port=514
/system logging add topics=firewall action=sysloghs
/system logging add topics=hotspot,info action=sysloghs

⚠️ Attenzione: in RouterOS 7 il nome dell’azione può contenere solo lettere e numeri. Con name=syslog-hs il router risponde action name can contain only letters and numbers.

La seconda regola manda al syslog anche gli eventi dell’hotspot, cioè login e logout degli utenti, che servono per collegare un indirizzo privato a un utente in un certo momento. Sul server, in laboratorio, sono arrivate righe come queste:

hotspot,account,info,debug test (192.168.88.199): logged in
firewall,info HS forward: in:bridge-lan out:ether5, connection-state:new src-mac 50:00:00:1E:00:00, proto TCP (SYN), 192.168.88.199:44928->104.20.21.8:80, len 60

Sul server syslog tieni un archivio ruotato e protetto. Topics, azioni ed esempi sono tutti nel manuale MikroTik: Log.

Passo 4: come verifico che funzioni?

Collega un dispositivo all’hotspot, fai il login e apri un sito. Sul router:

/log print where message~"HS "
/system logging print where action=sysloghs

Il primo comando ti mostra le righe del firewall, il secondo che le regole verso il syslog ci sono. Poi controlla che le stesse righe arrivino davvero al server: un syslog configurato ma irraggiungibile non ti avvisa di niente.

Passo 5: e Traffic Flow?

Il log del firewall scrive una riga di testo per ogni connessione nuova. Traffic Flow fa un lavoro diverso: il router riassume il traffico in flussi (chi ha parlato con chi, con quale protocollo e quali porte, quanti pacchetti e quanti byte) e li spedisce a un server, il collettore, in un formato standard: NetFlow v9 o IPFIX. Sono pacchetti UDP, compatti, pensati per essere conservati e interrogati, non per essere letti a occhio.

C’è un motivo in più per sceglierlo in un hotspot. In IPFIX, di serie, RouterOS esporta anche indirizzo e porta dopo il NAT (nat-src-address e nat-src-port). La richiesta dell’autorità parte proprio da lì: “l’indirizzo pubblico X, porta Y, alle 21:14”. Con l’IPFIX ogni flusso contiene insieme indirizzo privato, MAC del dispositivo e indirizzo e porta pubblici: la strada per tornare al dispositivo è già tracciata, senza incrociare tabelle a mano.

Lato router

/ip traffic-flow set enabled=yes interfaces=bridge-hs
/ip traffic-flow target add dst-address=10.6.0.50 port=2055 version=ipfix

interfaces=bridge-hs limita la raccolta al traffico degli ospiti; 10.6.0.50 è il collettore, metti l’indirizzo del tuo. Il router manda i flussi chiusi: una connessione ferma da 15 secondi (inactive-flow-timeout) o aperta da più di 30 minuti (active-flow-timeout) parte verso il collettore. Puoi controllare i campi esportati così:

/ip traffic-flow ipfix print

Lato server: nfdump

Come collettore uso nfdump, open source e nei pacchetti ufficiali di Debian e Ubuntu (github.com/phaag/nfdump). Due programmi: nfcapd riceve i flussi e li salva su disco, nfdump li interroga. Su un Debian 12:

apt install nfdump

Il pacchetto avvia da solo nfcapd in ascolto sulla porta UDP 2055, con i dati in /var/cache/nfdump: un file nuovo ogni 5 minuti. Non c’è altro da configurare. Se il server ha un firewall, apri la porta 2055 in UDP solo per l’indirizzo del router.

Per quanto tempo tenerli lo decide il gestore, non nfdump (vedi l’avviso in cima). Una volta deciso, per esempio 180 giorni, la pulizia la fa nfexpire, da mettere in un cron giornaliero:

nfexpire -e /var/cache/nfdump -t 180d

Cosa riceve il collettore

Nel mio laboratorio ho collegato un PC Linux dietro un CHR con il NAT e ho aperto due siti. Il PC ha l’indirizzo privato 192.168.72.254, il router esce verso “Internet” con 192.168.250.72. Dopo qualche secondo il collettore aveva questi flussi:

nfdump -R /var/cache/nfdump -o 'fmt:%ts %pr %sap -> %dap  NAT %nsap  %ismc %byt' 'proto tcp'

Date first seen         Proto      Src IP Addr:Port          Dst IP Addr:Port          X-Src IP Addr:Port     In src MAC Addr    Bytes
2026-10-09 13:37:22.592 TCP     192.168.72.254:50820 ->    104.20.23.154:80     NAT   192.168.250.72:50820  50:00:00:1f:00:00      447
2026-10-09 13:37:22.632 TCP      104.20.23.154:80    ->   192.168.250.72:50820  NAT    104.20.23.154:80     50:00:00:1a:00:01     1204
2026-10-09 13:37:22.832 TCP     192.168.72.254:37542 ->   130.255.112.53:443    NAT   192.168.250.72:37542  50:00:00:1f:00:00     2101
2026-10-09 13:37:22.872 TCP     130.255.112.53:443   ->   192.168.250.72:37542  NAT   130.255.112.53:443    50:00:00:1a:00:01    75334

Ogni connessione produce due flussi, uno per direzione. Leggi la terza riga, quella in uscita verso 130.255.112.53:443:

  • Src IP Addr:Port: il dispositivo, con il suo indirizzo privato e la porta, 192.168.72.254:37542;
  • X-Src IP Addr:Port: come l’ha visto Internet dopo il NAT, 192.168.250.72:37542. Nell’hotspot vero qui c’è l’indirizzo pubblico;
  • In src MAC Addr: il MAC del dispositivo, 50:00:00:1f:00:00;
  • Bytes: quanto ha mandato. La risposta del sito, nella quarta riga, pesa 75 KB.

La ricerca che serve davvero

Arriva la richiesta: “indirizzo pubblico 192.168.250.72, porta 37542”. Una sola riga di comando:

TZ=Europe/Rome nfdump -R /var/cache/nfdump -q -o 'fmt:%ts %pr %sap -> %dap %nsap %ismc' \
    'proto tcp and src xip 192.168.250.72 and src xport 37542'

2026-10-09 15:37:22.832 TCP     192.168.72.254:37542 ->   130.255.112.53:443     192.168.250.72:37542 50:00:00:1f:00:00

Ecco l’orario, l’indirizzo privato e il MAC del dispositivo. Con il login dell’hotspot di quell’ora (Passo 6) hai anche il nome dell’utente. Su un archivio grande aggiungi -t con l’intervallo di tempo della richiesta, così nfdump legge solo i file di quei minuti.

⚠️ Attenzione al fuso orario. Il router manda gli orari in modo assoluto, nfdump li mostra nel fuso del server. Il mio server di laboratorio è in UTC: senza TZ=Europe/Rome la stessa connessione compare alle 13:37 invece che alle 15:37. Con una richiesta “alle 21:14” due ore di differenza fanno trovare il dispositivo sbagliato.

nfdump non è l’unico: anche GoFlow2 e pmacct sono collettori open source che leggono l’IPFIX. Io l’ho provato con nfdump. Dettagli e campi lato MikroTik nel manuale MikroTik: Traffic Flow.

Passo 6: come collego l’IP a un utente?

Il log del firewall contiene l’indirizzo privato e il MAC; il nome dell’utente sta nel log dell’hotspot, alla riga del login. Incrociarli a mano è faticoso: c’è un howto dedicato a scrivere il nome utente in ogni riga di log.

Passo 7: cosa controllo prima di metterlo in produzione?

Un router che conserva i dati di navigazione degli ospiti deve essere il primo a essere protetto. Se non l’hai ancora fatto, segui l’Hardening di base di un router MikroTik.

Provato in laboratorio su PNETLab con CHR RouterOS 7.24.5 (stable), un hotspot e un client Linux: regola di log, invio a un server syslog remoto (righe del firewall e login hotspot ricevute), client NTP. Traffic Flow in IPFIX provato su un secondo CHR 7.24.5 con il NAT, verso nfdump 1.7.1 su Debian 12: flussi ricevuti con indirizzo e porta dopo il NAT e MAC del client, ricerca per indirizzo e porta pubblici.

Domande frequenti

Come si registrano le connessioni degli utenti di un hotspot MikroTik?

Con una regola di firewall in chain forward, connection-state=new e action=log, limitata alla rete dell’hotspot: registra il primo pacchetto di ogni connessione con indirizzi, porte e MAC del client.

Perché il log va mandato su un server syslog?

Perché il log in memoria del MikroTik è limitato e si perde al riavvio. Un server syslog esterno conserva le righe nel tempo e permette di archiviarle e cercarle.

Perché il router rifiuta il nome dell’azione di logging?

In RouterOS 7 il nome di un’azione di /system logging action può contenere solo lettere e numeri: syslog-hs viene rifiutato, sysloghs va bene.

Che differenza c’è fra log del firewall e Traffic Flow?

Il log del firewall scrive una riga di testo per ogni nuova connessione; Traffic Flow esporta i flussi in formato NetFlow o IPFIX, con byte, durata e, in IPFIX, anche indirizzo e porta dopo il NAT, verso un collettore dedicato.

Che server uso per ricevere il Traffic Flow di un MikroTik?

Un collettore NetFlow/IPFIX. Uno open source è nfdump: su Debian si installa con apt install nfdump e riceve già sulla porta UDP 2055. Con nfdump si cerca un flusso anche per indirizzo e porta dopo il NAT (src xip, src xport).

Il log rallenta il router?

Registrare solo le connessioni nuove, e non tutti i pacchetti, pesa poco. Con molti utenti conviene comunque mandare il log a un server esterno e non tenerlo in memoria.

Questo howto aggiorna a RouterOS 7 un articolo del 2016 sul mio vecchio blog wirelessguru.it, ormai offline.