Passa ai contenuti principali

Monitoraggio e gestione di base delle comunicazioni di rete in Linux

È noto che un indirizzo IP identifica un dispositivo di rete, ad esempio una scheda ethernet o wireless, di un computer. Ma, poiché attraverso lo stesso dispositivo di rete, nel medesimo istante, passano normalmente più comunicazioni verso altrettanti dispositivi di rete di altrettanti computer (sulla stessa scheda ethernet di un pc potrebbero ad esempio transitare simultaneamente i dati di una connessione internet, quelli  di una connessione peer-to-peer ed ancora quelli di una rasmissione FTP), qual è il meccanismo che consente ad un computer di distinguere fra i differenti flussi? In questo articolo si cercherà di indagare sulle comunicazioni in una rete di computer, assumendo Linux come ambiente di riferimento ed illustrando gli strumenti che il sistema operativo mette a disposizione dell'utente sia per l'analisi, sia per la gestione del traffico di rete .


Fondamenti della comunicazione via rete

Cerchiamo quindi innanzitutto di chiarire, anche ad alto livello, quel che avviene durante una comunicazione fra due (o più) computer in rete. Compito di un qualunque sistema operativo è quello di gestire l'accesso alle risorse della macchina da parte di più processi. Per "processo" è bene ricordarlo, si intende l'istanza di un certo programma in esecuzione (utilizzando ad esempio Firefox per navigare in Internet, sarà possibile notare ($ ps -e) uno o più processi relativi allo stesso browser). In particolare nel caso di processi che richiedano una comunicazione fra computer in rete, il kernel Linux (mediante i driver contenuti all'interno dei propri moduli) regola l'accesso di questi stessi processi ai dispositivi di rete disponibili sulla macchina organizzandone l'invio e la ricezione ordinata di dati da e verso il computer.

Si ricordi infine che, nell'ambito di una comunicazione di rete, un processo viene definito client o server a seconda che il computer su cui questo è attivo sia l'utilizzatore o il fornitore del servizio implementato dal processo stesso.

Può allora avvenire che sulla mia macchina il processo client P_Cli_1, istanza dell'applicazione Firefox, instauri una comunicazione col processo server P_Svr_1 relativo all'applicativo Apache che sta girando su una macchina remota dove risiedono le pagine del sito che sto consultando. La comunicazione fra i due processi P_Cli_1 e P_Srv_1 avverrà allora attraverso lo scambio di pacchetti che, uscendo dal dispositivo di rete di un computer e attraversando una rete raggiungono il device di rete dell'altro computer e viceversa. Ovviamente la comunicazione fra le due macchine, per essere efficace, dovrà avvenire nel rispetto di un prestabilito protocollo di trasmissione (che nel nostro esempio potrebbe essere HTTP o HTTPS).

È tuttavia possibile, anzi probabile, che anche altri utenti in altri punti della rete stiano consultando nel medesimo istante lo stesso mio sito. Questo significa che, allo stesso tempo t, esisteranno, oltre P_Cli_1, altri processi client (browser) P_Cli_2...P_Cli_n (sulle macchine di altrettanti utenti) che hanno instaurato una comunicazione con altrettanti nuovi processi server (Apache) P_Svr_2...P_Svr_n residenti sullo stesso computer che ospita il sito. Ovviamente lo scenario si potrebbe complicare ulteriormente: gli utenti potrebbero essere connessi in differente misura anche ad altri servizi, così come una macchina che ospita processi client relativamente ad un certo servizio potrebbe ospitare processi server per altri servizi, etc.

Concentrando in definitiva l'attenzione su un dispositivo di rete di un certo computer, quel che potrebbe osservarsi è che, nel medesimo istante, transitano qui pacchetti appartenenti a comunicazioni diverse, quindi: relativi a processi client e/o server distinti; in ingresso e/o in uscita; provenienti o destinati da/a indirizzi IP differenti; con protocolli di trasmissione che possono differire. Come avviene tutto ciò?

La soluzione al problema della condivisione dello stesso mezzo fra più comunicazioni di rete venne inizialmente proposto da Unix e successivamente adottata universalmente da tutti gli altri sistemi operativi e prevede l'uso di "porte". Si tratta di un'astrazione per la quale flussi di dati distinti che attraversano lo stesso device di rete vengono identificati da porte diverse. Pensando ad esempio ad un PC sulla cui scheda ethernet stiano transitando i pacchetti di tre trasmissioni diverse (si immagini ad esempio tre trasmissioni di tipo HTTP, SSH e FTP) il Kernel assocerà una porta differente a ciascuno dei tre flussi di dati. Di fatto i pacchetti di ciascuna delle tre comunicazioni verranno marchiati (taggati) con l'id della porta corrispondente. Questo consentirà di tenere distinti i tre flussi di dati.

Per convenzione le porte vengono indicate con un numero intero compreso tra 0 e 65535. L’Internet Assigned Numbers Authority (IANA) ha inoltre stabilito di suddividere questo insieme in tre gruppi distinti in funzione del loro utilizzo:

  • Well Known Ports:
(Porte 0 – 1023, vd. anche tabella seguente). Sono porte riservate esclusivamente a processi di tipo server (non devono essere assegnate ai client) che, in particolare, implementino "servizi standard", ovvero universalmente noti, come ad esempio SSH, FTP, HTTP, etc. Per convenzione una porta Well Known identifica un certo protocollo, quindi uno specifico servizio e, viceversa, ad un particolare servizio corrisponde di norma una determinata porta.
   
  • Registered Ports: 
(Porte 1024 – 49151). Si tratta di porte anch'esse riservate, ma per servizi di uso futuro o per specifiche esigenze (ad esempio, capita relativamente spesso di vedere che al protocollo HTTP venga associata la porta 8080 in luogo della 80).
   
  • Dynamic and/or Private Ports
(Porte 49152 – 65535). Porte di uso libero riservate ai processi client. Vengono normalmente assegnate dal sistema operativo ai processi client per la gestione delle comunicazioni. Queste porte non devono quindi essere assegnate a processi server.


Di seguito alcune delle porte Well Known fra le più utilizzate:

Port    Protocol Type    Protocol Name   
7 UDP ECHO
9 UDP DISCARD
13 TCP DAYTIME
17 TCP QUOTD (Quote of the day)
19 UDP CHARGEN (Character generator)
20 TCP FTP-DATA (FTP data transfer)
21 TCP FTP (File Transfer Protocol)
22 TCP SSH (Secure Shell)
23 TCP TELNET
25 TCP SMTP (Simple Mail Transfer Protocol)
42 WINS (Windows Internet Naming Service)
53 UDP DNS (Domain Name Server)
69 UDP TFTP (Trivial File Transfer Protocol)
79 TCP FINGER
80 TCP HTTP (Hyper Text Transfer Protocol)
110 TCP POP3 (Post Office Protocol 3)
113 TCP IDENT/AUTH
119 TCP NNTP (Network News Transfer Protocol)
135 EPMAP (DCE Endpoint Mapper)
137 UDP NETBIOS-ns (name service)
138 UDP NETBIOS-dgm (datagram service)
139 TCP NETBIOS-ss (session service)
143 TCP IMAP (Internet Message Access Protocol)
161 UDP SNMP (Simple Network Management Protocol)
389 TCP LDAP (Lightweight Directory Access Protocol)
443 TCP HTTPS (Secure HTTP)
445 TCP Microsoft-ds (Microsoft Directory Service)

Si noti come i protocolli, pur associati univocamente alle differenti porte, siano però tutti solo di due tipi principali: TCP e UDP. Senza necessità di scendere nei dettagli, si ricorda qui solamente che la differenza principale fra questi due risiede nel fatto che, mentre TCP garantisce una trasmissione affidabile, UDP predilige invece la velocità a discapito della precedente. Ne risulta in definitiva che, mentre i protocolli di tipo UDP sono preferibili ad esempio in comunicazioni real-time (tipo VOIP), i protocolli di tipo TCP sono più facilmente impiegati per implementare servizi dove viene richiesta completezza dell'informazione (es. SSH)

In ogni caso, attraverso l'uso di porte il sistema operativo riesce a gestire la comunicazione in rete fra processi remoti. Si parla in particolare di "socket", costrutto software rappresentato, per ciascuna macchina coinvolta nella comunicazione, dal binomio:

IP_Address : Port_Number

Per fare un parallelo col quotidiano, il socket assolve nella comunicazione digitale alla funzione che gli indirizzi riportati su un pacco svolgono in una comunicazione postale, lì dove vengono indicati l'indirizzo (IP_Address) ed il nominativo/interno (Port_Number) del destinatario e del mittente.

Di seguito, a titolo di esempio, la situazione che si potrebbe osservare in un computer all'indirizzo (locale via NAT) 192.168.1.117: un processo client al quale il sistema operativo ha assegnato la porta 60491 ha qui instaurato una comunicazione con un processo server (porta 80) residente su una macchina all'indirizzo 52.58.78.16 (evidentemente l'utente sta visitando un sito a quell'indirizzo); contestualmente un altro processo client sulla stessa macchina si vede assegnare la porta 60716 per mantenere una trasmissione di tipo Secure Shell (porta 22) con un processo server all'indirizzo 10.8.220.11 (l'utente ha quindi instaurato una connessione remota con la macchina all'indirizzo 10.8.220.11)

 Indirizzo locale Indirizzo esterno
 192.168.1.117:60491 52.58.78.16:80
 192.168.1.117:60716 10.8.220.11:22
 ...   ...

Analogamente, quella seguente è lo scenario che potrebbe osservarsi su una macchina all'indirizzo 192.168.1.17 che ospiti le pagine di un sito (intranet) disponibile ai computer della sua stessa rete (192.168.1.0/24). Due processi server sono contemporaneamente attivi all'indirizzo 192.168.1.17 e comunicano, utilizzando il protocollo HTTP (porta 80), ciascuno con un proprio processo client residente su una macchina remota (indirizzi 192.168.1.101 e 192.168.1.102 rispettivamente)

 Indirizzo locale Indirizzo esterno
 192.168.1.17:80  192.168.1.101:60321
 192.168.1.17:80  192.168.1.102:60497
 ...   ...

È usuale dividere i socket in base a particolari criteri. Ad esempio:

  • AF_UNIX::
(o Unix Domain Socket) indica i socket relativi a processi locali alla macchina (vale a dire che i due processi coinvolti nella comunicazione si scambiano dati, ma la trasmissione non è di rete rimanendo confinata alla stessa macchina; vd. esempi dopo).
   
  • AF_INET: 
indica viceversa le tradizionali comunicazioni fra host remoti, via rete.
   
O in base al tipo di protocollo adottato:

  • Datagram Socket:
questa tipologia di socket utilizza una connessione basata su protocolli di tipo UDP, connection-less (come visto scarsamente affidabili poiché non provvisti di controllo sulla trasmissione dei dati) in favore della velocità di trasmissione.
   
  • Stream Socket 
al contrario della precedente questa tipologia di socket utilizza connessioni di tipo TCP, quindi connection-oriented (la trasmissione è resa affidabile attraverso il controllo degli errori con possibilità di ritrasmissione dati) e full-duplex (la trasmissione é bidirezionale e simultanea).
   
  • Raw Socket::
riservato a particolari protocolli e a sviluppi futuri.
In questa sede ci si concentrerà sui socket di tipo stream (quindi su comunicazioni di tipo TCP) che rappresentano la maggior parte. Come visto, la trasmissione avviene di norma mediante l'interazione fra processi client e processi server e prevede tre fasi fondamentali:
  • creazione di socket lato client e lato server ad inizio trasmissione
  • trasmissione dei dati sul canale virtuale costituito dai suddetti
  • socket
  • chiusura del collegamento con cancellazione dei socket

Il dialogo fra processi di macchine remote avviene in particolare attraverso lo scambio di messaggi del tipo:

  • SYN::
sta per "syncronize" ed è il messaggio che un processo (client/server) invia alla propria controparte (processo remoto server/client) per notificargli di essere pronto ad iniziare la trasmissione. Il processo che riceve un SYN è tenuto a restituire al mittente un messaggio ACK (vd. dopo) a titolo di riscontro. La trasmissione fra due processi potrà aver luogo solo quando ciascuno di essi avrà ricevuto un messaggio SYN dall'altro.
   
  • FIN::
sta per "final" ed è analogo al SYN, ma in questo caso indica la disponibilità di un processo (client o server) a terminare la trasmissione. Anche in questo caso il processo che riceve un messaggio di FIN notificherà al processo mittente l'avvenuta ricezione dello stesso FIN con un messaggio di ACK e, come nel caso dei messaggi SYN, la fine della comunicazione fra i due processi potrà avvenire solo quando entrambi avranno ricevuto un messaggio di FIN dalla propria controparte.
   
  • ACK::
sta per "acknowledgment" ed è, come visto, il segnale di riscontro che il processo destinatario invia al processo mittente per confermargli l'avvenuta ricezione di un messaggio di SYN o FIN. In caso di mancato messaggio di ACK, il processo mittente potrebbe dover ritrasmettere al destinatario il proprio SYN o FIN.

In base a ciò, un processo può venirsi a trovare progressivamente in uno dei seguenti stati:

PROCESSI SERVER:

  • LISTEN::
il processo server è in "ascolto", pronto a ricevere un eventuale messaggio di connessione (SYN) da parte di un processo client.
   
  • SYN-RECEIVED::
il processo server ha ricevuto una richiesta di connessione da un processo client. Il processo server risponde con un ACK di conferma verso il client e valuta se è possibile accogliere la richiesta. Se la richiesta viene accettata, lo stesso processo server si prepara alla trasmissione e, quando pronto, invia il proprio SYN al client. Una volta ricevuto il relativo ACK di ritorno dal processo client, può avere inizio la trasmissione. 
   
  • ESTABLISHED::
entrambi i processi client e server si sono scambiati il proprio SYN e hanno ricevuto il relativo ACK di riscontro: la connessione è stata quindi instaurata e la trasmissione è ora in corso.
   
  • CLOSE-WAIT::
il processo server ha ricevuto una richiesta di fine trasmissione (FIN) dal processo client. Il processo server invia allora al client un ACK di riscontro e, se giudica la richiesta ricevibile, quando pronto, invia al client il proprio FIN di conferma ed entra nello stato LAST-ACK.
   
  • LAST-ACK::
il processo server ha ricevuto una richiesta di termine trasmissione da un processo client, la ha accolta, ha quindi inviato la propria FIN al processo client e sta attendendo dallo stesso processo client un (ultimo) ACK per procedere.
   
  • CLOSED::
il processo server ha ricevuto una richiesta di termine trasmissione da un processo client, la ha accolta, ha quindi inviato la propria FIN al processo client dal quale ha ricevuto l'ultimo ACK di conferma. La trasmissione è stata quindi terminata.
   
PROCESSI CLIENT:

  • SYN-SENT::
il processo client ha inviato una richiesta di connessione (SYN) al processo server ed è in attesa della relativa accettazione (ACK + SYN) da parte ello stesso. Una volta ricevuta l'approvazione del processo server, il client risponderà al solito con un ACK di conferma.
   
  • ESTABLISHED::
entrambi i processi client e server si sono scambiati il proprio SYN e hanno ricevuto il relativo ACK di riscontro: la connessione è stata quindi instaurata e la trasmissione è ora in corso.
   
  • FIN-WAIT-1::
il processo client ha inviato al processo server una richiesta di termine trasmissione (FIN) ed è in attesa di risposta (ACK) da.parte di quest'ultimo.
   
  • FIN-WAIT-2 (oppure CLOSING)::
il processo client ha ricevuto un ACK per la sua richiesta di terminare la connessione e ora sta aspettando una FIN corrispondente dal processo server (oppure, il processo client ha ricevuto una FIN dal processo server e gli ha inviato un ACK, ma non ha ancora ricevuto un ACK per il proprio messaggio FIN).
   
  • TIME-WAIT::
il processo client ha finalmente ricevuto una FIN dal processo server, ha inviato il proprio ACK di conferma. La trasmissione potrebbe quindi essere terminata, ma si lascia comunque trascorrere un lasso di tempo sufficiente a prevenire potenziali sovrapposizioni con nuove connessioni.
   
  • CLOSED::
la trasmissione col processo serve è stata terminata.


Monitorare con SS

Si posseggono ora tutti gli strumenti per utilizzare al meglio uno strumento quale SS (Socket Statistics). In molte distro Linux SS ha preso il posto del celebre Netstat (oramai deprecato) e, al pari di quest'ultimo, anzi con maggior dettaglio, è in grado di produrre informazioni circa le connessioni attive sulla macchina.

L'utilizzo di SS è immediato: è possibile digitare semplicemente il comando (non sono richiesti i diritti di amministratore):

 $ ss

per ottenere la lista di tutte le connessioni nello stato ESTABLISHED sulla nostra macchina. Per un utilizzo più completo, è sufficiente attenersi alla seguente sintassi:

 ss [Options] [Filter]

Si rimanda alla pagina del manuale (man ss) per i dettagli. Qui si riportano le opzioni ed i filtri di più frequente utilizzo (ovviamente è consentito combinare più opzioni e/o filtri nella stessa istruzione per ottenere il risultato desiderato).


Options:
-a, --all
visualizza tutti i socket: non solo quelli nello stato ESTABLISHED, come previsto di default
-l, --listening
visualizza solo i socket nello stato LISTEN
-t, --tcp
visualizza solo i socket di tipo TCP
-u, --udp
visualizza solo i socket di tipo UDP
-x, --unix
visualizza solo i socket di tipo UNIX
-p, --process
mostra i processi relativi ai socket
-n, --numeric
non risolve i nomi

Filter:
state {established | syn-sent |  
syn-recv | fin-wait-1 | fin-wait-2 | 
time-wait | closed | close-wait | 
last-ack | listening | closing}
consente di filtrare i socket in base alla stato del processo
{src|dst}
filtra i socket in base all'indirizzo IP di origine o di destinazione
{sport|dport} {eq|ne|lt|gtle|ge|}
filtra in base ad un calcolo relativo all'indirizzo di origine o di destinazione con evidente significato delle parole chiave


Di seguito alcuni esempi.

Il comando ss senza opzioni elenca tutte le connessioni ESTABLISHED. Notare che vengono incluse anche quelle di tipo UNIX (fra processi della stessa macchina):

 $ ss

Per visualizzate le sole trasmissioni TCP, UDP o UNIX rispettivamente è possibile utilizzare:

 $ ss -t

 $ ss -ua

 $ ss -x

Nel'esempio seguente vengono mostrate le connessioni TCP ma senza che vengano risolti gli indirizzi DNS:

 $ ss -nt

Per visualizzare invece le sole trasmissioni LISTENING:

 $ ss -ltn

Se invece si preferisce visualizzare i processi associati alle trasmissioni TCP:

 $ ss -tp

Filtrando infine in base allo stato dell connessione:

 $ ss -t state established


Analisi del traffico con TCPDUMP

Altro strumento indispensabile per l'analisi del traffico di rete è tcpdump. Si tratta di un analizzatore di pacchetti (in gergo sniffer) disponibile nei repository di tutte le principali distro Linux. Tcpdump si appoggia peraltro alla libreria libcap, ben nota per dar supporto anche al blasonatissimo Wireshark.

La funzione di tcpdump è quella di tracciare il traffico di rete in ingresso e in uscita dalla macchina sulla quale è in esecuzione.

Nel caso più semplice, il suo utilizzo si limita all'esecuzione del programma senza ulteriori argomenti come di seguito (sono richiesti i diritti di amministratore):

 # tcpdump

Eseguendo allora una qualsiasi operazione che comporti scambio di dati in rete, sarà possibile osservare una continua produzione di messaggi. Ciascun messaggio si riferisce ad un pacchetto inviato o ricevuto e per ogni pacchetto vengono riportate dettagliate caratteristiche.

Nell'output di tcpdump sono in particolare distinguibili facilmente l'orario (timestamp) di generazione dei messaggi, i socket di origine e di destinazione dei singoli pacchetti, il protocollo utilizzato nella trasmissione.

Potrebbe viceversa risultare non immediata l'interpretazione di altri valori riportati. Questi sono in realtà ricavati da tcpdump dalla lettura dell'header del pacchetto al quale il messaggio si riferisce. La tabella seguente descrive quindi la struttura di un pacchetto (IPv4) per facilitare la valutazione dei risultati di tcpdump.

Posizione Campo Descrizione
0-3 Version Indica la versione del pacchetto IP (ad esempio, IPv4 ha valore 4, da cui il nome).
4-7 Header_Length (HL) Indica la lunghezza (in word di 32 bit) del solo header del pacchetto.
8-15 Type_of_Service (ToS) Nelle specifiche iniziali del protocollo, questi bit servivano all'host mittente per specificare il modo con cui l'host ricevente doveva trattare il pacchetto.
16-31 Total_Length. Indica la dimensione (in byte) dell'intero pacchetto, comprendendo quindi header e dati.
32-47 Identification Identifica in modo univoco i vari frammenti in cui può essere stato "spezzato" il pacchetto.
48-50 Flags Utilizzato per il controllo del protocollo e della frammentazione dei pacchetti. Ciascuno dei tre bit ha un significato particolare: il bit 48 è riservato; il bit 49, detto DF (Don't Fragment), se posto ad 1 indica che il pacchetto non deve essere frammentato; il bit 50 prende il nome di MF (More Fragments) e, se pari a 0, indica che il pacchetto è l'ultimo, o il solo, frammento del pacchetto.
51 -63 Fragment_Offset Indica l'offset (misurato in blocchi di 8 byte) di un particolare frammento relativamente all'inizio del pacchetto.
64-71 Time_To_Live (TTL) Indica il tempo di vita (time to live) del pacchetto, necessario per evitarne la persistenza indefinita sulla rete nel caso in cui non si riesca a recapitarlo al destinatario.
72-79 Protocol Indica il codice associato al protocollo utilizzato nel campo dati del pacchetto IP (ad esempio al protocollo TCP è associato il codice 6, ad UDP il codice 17).
80-95 Header_Checksum È un campo usato per il controllo degli errori dell'header. Ad ogni hop, il checksum viene ricalcolato e confrontato con il valore di questo campo: se non c'è corrispondenza il pacchetto viene scartato.
96-127 Source_Address Indica l'indirizzo IP associato all'host del mittente del pacchetto
128-159 Destination_Address Indica l'indirizzo IP associato all'host del destinatario del pacchetto
160-191 Options Opzioni (facoltative e non molto usate) per usi più specifici del protocollo
   
160 o 192 e ss. DATA Contenuto informativo del pacchetto.

In ogni caso, la produzione di messaggi in tempo reale non rende certamente agevole la lettura ordinata degli stessi. Per questo motivo tcpdump offre all'utente la possibilità di filtrare i risultati secondo differenti criteri. Questa la sintassi:

 # tcpdump [options]

dove:

Options:

     

[ -q | -v | -vv | -vvv ]
     
Produce un output sintetico ("quick") o sempre più dettagliato ("verbose")

-D, --list-interfaces
     
Elenca le interfacce disponibili

-i <interface>
     
Limita il controllo alla sola interfaccia specificata

-n
     
Numeric: non traduce gli indirizzi

-c <n>
     
ferma la cattura dopo n pacchetti

-F <file_path>
     
il filtro è configurato nel file di posizione file_path

-A
     
L'output viene visualizzato in caratteri ascii (utile, ad esempio, se si vogliono intercettare password)

[src|dst] host <host>
     
Limita la cattura al solo host di origine o destinazione specificato

[src|dst] net <network>/<len>
     
Limita la cattura alla sola rete di origine o destinazione indicata

[tcp|udp] [src|dst] port <port>
     
Limita la cattura al solo servizio (protocollo-porta) specificato in origine o destinazione

[tcp|udp] [src|dst] portrange <p1>-<p2>
     
Limita la cattura ad un range di servizi (protocollo-porte) specificati in origine o destinazione

[[ip] proto] {icmp|icmp6|igmp|igrp|pim|
   ah|esp|\udp|\tcp}
Limita la cattura ad uno specifico protocollo

<expr>
     
Limita la cattura in base all'espressione dichiarata che può includere [!|not] [&&|and] [|||or] 

Così, volendo ad esempio visualizzare il solo traffico relativo all'interfaccia enp0s3 sarà sufficiente eseguire:

 # tcpdump -i enp0s3

Se poi, dello stesso traffico, si desiderasse intercettare solo i primi 100 pacchetti, la precedente istruzione potrebbe modificarsi come segue:

 # tcpdump -i enp0s3 -c 100

Un'ulteriore variante potrebbe essere quella di non voler risolvere i nomi. In questo caso:

 # tcpdump -i enp0s3 -c 100 -n

Se viceversa si fosse interessati al solo traffico proveniente dalla rete 10.8.110.0/23 sarebbe sufficiente eseguire:

 # tcpdump src net 10.8.110.0/23

Se invece fosse di interesse il solo indirizzo di origine 10.8.110.117:

 # tcpdump src host 10.8.110.117

Analogamente potrebbe volersi tracciare il solo traffico SSH diretto verso il proprio server. Nel qual caso:

 # tcpdump tcp dst port 22

Etc.


IPTABLES: il firewall Linux

Con la versione 2.4 del kernel, è stata introdotta in Linux una infrastruttura per la manipolazione dei pacchetti IP: NETFILTER. Netfilter è ad oggi parte integrante del kernel Linux, e IPTABLES è il suo strumento di gestione (più esattamente, IPTABLES si riferisce a IPv4, mentre per IPv6 esiste IP6TABLES). Iptables codtituisce il giusto completamento agli strumenti già esaminati: tramite SS e TCPDUMP è possibile operare un'accurata analisi del traffico di rete sulla nostra macchina, con Iptables sarà ora possibile gestirne la sicurezza. 

Iptables opera attraverso quattro "tabelle":

  • FILTER Table:
È la tabella di default. Come sarà più ampiamente spiegato di seguito, è responsabile del filtraggio dei pacchetti. Per tale motivo può essere proficuamente utilizzata per la gestione del firewalling.
   
  • NAT Table: 
Preposta alla gestione del NAT (Network Address Translation), questa tabella contiene le regole per la modifica degli indirizzi e delle porte dei pacchetti all'interno della macchina.
   
  • MANGLE Table: 
Tabella utilizzata per la modifica delle opzioni nell'header dei pacchetti, ad esempio il QoS o Quality of Service (ovvero la priorità con la quale le applicazioni accedono alle risorse di rete). 
   
  • RAW Table:
Tabella utilizzata per la gestione delle eccezioni di configurazione.


Ciascuna delle precedenti tabelle contiene al proprio interno delle "catene". Con questo termine vengono indicate delle sequenze di regole che ricordano molto le ACL (Access Control List). Ciascuna regola, difatti, indica una particolare condizione e l'azione da intraprendere nel caso in cui detta condizione venga verificata. Un pacchetto continua ad essere confrontato con ciascuna regola di una certa catena finchè non verifichi una delle condizioni, o non raggiunga il termine della catena stessa. Nel caso in cui il pacchetto verifichi una condizione, viene immediatamente gestito secondo la corrispondente azione prescritta e il processo reinizia con un altro pacchetto; se viceversa il pacchetto raggiunge la fine della catena senza soddisfare alcuna condizione, viene processato secondo un'azione di default.

In questa sede ci si concentrerà sulla tabella FILTER (si esaminerà cioè la funzione di firewall che è possibile esercitare mediante un kernel Linux). La tabella FILTER contiene in particolare tre catene predefinite (è comunque possibile crearne di nuove):

  • INPUT Chain:
filtra i pacchetti in ingresso al computer.
   
  • OUTPUT Chain: 
filtra i pacchetti in uscita dal computer.
   
  • FORWARD Chain:
filtra i pacchetti in transito all'interno del computer, ma diretti verso altre macchine.


È possibile agire sulle regole delle tre catene mediante la seguente sintassi (si osservino i diritti amministrativi):

 # iptables <command> [<chain>] [<options>] [-j] [<target>]

dove <target> rappresenta l'azione da intraprendere (la clausola -j o --jump è evocativa) qualora la condizione espressa nella prima parte del comando venga verificta (<target> in particolare può assumere esclusivamente i valori ACCEPT, DROP e REJECT a seconda che il pacchetto possa essere accettato o viceversa debba essere scartato eventualmente dandone notifica al mittente - è il casoi di REJECT,) - e dove:


Commands:

-L, --list
-S, --ist-rules
Visualizza il contenuto di una catena, se specificata, o di tutte le catena

-A, --append
Aggiunge una nuova regola alla catena specificata

-D, --delete
Cancella una regola da una catena, specificando il testo o il numero della regola (es. $ sudo iptables -D OUTPUT 4)

-C, --check
Verifica se la regola specificata esiste nella catena indicata (es. $ sudo iptables --check INPUT -s 192.168.1.123 -j DROP)

-I, --insert
Inserisce la regola specificata nella catena e nella posizione indicate (es. $ sudo iptables -I INPUT 1 -s 192.168.10.163 -j ACCEPT)

-R, --replace
Sostituisce una regola con un'altra (es. $ sudo iptables --replace INPUT 1 -s 192.168.1.127 -j ACCEPT)

-F, --flush
Cancella le regole di una catena, se specificata, o di tutte le catene (es. $ sudo iptables -F INPUT)

-Z, --zero
Azzera i contatori della catena, se specificata, o di tutte le catene.

-P, --policy
Definisce la policy di default,, ovvero un'azione da eseguire a prescindere da condizioni; viene tipicamente posta come ultima regola della  catena in modo tale da poter essere eseguita solo quando nessuna delle condizioni della catena risulta vera per il pacchetto in esame (es. $ sudo iptabes -P FORWARD DROP)

-N, --new
Crea una nuova catena

-X, --delete-chain
Cancella una catena precedntemente creata

-E, --rename-chain
Rinomina una catena precedentemente creata

 
Parameters:

-p, --protocol
Consente di specificare il tipo di protocollo da filtrare fra: tcp, udp, udplite, icmp, icmpv6, esp, ah, sctp, mh, all; è possibile utilizzare l'argomento "!" per invertire il test (NOT); E' possibile ulteriormente specificare (con evidente significato):
  • -p tcp --tcp-flags SYN, FIN, RST, ACK  SYN, ACK
  • -p {tcp|udp} [!]--sport| <port_num>
  • -p {tcp|udp} [!] --dport <port_num>
  • -p icmp [!] --icmp-type {echo-request|echo-reply|...}

-s, --source
Consente di specificare l'indirizzo o la rete (IP_Add [/mask][,...]) di origine del pacchetto da filtrare

-d, --destination
Consente di specificare l'indirizzo o la rete (IP_Addr [/mask][,...]) di destinazione del pacchetto da selezionare

-i, --interface
Consente di indicare l'Id dell'interfaccia di ingresso dei pacchetti oggetto del filtro

-o, --out-interface
Consente di indicare l'Id dell'interfaccia di uscita dei pacchetti oggetto di verifica

-m, --match
Consente di caricare particolari estensioni di iptables (vd. "man iptables-extensions" per i dettagli)
  • -m mac --mac-source <m:a:c:_:a:d:d:r>
  • -m state --state {INVALID | NEW | ESTABLISHED | RELATED | UNTRACKED}

-j, --jump
Permette di specificare il "target" della regola fra:
  • ACCEPT: accetta i pacchetti specificati nella regola.
  • DROP: rifiuta i pacchetti specificati nella regola.
  • REJECT: come DROP, ma restituisce all'host sorgente un messaggio d'errore.

 -n, --numeric
Fornisce un output numerico di porte ed indirizzi

-v, --verbose
Fornisce un output con maggior dettaglio

-x, --exact
Visualizza un output numerico in luogo di K, M o G (kilobyte, megabyte, gigabyte).

Di seguito alcuni esempi:

Si inizi col visualizzare il contenuto delle tabelle INPUT, OUTPUT e FORWARD (di default le tre tabelle sono prive di regole e per tutte la policy è ACCEPT)

 # iptables -L

Aggiungiamo una regola alla tabella INPUT con la quale semplicemente vengono dichiarati ricevibili i pacchetti che originano dallo stesso computer

 # iptables -A INPUT -s 127.0.0.1 -j ACCEPT

Se poi, magari ritenendo di aver commesso un errore, si volesse cancellare la regola appena inserita, questa potrebbe essere l'istruzione:

 # iptables -D INPUT 1

Qualcosa di analogo potrebbe aversi volendo modificare, piuttosto che cancellare, la stessa regola (di seguito vengono dichiarati sicuri i pacchetti provenienti dalla rete 192.168.1.0/24):

 # iptables -R INPUT 1 192.168.1.0/24 -j ACCEPT

Potremmo a questo punto aggiungere una policy che dichiara non ricevibili tutti gli altri pacchetti:

 # iptables -P INPUT DROP

Volendo invece ripristinare la situazione di partenza e mascherare questa volta il PING verso la nostra macchina:

 # iptables -P INPUT ACCEPT
 # iptables -F
 # iptables -A INPUT -p icmp -j DROP

Se viceversa l'intento fosse quello di rendere il nostro server accessibile solo attraverso connessione Secure Shell e solo dall'indirizzo 10.8.110.163:

 # iptables -F
 # iptables -A INPUT -s 10.8.110.163 -p tcp --dport 22 -j ACCEPT
 # iptables -P INPUT DROP

Volendo assicurare ulteriore sicurezza, si potrebbe voler completare la precedente misura imponendo che anche il MAC Address del computer mittente sia quello stabilito. Nel qual caso:

 # iptables -F
 # iptables -A INPUT -s 10.8.110.163 -p tcp --dport 22 
                     -m --mac-source 00:0F:EA:91:04:08 -j ACCEPT
 # iptables -P INPUT DROP

Di seguito invece la possibile configurazione di un personal firewall che, non avendo servizi da esporre,: consente ogni pacchetto in uscita, ma accetta in entrata solo i pacchetti di ritorno:

 # iptables -F
 # iptables -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
 # iptables -A OUTPUT -m state --state NEW,RELATED,ESTABLISHED -j ACCEPT
 # iptables -A INPUT -i lo -j ACCEPT
 # iptables -A OUTPUT -o lo -j ACCEPT
 # iptables -P INPUT DROP

Le regole impostate mediante iptables non sono persistenti, quindi, al prossimo riavvio, il nostro firewall possiederà nuovamente le impostazioni iniziali:

 # sudo iptables -S

 -P INPUT ACCEPT
 -P FORWARD ACCEPT
 -P OUTPUT ACCEPT

Per rendere permanenti le modifiche apportate a Netfilter mediante iptables esistono comunque diversi modi:
  • Creare uno script contenente le istruzioni iptables da eseguirsi all all'avvio (eventualmente mediante Systemd)

  • Utilizzare le utility
    • iptables-save: produce in output un codice che può ben essere salvato in un file (es. sudo iptables-save > ~/rules.bck);
    • iptables-restore: ripristina da file le regole precedentemente salvate (es. sudo iptables [<] ~/rules.bck)

  • Installare, se presente nei repository, il pacchetto IPTABLES-PERSISTENT. Purtroppo lo sviluppoo non è ancora del tutto consolidato e la documentazione è in continua trasformazione, ma, almeno nelle ultime versioni, questo crea i file /etc/iptables/rules.v4 e /etc/iptables/rules.v6 dove, mediante IPTABLES-SAVE, sarà possibile salvare la configurazione. La stessa configurazione sarà automaticamente ricaricata all'avvio.


Approfondimenti: 

Commenti

Post popolari in questo blog

Introduzione alle reti 3 - Switch tecnologies

In questa sezione verranno esaminate le Virtual LAN, prima espressione della tecnologia LAN Switching.    Virtual Local Area Network (VLAN) Come già detto, uno dei punti di forza di uno switch risiede nella possibilità di creare sotto-reti a basso costo. Le VLAN ( Virtual Local Area Network ) , in particolare,  rappresentano la risposta a quelle situazioni nelle quali, pur non disponendo di grandi risorse, si renda comunque necessario tener distinti due o più ambiti della stessa rete, o, come è usuale dire, suddividere in più parti un dominio di broadcast.  L'esempio tipico è quello di una (piccola) impresa che abbia necessità di tener separati sulla rete i propri device in base alle attività produttive. La rete potrebbe allora pensarsi composta di tante VLAN quante sono le attività aziendali, ciascuna VLAN potendo contenere al proprio interno l'hw destinato ad ogni specifica attività. Dal punto di vista sistemistico, una  VLAN  è costituita da un sottoinsiem

Switch Commands - istruzioni Cisco HP Extreme "in a nutshell"

Indirizzamento IP

Obiettivo di questo articolo, senza pretesa di esaurire l'argomento, è quello di presentare in modo chiaro e comprensibile un argomento alle volte ostico: l'indirizzamento IP.  Questo, fra l'altro, consentirà di affrontare, anche agli utenti meno esperti, operazioni semplici quali   la configurazione di una scheda di rete con maggiore consapevolezza. Gli indirizzi IP Come noto, con IP  ci si riferisce ad uno dei protocolli di comunicazione di rete più affermati nel mondo delle telecomunicazioni:  Internet Protocol .   Un indirizzo IP è, in particolare, un codice binario che identifica univocamente un dispositivo di rete (una scheda ethernet, la porta di uno switch o di un router, etc.) all'interno di una rete di computer.  Di primaria importanza, nell'ambito dell'indirizzamento, è la lunghezza degli indirizzi, ovvero il numero di bit utilizzati per rappresentare un indirizzo di rete. Questo, evidentemente, perché con n bit sarà possibile ind