Kernel Linux 2.4: firewall

 

Il kernel Linux può gestire direttamente il filtro dei pacchetti IP, cosa che quindi rappresenta la scelta più semplice per la realizzazione di un firewall con questo sistema operativo. A parte le limitazioni che può avere un tale tipo di firewall, il suo inserimento nella rete non genera effetti collaterali particolari, dal momento che poi non c'è bisogno di utilizzare software speciale per gli elaboratori che lo devono attraversare, come avviene invece nel caso di un firewall di tipo proxy.

Trattandosi di un'attività del kernel, è necessario che questo sia stato predisposto in fase di compilazione, oppure sia accompagnato dai moduli necessari (sezione 29.2.9). Inoltre, è opportuno aggiungere anche le funzionalità di ricomposizione dei pacchetti frammentati, oltre che le funzionalità relative al NAT (Network address translation).

L'attraversamento dei pacchetti tra un'interfaccia e l'altra è controllato dalla funzionalità di forwarding-gatewaying, che in passato andava inserita esplicitamente nel kernel. In generale, il kernel non permette questo attraversamento, che deve essere abilitato attraverso un comando simile a quello seguente:

# echo 1 > /proc/sys/net/ipv4/ip_forward

per IPv4 e

# echo 1 > /proc/sys/net/ipv6/conf/all/forwarding

per IPv6.

177.1 Schema generale di funzionamento del kernel
Il kernel Linux 2.4.* suddivide le funzionalità di trattamento dei pacchetti IP in «tabelle». Nell'ambito di ogni tabella ci possono essere diversi punti di controllo, denominati chain, che possono essere programmati per catturare i pacchetti IP e deciderne la loro sorte. A seconda delle circostanze, un pacchetto IP può essere sottoposto alla verifica di uno o più di questi punti di controllo, che vengono programmati in base a delle regole. Quando un pacchetto sottoposto a controllo corrisponde a una regola, la sua sorte viene definita dall'obiettivo di questa (ammesso che sia stato definito).

La tabella relativa alla gestione del firewall è denominata filter e si compone di tre punti di controllo: INPUT, FORWARD e OUTPUT, che indicano rispettivamente i pacchetti in ingresso, quelli in transito e quelli in uscita. Gli obiettivi più frequenti sono due, ACCEPT e DROP, che rispettivamente si riferiscono al permesso di attraversamento del punto di controllo, oppure al blocco ed eliminazione del pacchetto intercettato.

Figura 177.1. Schema di intercettazione da parte dei punti di controllo relativi alla gestione del firewall.

Pacchetti provenienti .-------------.
dall'esterno e destinati | Ingresso |
all'elaboratore stesso | |
| Regole per |
| l'ingresso |
Ingresso ------------------>| dei |----------------> Elaborazione locale
| pacchetti |
| |
| |
| Politica |
| predefinita |
`-------------'

Pacchetti provenienti .-------------.
dall'esterno e destinati | Inoltro |
altrove | |
| Regole per |
| l'attraver- |
Ingresso ------------------>| samento dei |-----------------------------> Uscita
| pacchetti |
| |
| |
| Politica |
| predefinita |
`-------------'

Pacchetti generati .-------------.
all'interno dell'elabora- | Uscita |
tore dai processi locali | |
| Regole per |
| l'uscita |
Elaborazione locale ------->| dei |-----------------------------> Uscita
| pacchetti |
| |
| |
| Politica |
| predefinita |
`-------------'

Un pacchetto proveniente da un'interfaccia qualunque, diretto allo stesso firewall, è soggetto al controllo di ingresso;(1) un pacchetto passante viene sottoposto al controllo di inoltro; un pacchetto che deve uscire attraverso un'interfaccia del firewall, perché generato da un processo locale, è sottoposto al controllo di uscita.(2)

Quando un pacchetto IP viene analizzato in un punto di controllo e all'interno di questo non c'è alcuna regola che lo prenda in considerazione, la sua sorte è stabilita dalla politica predefinita (policy) per quel contesto. Generalmente, questa politica è tale per cui gli viene concesso il transito.

177.2 IPTables per l'amministrazione del firewall
La gestione del filtro di pacchetto IP del kernel 2.4.* avviene per mezzo di IPTables, (3) ovvero l'eseguibile iptables per il controllo di IPv4 e ip6tables per il controllo di IPv6. Dal momento che le funzionalità di firewall del kernel sono piuttosto estese, la sintassi di questo programma è molto articolata, per cui se ne può apprendere l'utilizzo solo gradualmente.

Inoltre, è bene chiarire subito che le funzionalità di firewall del kernel non possono essere definite attraverso un file di configurazione; quindi, al massimo, tutto quello che si può fare è la realizzazione di uno script contenente una serie di comandi con IPTables.

IPTables interviene su un elenco di regole riferite alle funzionalità di controllo dei pacchetti IP del kernel, dove la gestione particolare riferita alle funzionalità di firewall riguarda la tabella filter. Il meccanismo è comunque simile a quello della gestione della tabella degli instradamenti di un router. L'ordine in cui sono elencate tali regole è importante, quindi si deve poter distinguere tra l'inserimento di una regola all'inizio, alla fine o in un'altra posizione dell'elenco esistente (elenco riferito sempre a un certo punto di controllo).

Salvo eccezioni particolari, che verranno descritte nel contesto opportuno, la sintassi di massima per l'utilizzo di IPTables è quella seguente:

iptables [-t tabella] opzione_di_comando punto_di_controllo [regola] [obiettivo]

ip6tables [-t tabella] opzione_di_comando punto_di_controllo [regola] [obiettivo]

La tabella serve a stabilire il contesto di intervento; il nome dell'eseguibile (iptables o ip6tables) definisce il tipo di protocolli di competenza (IPv4 o IPv6). La tabella predefinita è proprio quella riferita alle funzionalità di firewall, ovvero filter.

In generale, l'utilizzo di iptables o di ip6tables è uguale, salvo le differenze che riguardano il modo di rappresentare gli indirizzi e salvo piccole eccezioni. Nel capitolo si accennerà alle differenze solo quando necessario; tenendo conto che di solito basta sostituire il nome dell'eseguibile per cambiare il contesto.

L'opzione di comando serve a stabilire il tipo di intervento nel sistema di gestione del firewall. L'elenco seguente si riferisce alle opzioni che permettono la cancellazione o l'inserimento delle regole in un punto di controllo:


-F | --flush
elimina tutte le regole del punto di controllo specificato, oppure di tutta la tabella;
-D | --delete
elimina una o più regole dal punto di controllo specificato;
-A | --append
aggiunge una regola in coda a quelle del punto di controllo selezionato;
-I | --insert
inserisce una regola in una posizione stabilita del punto di controllo selezionato;
-R | --replace
sostituisce una regola del punto di controllo selezionato.

Altre opzioni non modificano le regole; in particolare:


-L | --list
elenca le regole di un uno o di tutti i punti di controllo della tabella;
-P | --policy
cambia la politica predefinita per il punto di controllo specificato;

Altre opzioni verranno mostrate quando sarà più opportuno.

Come già accennato, il punto di controllo viene indicato attraverso un nome. Si tratta di INPUT, FORWARD e OUTPUT, che intuitivamente fanno riferimento all'ingresso, al transito e all'uscita.

Si osservi che questi nomi sono scritti utilizzando lettere maiuscole, a differenza di quanto accadeva con la gestione del kernel 2.2.*, per sottolineare la loro differenza nel funzionamento, per cui i pacchetti in transito non sono più presi in considerazione dai punti di controllo di ingresso e di uscita.

IPTables permette di gestire delle regole all'interno di contenitori aggiuntivi a cui si fa riferimento a partire da regole inserite nei punti di controllo normali. Nella terminologia di IPTables si parla sempre di chain, sia per indicare i punti di controllo standard, sia per indicare questi elenchi di regole aggiuntive.

Infine, una regola comune è conclusa con l'indicazione di un obiettivo. L'obiettivo è la definizione della sorte da dare al pacchetto intercettato, indicata attraverso una parola chiave. Le più importanti per iniziare ad apprendere la configurazione del firewall sono: ACCEPT, DROP e REJECT.


ACCEPT
consente il transito del pacchetto;
DROP
impedisce il transito del pacchetto, limitandosi a ignorarlo;
REJECT
impedisce il transito del pacchetto notificando all'origine il rifiuto (viene inviato un messaggio ICMP specificante che il pacchetto è stato rifiutato).

Segue la descrizione di alcuni esempi.

iptables [-t filter] -A INPUT regola -j DROP

Lo schema mostra l'aggiunta di una regola di ingresso, non meglio definita, per la quale viene applicato l'obiettivo DROP.

iptables [-t filter] -R INPUT 1 regola -j DROP

Lo schema mostra la sostituzione della prima regola di ingresso con un'altra regola non meglio definita, per la quale viene applicato l'obiettivo DROP.

iptables [-t filter] -I INPUT 1 regola -j ACCEPT

Lo schema mostra l'inserimento nella prima posizione di una regola di ingresso per la quale viene consentito il transito dei pacchetti (ACCEPT).

iptables [-t filter] -D INPUT 2

Questo schema mostra l'eliminazione della seconda regola di ingresso.

iptables [-t filter] -F INPUT

Questo schema mostra l'eliminazione di tutte le regole di ingresso.

iptables [-t filter] -F

Questo schema mostra l'eliminazione di tutte le regole di tutti i punti di controllo.

iptables [-t filter] -P INPUT DROP

Cambia la politica predefinita di ingresso specificando che, in mancanza di regole, i pacchetti devono essere bloccati.

Negli esempi è stato sottolineato l'uso facoltativo dell'opzione -t per identificare precisamente la tabella su cui intervenire. Dal momento che la tabella filter è quella predefinita, nel capitolo non verrà più utilizzata tale opzione.

177.2.1 Un po' di confidenza con IPTables per la gestione del firewall
Data la complessità delle funzionalità di filtro di pacchetto del kernel, anche l'uso di IPTables è piuttosto articolato. Prima di iniziare a vedere come si possono definire le regole, conviene fare qualche esperimento che serva a introdurre l'uso di questo programma.

Gli esempi fanno riferimento a IPv4, ma dovrebbero andare bene anche per IPv6, salva la sostituzione degli indirizzi.

La prima cosa da sapere è in che modo si ottiene la visualizzazione della situazione dei punti di controllo che compongono la tabella.

# iptables -L

In questo modo si ottiene la situazione di tutti i punti di controllo (ed eventualmente anche dei raggruppamenti di regole aggiuntivi). Inizialmente si dovrebbe osservare la situazione seguente:

Chain INPUT (policy ACCEPT)
target prot opt source destination

Chain FORWARD (policy ACCEPT)
target prot opt source destination

Chain OUTPUT (policy ACCEPT)
target prot opt source destination Quello che si vede è la situazione normale del sistema prima di iniziare a inserire delle regole; tutto quello che c'è sono le politiche predefinite per ogni punto di controllo.

Se si è interessati a conoscere solo la situazione di un punto di controllo particolare, basta aggiungere il nome di questo. Per esempio, per limitare il risultato al solo punto di controllo di ingresso si può usare il comando seguente:

# iptables -L INPUT

Chain INPUT (policy ACCEPT)
target prot opt source destination Per verificare l'effetto del blocco del traffico attraverso uno dei punti di controllo si può agire sommariamente sulla politica predefinita; per esempio si può bloccare il transito dei pacchetti in ingresso con il comando seguente:

# iptables -P INPUT DROP

Questo tipo di blocco è totale e interviene anche nell'interfaccia virtuale che identifica il sistema locale: lo. Basta provare a fare un ping verso il nodo locale per accorgersi che non si ottiene più alcuna risposta.(4)

$ ping localhost

Un risultato simile si poteva ottenere utilizzando l'obiettivo REJECT. In alternativa si può intervenire nel punto di controllo di uscita; nell'esempio seguente si ripristina prima la politica di ACCEPT per i pacchetti in ingresso.

# iptables -P INPUT ACCEPT

# iptables -P OUTPUT DROP

Con il ping si ottiene in pratica lo stesso risultato, con la differenza che i pacchetti trasmessi vengono bloccati prima di poter uscire dal processo che li genera.

Se invece si interviene nel punto di controllo di inoltro (o di transito), si avverte l'effetto solo nei pacchetti che devono attraversare il firewall da un'interfaccia a un'altra. Prima di tutto è bene ricordare che questi possono transitare solo se la cosa viene abilitata attraverso il comando:

# echo 1 > /proc/sys/net/ipv4/ip_forward

oppure, per IPv6:

# echo 1 > /proc/sys/net/ipv6/conf/all/forwarding

Il comando seguente, per quanto inutile, impedisce il transito dei pacchetti tra le interfacce, attraverso la gestione del firewall, con la modifica della politica predefinita del punto di controllo relativo:

# iptables -P FORWARD DROP

Prima di proseguire è bene rimettere a posto le politiche predefinite dei tre punti di controllo:

# iptables -P INPUT ACCEPT

# iptables -P OUTPUT ACCEPT

# iptables -P FORWARD ACCEPT

177.2.2 Opzioni di contorno
Prima di affrontare l'analisi delle regole che possono essere inserite nei punti di controllo riferiti alla gestione del firewall, è meglio descrivere subito l'utilizzo di alcune opzioni di contorno che hanno un'importanza minore, oppure che si possono utilizzare indipendentemente dal tipo di protocollo a cui si fa riferimento con una regola.


ACCEPT
consente il transito del pacchetto;
-v | --verbose
Questa opzione si utilizza generalmente assieme all'opzione di comando -L, allo scopo di rendere più dettagliata l'informazione che si ottiene.
-n | --numeric
Quando IPTables viene usato per ottenere delle informazioni, con questa opzione si fa in modo che le informazioni numeriche non siano convertite in nomi (per esempio a proposito degli indirizzi IP e delle porte TCP o UDP).
-p [!] {tcp|udp|icmp|all}

--protocol [!] {tcp|udp|icmp|all}
Stabilisce il tipo di protocollo della regola che viene definita. La parola chiave all rappresenta qualsiasi protocollo ed è l'impostazione predefinita se questo non viene specificato. Le parole chiave che identificano i protocolli possono essere espresse anche attraverso lettere maiuscole. Il punto esclamativo, se utilizzato, serve a fare riferimento a tutti i protocolli fuorché quello indicato.
--source-port [!] {porta|intervallo_di_porte}

--sport [!] {porta|intervallo_di_porte}
Stabilisce la porta o le porte di ingresso coinvolte, nel caso dei protocolli TCP o UDP.
--destination-port [!] {porta|intervallo_di_porte}

--dport [!] {porta|intervallo_di_porte}
Stabilisce la porta o le porte di destinazione coinvolte, nel caso dei protocolli TCP o UDP.
-i [!] interfaccia

--in-interface [!] interfaccia
Indica il nome dell'interfaccia di rete attraverso la quale sono ricevuti i pacchetti della regola che si sta definendo. Quando questa opzione non viene usata, si intende fare riferimento implicitamente a qualunque interfaccia di rete.
Non è necessario che l'interfaccia indicata esista già nel momento in cui si inserisce la regola. Inoltre, è possibile indicare un gruppo di interfacce, sostituendo il numero finale con il segno +. Per esempio, ppp+ rappresenta tutte le interfacce ppp0, ppp1, ecc.
Questo comportamento riguarda anche l'opzione -o, riferita all'interfaccia di uscita.
-o [!] interfaccia

--out-interface [!] interfaccia
Indica il nome dell'interfaccia di rete attraverso la quale sono inviati i pacchetti della regola che si sta definendo. Quando questa opzione non viene usata, si intende fare riferimento implicitamente a qualunque interfaccia di rete.
-j obiettivo

--jump obiettivo
Questa opzione serve a definire l'obiettivo, attraverso una parola chiave tra quelle consuete, oppure il riferimento a un gruppo di regole creato a parte, oppure ancora permette di specificare un'estensione.
Un'estensione è un obiettivo speciale che può essere utilizzato in base al contesto, oppure a seguito di una richiesta esplicita di caricamento di un modulo con l'opzione -m. Verrà chiarito in seguito di cosa si tratta.

Segue la descrizione di alcuni esempi.

# iptables -L INPUT -v

Elenca le regole di ingresso in modo dettagliato.

# iptables -L OUTPUT -n

Elenca le regole di uscita senza tradurre informazioni numeriche nei nomi corrispondenti.

iptables -A punto_di_controllo regola -i eth0 -j DROP

Lo schema mostra l'aggiunta in coda di una regola non meglio identificata, nella quale viene specificato in particolare che deve riferirsi al traffico entrante dall'interfaccia eth0. Per i pacchetti che vengono intercettati dalla regola, viene applicato l'obiettivo DROP.

iptables -A punto_di_controllo -p tcp regola -i eth0 -j DROP

Lo schema mostra l'aggiunta in coda di una regola non meglio identificata, nella quale viene specificato in particolare che deve riferirsi al traffico TCP entrante dall'interfaccia eth0. Per i pacchetti che vengono intercettati dalla regola, viene applicato l'obiettivo DROP.

iptables -A punto_di_controllo -p ! tcp regola -i ! eth0 -j DROP

Lo schema mostra l'aggiunta in coda di una regola non meglio identificata, nella quale viene specificato in particolare che deve riferirsi a tutto il traffico che non sia TCP, entrante da un'interfaccia qualunque purché non sia eth0. Per i pacchetti che vengono intercettati dalla regola, viene applicato l'obiettivo DROP.

177.2.3 Regole che non fanno riferimento a un protocollo
Le regole che non indicano un protocollo particolare possono servire esclusivamente a individuare il traffico riferito a un'origine e a una destinazione, con l'indicazione eventuale dell'interfaccia di ingresso e di uscita:

[-p all] [-s [!] origine] [-i interfaccia] [-d [!] destinazione] [-o interfaccia]

Come si vede dallo schema, si possono utilizzare le opzioni -s e -d per indicare rispettivamente l'origine e la destinazione di un pacchetto. In aggiunta, si potrebbe inserire l'indicazione di una certa interfaccia attraverso cui i pacchetti vengono ricevuti o trasmessi; inoltre, volendo indicare espressamente che non si fa riferimento a un protocollo particolare, si può aggiungere l'opzione -p con l'argomento all.

La definizione di un gruppo di indirizzi IP può essere fatta attraverso l'indicazione di una coppia numero_ip/maschera, con una barra obliqua di separazione tra i due. La maschera può essere indicata nel modo consueto, oppure con un numero che esprime la quantità di bit iniziali da porre al valore uno. A titolo di esempio, la tabella 177.5 mostra l'equivalenza tra alcune maschere di rete tipiche e questo numero di abbreviazione.


Tabella 177.5. Maschere di rete tipiche per IPv4.

Maschera di rete Abbreviazione Sottorete
255.0.0.0 8 Classe A
255.255.0.0 16 Classe B
255.255.255.0 24 Classe C
255.255.255.255 32 punto-punto

Quando si vuole fare riferimento a indirizzi imprecisati, si utilizza solitamente l'indirizzo 0.0.0.0, che può essere indicato anche con un solo zero; questo si abbina di solito alla maschera nulla: 0.0.0.0/0 o 0/0. Tuttavia, per fare riferimento a qualunque indirizzo, è sufficiente omettere la sua indicazione, in pratica basta fare a meno di indicare l'opzione -s o -d.

L'indicazione di un indirizzo può essere fatta utilizzando direttamente il nome di dominio corrispondente, ma questo richiede la disponibilità di un servizio DNS; ciò può essere conveniente quando si tratta di un firewall connesso stabilmente con la rete esterna, altrimenti si creerebbero delle attese inutili e fastidiose, nel tentativo di risolvere dei nomi che non sono di competenza delle zone locali. Pertanto, in generale è preferibile indicare indirizzi in forma numerica.

Il punto esclamativo che può essere inserito facoltativamente di fronte all'indicazione di un indirizzo IP, o di un gruppo di indirizzi, rappresenta la negazione logica e serve a fare riferimento al gruppo di indirizzi complementare.


Tabella 177.6. Rappresentazione dell'origine e della destinazione.

Opzione Descrizione
-s [!] indirizzo[/maschera]

--source [!] indirizzo[/maschera]
Permette di definire l'origine dei pacchetti. L'indirizzo viene indicato generalmente in forma numerica, anche se c'è la possibilità di usare un nome di dominio. La maschera, eventuale, serve a indicare un gruppo di indirizzi.
Se questo parametro viene omesso, si intende implicitamente -s 0.0.0.0/0, ovvero -s 0/0, che rappresenta tutti gli indirizzi possibili.
-d [!] indirizzo[/maschera]

--destination [!] indirizzo[/maschera]
Permette di definire la destinazione dei pacchetti. L'indirizzo viene indicato generalmente in forma numerica, anche se c'è la possibilità di usare un nome di dominio. La maschera, eventuale, serve a indicare un gruppo di indirizzi.
Se questo parametro viene omesso, si intende implicitamente -d 0.0.0.0/0, ovvero -d 0/0, che rappresenta tutti gli indirizzi possibili.

Segue la descrizione di alcuni esempi.

# iptables -A INPUT -s 192.168.100.0/24 -j DROP

Blocca tutto il traffico in ingresso, destinato all'elaboratore locale, proveniente dalla rete 192.168.100.*.

# iptables -A INPUT -s 192.168.100.0/24 -d 0/0 -j DROP

Esattamente come nell'esempio precedente.

# iptables -A INPUT -s 192.168.100.0/24 -d 0/0 -i eth0 -j DROP

Come nell'esempio precedente, specificando però che questo traffico in ingresso deve provenire dall'interfaccia eth0 (se provenisse da un'altra interfaccia, non verrebbe intercettato da questa regola).

# iptables -A FORWARD -d 192.168.100.0/24 -j DROP

Blocca tutto il traffico in transito, che risulta destinato alla rete 192.168.100.*.

# iptables -A FORWARD -s 0/0 -d 192.168.100.0/24 -j DROP

Esattamente come nell'esempio precedente.

# iptables -A FORWARD -s 0/0 -d ! 192.168.100.0/24 -j DROP

Blocca tutto il traffico in transito che risulta destinato a indirizzi diversi dalla rete 192.168.100.*.

# iptables -A OUTPUT -d 192.168.100.0/24 -j DROP

Blocca tutto il traffico in uscita, generato nell'elaboratore locale, che risulta destinato alla rete 192.168.100.*.

177.2.4 Utilizzo pratico di regole elementari
Come negli esempi mostrati in precedenza, in cui si agiva soltanto sulla politica predefinita, con la stessa semplicità si può sperimentare l'uso delle regole. Per cominciare, quando il comando iptables -L genera il risultato

Chain INPUT (policy ACCEPT)
target prot opt source destination

Chain FORWARD (policy ACCEPT)
target prot opt source destination

Chain OUTPUT (policy ACCEPT)
target prot opt source destination

significa che non ci sono regole per alcun punto di controllo e le politiche predefinite non oppongono resistenza al transito dei pacchetti. Con una regola molto semplice è possibile bloccare qualunque ingresso attraverso l'interfaccia virtuale corrispondente a localhost, cioè all'indirizzo 127.0.0.1:

# iptables -A INPUT -s 127.0.0.1 -j DROP

Se si tenta di fare il ping verso il nodo locale, questo non genera alcuna risposta, dal momento che tutti i pacchetti in ingresso vengono eliminati. Anticipando un po' quello che verrà descritto in seguito, se lo scopo fosse stato esclusivamente quello di impedire l'ingresso dei pacchetti del protocollo ICMP (cosa che tra l'altro impedisce il ping), si poteva usare un comando più specifico:

# iptables -A INPUT -p icmp -s 127.0.0.1 -j DROP

Se sono stati eseguiti gli esempi, il comando iptables -L INPUT dovrebbe generare il risultato seguente:

Chain INPUT (policy ACCEPT)
target prot opt source destination
DROP all -- localhost anywhere
DROP icmp -- localhost anywhere

Prima di fare altre considerazioni, conviene osservare la simbologia usata nel rapporto che è stato ottenuto: la colonna prot rappresenta il protocollo di riferimento; la colonna opt rappresenta delle specificazioni opzionali delle regole che in questo caso non sono mai state utilizzate; le colonna source e destination rappresentano l'origine e la destinazione dei pacchetti, dove in particolare la parola chiave anywhere esprime in pratica ciò che altrimenti si indicherebbe con la notazione 0.0.0.0/0. Si osservi la differenza nel risultato nel caso si utilizzi l'opzione -n, ovvero il comando iptables -L INPUT -n, allo scopo di eliminare le rappresentazioni simboliche degli indirizzi.

Chain INPUT (policy ACCEPT)
target prot opt source destination
DROP all -- 127.0.0.1 0.0.0.0/0
DROP icmp -- 127.0.0.1 0.0.0.0/0

Le regole hanno una sequenza precisa; avendo utilizzato sempre l'opzione di comando -A, queste sono state aggiunte di seguito. Come si può intuire, la seconda regola è inutile, dal momento che i pacchetti che potrebbero riguardarla vengono già presi in considerazione da quella precedente che li blocca completamente per conto proprio.

Le regole possono essere eliminate in modo selettivo attraverso l'opzione di comando -D, oppure in modo complessivo attraverso l'opzione -F. Per eliminare la prima regola, si potrebbe utilizzare uno dei due comandi seguenti:

# iptables -D INPUT -s 127.0.0.1 -j DROP

# iptables -D INPUT 1

Nel primo caso viene eliminata la prima regola che corrisponde al modello, cioè la prima in assoluto, mentre il secondo comando fa riferimento direttamente al numero della regola. Naturalmente, dopo l'eliminazione della prima regola, quella che inizialmente era la seconda diventa la prima:

Chain INPUT (policy ACCEPT)
target prot opt source destination
DROP icmp -- localhost anywhere

Come accennato, per eliminare tutte le regole di un punto di controllo si può usare l'opzione di comando -F:

# iptables -F INPUT

L'esempio elimina tutte le regole di ingresso.

Se l'elaboratore con il quale si fanno questi esperimenti ospita un servizio si può fare qualche esperimento più interessante. Supponendo di disporre di un servente HTTP che riceve richieste attraverso la porta 80 del protocollo TCP, si potrebbe impedirne l'accesso da parte dell'utente che accede dallo stesso sistema locale attraverso il comando seguente:

# iptables -A INPUT -p tcp -s 127.0.0.1 -d 127.0.0.1 <-'
`->--dport 80 -j REJECT

Quando si avvia un programma di navigazione per accedere al servizio HTTP locale, questo cerca di instaurare una connessione TCP utilizzando la porta 80 nella destinazione; se il firewall dispone della regola inserita con il comando appena mostrato, intercetta il tentativo di connessione e restituisce un messaggio di rifiuto attraverso il protocollo ICMP. La scelta di utilizzare l'obiettivo REJECT è motivata da questa esigenza: evitare di fare perdere tempo a chi tenta di accedere, perché diversamente l'obiettivo DROP renderebbe la cosa più subdola. Si osservi cosa si ottiene con l'opzione -L:

# iptables -L INPUT

Chain INPUT (policy ACCEPT)
target prot opt source destination
REJECT tcp -- localhost localhost tcp (segue) dpt:www reject-with icmp-port-unreachableLa sigla dpt sta per Destination port; www è evidentemente il nome della porta 80. Dal momento che è stata richiesto l'obiettivo REJECT, viene mostrato esplicitamente il tipo di messaggio ICMP che viene restituito a seguito di un tentativo di accesso: port-unreachable.

Per definire delle regole corrette per i fini che ci si prefigge, occorre conoscere bene il comportamento del protocollo che si utilizza. Tornando all'esempio appena fatto, in cui lo scopo era quello di impedire all'utente del sistema locale di accedere al servizio HTTP locale, si potrebbe ottenere un risultato equivalente agendo sul punto di controllo di uscita. Per farlo occorre sapere che la connessione TCP è simmetrica e che nel flusso di ritorno il servizio HTTP utilizza ancora la stessa porta 80, già impiegata per ricevere la richiesta di connessione.

# iptables -F INPUT

# iptables -A OUTPUT -p tcp -s 127.0.0.1 -sport 80 <-'
`->-d 127.0.0.1 -j REJECT

In questo caso di deve osservare comunque una cosa: il messaggio ICMP, con cui si notifica il blocco del transito del pacchetto in uscita, è diretto all'applicazione che tenta di rispondere alla richiesta del cliente, di conseguenza il cliente ne resta all'oscuro.

177.2.5 Regole per i protocolli TCP e UDP
Il modo con cui si possono definire le regole necessarie a individuare i pacchetti, dipendono dal tipo di protocollo utilizzato. Generalmente si è interessati maggiormente a controllare i protocolli TCP e UDP, che hanno in comune l'utilizzo delle porte.

Dovendo fare riferimento a un protocollo TCP o UDP si utilizza l'opzione -p, seguita dalla parola chiave tcp o udp. Dal momento che i protocolli TCP e UDP utilizzano le porte, l'origine e la destinazione possono includere questa informazione, con l'uso delle opzioni --sport e --dport rispettivamente.

Le porte possono essere indicate in modo preciso (una soltanto), oppure attraverso un intervallo. Queste porte possono essere espresse attraverso un nome, come definito nel file /etc/services, oppure per numero, cosa che di solito si preferisce per evitare ambiguità o malintesi. Gli intervalli di porte, in particolare, vengono espressi nella forma seguente:

porta_iniziale:porta_finale

Se si indica un intervallo, cosa che si determina per la presenza dei due punti, se manca l'indicazione della porta iniziale si intende in modo predefinito la numero zero, se invece manca quella finale si intende la porta 65 535. Come nel caso degli indirizzi IP, l'indicazione della porta o dell'intervallo di queste può essere preceduta dal punto esclamativo in qualità di negazione logica.


Tabella 177.7. Opzioni per i protocolli TCP e UDP.

Opzione Descrizione
-s [!] indirizzo[/maschera] <-'
`->[!] [--sport porta|intervallo_di_porte]

--source [!] indirizzo[/maschera] <-'
`->[!] [--source-port porta|intervallo_di_porte]

-d [!] indirizzo[/maschera] <-'
`->[!] [--dport porta|intervallo_di_porte]

--destination [!] indirizzo[/maschera] <-'
`->[!] [--destination-port porta|intervallo_di_porte]
Con i protocolli TCP e UDP, l'origine e la destinazione possono includere l'indicazione delle porte.

Nel caso di protocolli TCP, è possibile analizzare i bit che qualificano lo stato della connessione. Questi bit hanno un nome simbolico, corrispondente a: SYN, ACK, FIN, RST, URG e PSH. Si può controllare lo stato di questi bit con l'opzione --tcp-flags. Dal momento che è comune la richiesta di individuare i pacchetti con il bit SYN attivo e i bit RST e ACK disattivati, si può usare per questo l'opzione --syn.


Tabella 177.8. Opzioni per i protocolli TCP.

Opzione Descrizione
--tcp-flags elenco_bit_da_considerare <-'
`->elenco_bit_attivi
Gli elenchi in questione si ottengono indicando i nomi dei bit separati da una virgola, senza l'aggiunta di spazi, dove in particolare, la parola chiave ALL fa riferimento a tutti i bit gestibili.
Per esempio, --tcp-flags ALL SYN,ACK indica la richiesta di individuare i pacchetti TCP in cui solo i bit SYN e ACK sono attivi simultaneamente (mentre tutti gli altri sono disattivati). La stessa cosa si poteva esprimere in modo esteso come: --tcp-flags SYN,ACK,FIN,RST,URG,PSH SYN,ACK.
--syn
Corrisponde in pratica a --tcp-flags SYN,RST,ACK SYN.
Questi pacchetti vengono usati nel protocollo TCP per richiedere l'inizializzazione della connessione. In pratica, bloccando questi pacchetti si impedisce l'instaurarsi di una connessione TCP in un solo verso.

Segue la descrizione di alcuni esempi.

# iptables -A INPUT -p tcp -s ! 192.168.0.0/16 <-'
`->-d 192.168.0.0/16 --dport 80 -j REJECT

Impedisce l'accesso ai servizi HTTP (protocollo TCP, porta 80) della rete 192.168.*.* a tutti gli indirizzi estranei alla rete stessa.

# iptables -A INPUT -p tcp -s ! 192.168.0.0/16 <-'
`->-d 192.168.0.0/16 --dport 80 --syn -j REJECT

Come nell'esempio precedente, limitandosi a intervenire nei pacchetti di inizializzazione delle connessioni.

177.2.6 Regole per il protocollo ICMP
Il protocollo ICMP è molto importante per il controllo del funzionamento della rete, in questo senso è rara la possibilità che sia il caso di bloccarne il transito attraverso il firewall. Tuttavia, dal momento che i fini del firewall non si limitano al blocco del traffico, è comunque importante poter indicare una regola che sappia selezionare un tipo particolare di pacchetto ICMP. La tabella 176.2 elenca i tipi di pacchetto ICMP e il loro utilizzo.

Per indicare una regola che faccia riferimento a un tipo particolare di pacchetto ICMP, si sfruttano le opzioni che servono a specificare l'origine o la destinazione, aggiungendo il numero o il nome del tipo ICMP (il numero può essere composto da una seconda parte, denominato codice). In pratica, questa informazione va a sostituire il numero di porta nel caso dei protocolli TCP e UDP.

È estremamente importante che non vengano bloccati i messaggi ICMP di tipo 3.

Il protocollo ICMP è differente tra IPv4 e IPv6, pertanto la sigla usata per farvi riferimento cambia.

Il comando iptables -p icmp -h genera l'elenco di tutti i messaggi ICMP gestibili con IPv4:

# iptables -p icmp -h[Invio]

Valid ICMP Types:
echo-reply (pong)
destination-unreachable
network-unreachable
host-unreachable
protocol-unreachable
port-unreachable
fragmentation-needed
source-route-failed
network-unknown
host-unknown
network-prohibited
host-prohibited
TOS-network-unreachable
TOS-host-unreachable
communication-prohibited
host-precedence-violation
precedence-cutoff
source-quench
redirect
network-redirect
host-redirect
TOS-network-redirect
TOS-host-redirect
echo-request (ping)
router-advertisement
router-solicitation
time-exceeded (ttl-exceeded)
ttl-zero-during-transit
ttl-zero-during-reassembly
parameter-problem
ip-header-bad
required-option-missing
timestamp-request
timestamp-reply
address-mask-request
address-mask-replySi può osservare che i nomi rientrati, fanno riferimento a un tipo ICMP formato anche attraverso l'indicazione di un codice. Per esempio, network-unreachable corrisponde a 3/0.


Tabella 177.9. Opzioni per i protocolli ICMP.

Opzione Descrizione
-s [!] indirizzo[/maschera] <-'
`->[!] [--icmp-type tipo[/codice]]

--source [!] indirizzo[/maschera] <-'
`->[!] [--icmp-type tipo[/codice]]

-d [!] indirizzo[/maschera] <-'
`->[!] [--icmp-type tipo[/codice]]

--destination [!] indirizzo[/maschera] <-'
`->[!] [--icmp-type tipo[/codice]]
Come già accennato, con il protocollo ICMP l'origine e la destinazione possono includere l'indicazione del tipo di messaggio ICMP.

Segue la descrizione di alcuni esempi.

# iptables -A INPUT -p icmp -s ! 192.168.0.0/16 <-'
`->--icmp-type 8 -d 192.168.0.0/16 -j DROP

Blocca e ignora i pacchetti ICMPv4 che contengono un messaggio di tipo 8, cioè echo-request, proveniente da un indirizzo estraneo alla rete 192.168.*.* e destinato alla rete stessa.

# iptables -A INPUT -p icmp -s ! 192.168.0.0/16 <-'
`->--icmp-type echo-request -d 192.168.0.0/16 -j DROP

Esattamente come nell'esempio precedente, indicando per nome il tipo ICMPv4.

# ip6tables -A INPUT -p icmpv6 -s ! fec0::/16 <-'
`->--icmpv6-type echo-request -d fec0::/16 -j DROP

Blocca e ignora i pacchetti ICMPv6 che contengono un messaggio di tipo echo-request, proveniente da un indirizzo estraneo alla rete fec0:* e destinato alla rete stessa.

177.2.7 Pacchetti frammentati
I pacchetti frammentati costituiscono un problema per la gestione del firewall. In generale ci si limita a intervenire sul primo frammento, perché questo dovrebbe contenere le informazioni necessarie a identificarlo correttamente.

Se il firewall rappresenta un passaggio obbligato per il traffico che lo attraversa, è molto importante che sia abilitata la ricomposizione dei pacchetti frammentati. Questo risolve tanti problemi e soprattutto quello del controllo dei frammenti.

Per identificare un frammento di pacchetto successivo al primo, si utilizza l'opzione -f nel modo seguente:

[!] -f | [!] --fragment

Il punto esclamativo permette di ottenere l'effetto contrario, cioè di fare riferimento a tutti i pacchetti che non sono frammenti. Utilizzando questa opzione non è possibile indicare delle porte TCP o UDP, né specificare il tipo di messaggio per il protocollo ICMP.

L'esempio seguente blocca l'attraversamento di frammenti dei pacchetti ICMP provenienti da un indirizzo estraneo alla rete 192.168.*.* e destinati alla rete stessa.

# iptables -A FORWARD -p icmp -s ! 192.168.0.0/16 <-'
`->-d 192.168.0.0/16 -f -j DROP

177.3 Estensioni particolari
Le funzionalità di filtro del kernel sono suddivise in segmenti differenti che possono essere incluse o meno, in fase di compilazione, oppure possono essere caricate attraverso moduli esterni. Queste funzionalità particolari sono definite moduli, senza per questo voler confondere il concetto con i moduli del kernel. Per utilizzare queste funzionalità si deve indicare prima il modulo, attraverso l'opzione -m:

-m modulo

--match modulo

Nel seguito vengono presentati solo alcuni dei moduli disponibili.

È molto probabile che tali estensioni non siano tutte disponibili per IPv6; ma di questo ci si accorge facilmente dalle segnalazioni di errore generate da ip6tables.

177.3.1 Limiti
È possibile definire una regola che scatti fino al raggiungimento di un certo limite per un certo tipo di pacchetto. Si tratta del modulo limit:

-m limit

Si distinguono due informazioni in questo contesto: la quantità di pacchetti per unità di tempo e il margine di sicurezza prima che venga preso in considerazione il raggiungimento del limite.


Tabella 177.10. Opzioni relative al modulo limit.

Opzione Descrizione
-m limit --limit n[/unità_di_tempo]
Questa opzione serve a definire la quantità di pacchetti (n) entro la quale scatta la regola. Se non si indica l'unità di tempo si fa riferimento implicitamente a secondi. A ogni modo, si possono usare le parole chiave seguenti, con il significato intuitivo che hanno: second, minute, hour, day. È importante osservare che si possono usare anche solo le iniziali di questi termini. Per esempio, --limit 10 rappresenta un limite di 10 pacchetti per secondo, cosa che si può esprimere come --limit 10/second, oppure anche --limit 10/s.
-m limit --limit-burst n
Questa opzione, --limit-burst, serve a creare un margine iniziale ulteriore, dopo il quale inizia il conteggio del limite stabilito con l'opzione --limit. Se non si specifica questa opzione, il margine è di 5.

Vengono riproposti gli esempi che appaiono già nel Linux 2.4 packet filtering HOWTO di Rusty Russell. Ovviamente, perché questi limiti abbiano un senso, dopo le regole che consentono il transito entro una certa frequenza, occorre aggiungere delle regole che blocchino lo stesso tipo di pacchetti, senza più l'indicazione di un limite.

Protezione contro un attacco da inondazione di pacchetti «SYN»:

# iptables -A FORWARD -p tcp --syn -m limit <-'
`->--limit 1/s -j ACCEPT

Consente il transito di un solo pacchetto di inizializzazione delle connessioni TCP al secondo. Per bloccare i pacchetti successivi si aggiunge il blocco degli stessi pacchetti:

# iptables -A FORWARD -p tcp --syn -j DROP

Protezione contro un tentativo di scansione delle porte TCP:

# iptables -A FORWARD -p tcp <-'
`->--tcp-flags SYN,ACK,FIN,RST RST -m limit <-'
`->--limit 1/s -j ACCEPT

Consente il transito di un pacchetto TCP al secondo con il solo bit RST attivo, nell'ambito del gruppo di bit composto da SYN, ACK, FIN e RST. Per bloccare i pacchetti successivi si aggiunge il blocco degli stessi pacchetti:

# iptables -A FORWARD -p tcp <-'
`->--tcp-flags SYN,ACK,FIN,RST RST -j DROP

Protezione contro un'inondazione di richieste di eco ICMP (ping):

# iptables -A FORWARD -p icmp --icmp-type echo-request <-'
`->-m limit --limit 1/s -j ACCEPT

Consente il transito di un pacchetto ICMP di tipo 8 (richiesta di eco) al secondo. Per bloccare i pacchetti successivi si aggiunge il blocco degli stessi pacchetti:

# iptables -A FORWARD -p icmp --icmp-type echo-request -j DROP

Gli esempi mostrano tutti un controllo applicato ai pacchetti in transito. Per proteggere anche il firewall occorre intervenire nello stesso modo sui pacchetti in ingresso.

177.3.2 Stato delle connessioni
Un modulo speciale, denominato state, consente di analizzare le connessioni e di individuarle in base a uno status semplice da definire.

-m state

Questo modulo consente semplicemente di utilizzare l'opzione --state, con cui si specifica lo stato di una connessione:

--state {NEW|ESTABLISHED|RELATED|INVALID}[,...]

Le varie parole chiave utilizzate per definire lo stato di una connessione hanno il significato descritto nell'elenco seguente.


Tabella 177.11. Opzioni relative al modulo state.

Opzione Descrizione
-m state --state NEW[,...]
Si tratta di un pacchetto che crea una nuova connessione.
-m state --state ESTABLISHED[,...]
Si tratta di un pacchetto che appartiene a una connessione già esistente.
-m state --state RELATED[,...]
Si tratta di un pacchetto correlato a un'altra connessione. Per esempio, potrebbe trattarsi di un messaggio ICMP di errore, oppure di una connessione TCP generata automaticamente da una connessione FTP precedente.
-m state --state INVALID[,...]
Si tratta di un pacchetto che non può essere individuato per qualche ragione e come tale può essere considerato non valido.

Segue la descrizione di alcuni esempi.

# iptables -A FORWARD -d 192.168.0.0/16 -m state <-'
`->--state ESTABLISHED,RELATED -j ACCEPT

Consente il transito verso gli indirizzi 192.168.*.* quando si tratta di connessioni già realizzate o si tratta di pacchetti correlati a connessioni preesistenti.

# iptables -A FORWARD -d 192.168.0.0/16 -m state <-'
`->--state INVALID -j DROP

Elimina i pacchetti destinati agli indirizzi 192.168.*.* quando questi non sono identificabili in qualche modo, nel senso che non sembrano avere motivo di esistere.

# iptables -A FORWARD -m state --state NEW -i ! ppp0 -j ACCEPT

Consente l'instaurarsi di una connessione che attraversi il nodo, purché ciò non avvenga a cominciare da un pacchetto che entri dall'interfaccia ppp0 (PPP).

177.4 Strategie
In generale, quando si predispone uno script con tutte le regole di firewall che si vogliono applicare ai pacchetti in ingresso, in uscita e in transito, si inizia dall'azzeramento di quelle eventualmente esistenti, esattamente nel modo seguente:


--------------------------------------------------------------------------------

#!/bin/sh

/sbin/iptables -F
#...
--------------------------------------------------------------------------------

Dal momento che le funzionalità di filtro del kernel Linux non devono interferire con quelle di instradamento (routing), nel caso le prime non siano state definite, è necessario che la politica predefinita sia sempre ACCEPT. In generale, se si vuole configurare il proprio elaboratore come firewall la situazione cambia e dovrebbe essere conveniente il contrario, in modo da poter controllare la situazione. In pratica, ancora prima dell'azzeramento delle regole delle varie categorie, è solitamente opportuno modificare le politiche predefinite, in modo da bloccare gli accessi e il transito dei pacchetti.


--------------------------------------------------------------------------------

/sbin/iptables -P INPUT DROP
/sbin/iptables -P OUTPUT DROP
/sbin/iptables -P FORWARD DROP
--------------------------------------------------------------------------------

La definizione delle regole di firewall deve tenere conto dell'ordine in cui appaiono nell'elenco gestito all'interno del kernel, quindi, la scelta tra le opzioni di comando -A (aggiunta in coda) e -I (inserimento all'inizio o in un'altra posizione) deve essere fatta in modo consapevole. A seconda della propria filosofia personale, si sceglierà probabilmente di utilizzare sempre solo un tipo, oppure l'altro.

Se si sceglie di «aggiungere» le regole, dovrebbe essere conveniente iniziare da quelle di eliminazione o rifiuto (DROP o REJECT), per finire con quelle di accettazione (ACCEPT).

Se si preferisce lasciare che la politica predefinita sia ACCEPT, è importante ricordare di aggiungere una regola che impedisca l'accesso in modo generalizzato alla fine di tutte le regole di un punto di controllo, come mostrato nell'esempio seguente:


--------------------------------------------------------------------------------

# In coda a tutte le regole
/sbin/iptables -A INPUT -j DROP
/sbin/iptables -A OUTPUT -j DROP
/sbin/iptables -A FORWARD -j DROP
--------------------------------------------------------------------------------

Nell'esempio, non avendo fatto riferimento ad alcun protocollo, né ad alcun indirizzo sorgente o di destinazione, si intendono implicitamente tutti i tipi di pacchetto. Questo tipo di strategia è comunque applicabile con qualunque tipo di politica predefinita, dal momento che con questa regola si catturano tutti i pacchetti rimanenti.

Quando lo scopo di un firewall è solo quello di proteggere una rete interna da quella esterna, si potrebbe pensare che l'uso di regole per il solo attraversamento dovrebbe bastare. In effetti, dal momento che i pacchetti devono attraversare il firewall per raggiungere la rete interna, il ragionamento è corretto; tuttavia, bisogna pensare anche a proteggere il firewall e in tal senso si comprende l'utilità di disporre di un punto di controllo in ingresso. Infatti, se un aggressore riesce a ottenere accesso nel firewall, da lì può entrare nella rete interna che invece si considera protetta. Il punto di controllo in uscita è una possibilità in più per completare le cose ed è un bene che ci siano tante possibilità.

Naturalmente, le funzionalità di filtro dei pacchetti sono utili anche per gli elaboratori che devono difendersi da soli, perché si trovano in un ambiente ostile, o perché semplicemente non ci si può fidare. È evidente in questi casi che diventa importantissima la possibilità di intervenire nelle regole del punto di controllo di ingresso ed eventualmente anche in quelle del punto di controllo in uscita, mentre il controllo dell'attraversamento dovrebbe risultare semplicemente inutile.

177.4.1 UDP e DNS
Una delle politiche normali nella configurazione di un firewall che deve proteggere una rete interna è quella di non lasciare che i pacchetti del protocollo UDP possano attraversarlo. In linea di principio questo atteggiamento è ragionevole, dal momento che con il protocollo UDP si gestiscono spesso informazioni delicate e aggredibili con facilità (NFS e NIS sono gli esempi più importanti).

# iptables -A FORWARD -p udp -j DROP

Quello che si vede è il comando molto semplice che permette di ottenere questo risultato, intervenendo necessariamente in fase di attraversamento.

Il sistema DNS utilizza prevalentemente il protocollo UDP e a volte il protocollo TCP. In questo senso, un servizio DNS collocato all'interno di una rete protetta che abbia bisogno di risolvere nomi della rete esterna, deve necessariamente avvalersi di un altro servizio DNS posto nel firewall o anche al di fuori di questo.


--------------------------------------------------------------------------------

options {
forwarders {
123.123.123.123;
};
};
--------------------------------------------------------------------------------

L'esempio che si vede rappresenta una parte del file /etc/named.conf (o /etc/bind/named.conf) dove si indica l'indirizzo 123.123.123.123 da utilizzare per inoltrare le richieste che non possono essere risolte in base alla definizione delle zone locali. La comunicazione con il servizio presso 123.123.123.123 avviene con il protocollo TCP, permettendo di superare il problema del blocco al transito dei pacchetti UDP.

Il fatto che il sistema DNS utilizzi a volte il protocollo TCP per le comunicazioni normali deve servire a capire che un blocco del protocollo UDP può creare problemi intermittenti alla risoluzione dei nomi e degli indirizzi IP.

177.4.2 Contraffazione dell'origine: IP spoof
Uno dei riferimenti importanti su cui si basa il controllo da parte del firewall è l'indirizzo di origine dei pacchetti. Spesso, chi attacca un sistema altera i pacchetti che invia modificando l'origine, per non essere individuato. Il firewall non è in grado di sapere se l'origine è veritiera o contraffatta.

Per risolvere questo problema con IPv4 si utilizza la gestione dell'instradamento attraverso la procedura denominata «Source Address Verification». Per prima cosa si deve verificare che esista il file virtuale /proc/sys/net/ipv4/conf/all/rp_filter, quindi si possono sovrascrivere tutti i file /proc/sys/net/ipv4/conf/*/rp_filter con il valore uno. In pratica:


--------------------------------------------------------------------------------

if [ -e /proc/sys/net/ipv4/conf/all/rp_filter ]
then
for f in /proc/sys/net/ipv4/conf/*/rp_filter
do
echo 1 > $f
done
fi
--------------------------------------------------------------------------------

In modo più grossolano è possibile eliminare i pacchetti che sono «evidentemente» contraffatti. Per esempio, se l'interfaccia di rete ppp0 è quella che si rivolge verso la rete esterna, si possono bloccare tranquillamente i pacchetti che provengono da questa con l'indicazione di un'origine appartenente a uno degli indirizzi riservati per le reti private.

/sbin/iptables -A INPUT -s 127.0.0.0/8 -i ! lo -j DROP
/sbin/iptables -A FORWARD -s 127.0.0.0/8 -i ! lo -j DROP
/sbin/iptables -A INPUT -s 192.168.0.0/16 -i ppp0 -j DROP
/sbin/iptables -A FORWARD -s 192.168.0.0/16 -i ppp0 -j DROP
/sbin/iptables -A INPUT -s 172.16.0.0/12 -i ppp0 -j DROP
/sbin/iptables -A FORWARD -s 172.16.0.0/12 -i ppp0 -j DROP
/sbin/iptables -A INPUT -s 10.0.0.0/8 -i ppp0 -j DROP
/sbin/iptables -A FORWARD -s 10.0.0.0/8 -i ppp0 -j DROPNel fare questo, tuttavia, bisogna tenere in considerazione che a volte, alcuni fornitori di accesso a Internet utilizzano degli indirizzi riservati alle reti private per le connessioni PPP; generalmente si tratta del gruppo 10.*.*.*.

177.4.3 Esempi
Di seguito vengono mostrati altri esempi che dovrebbero aiutare a comprendere ancora meglio il funzionamento di un firewall realizzato con un sistema GNU/Linux.

/sbin/iptables -A FORWARD -s 224.0.0.0/3 -d 0/0 -j DROPQuesta regola impedisce il transito di tutti quei pacchetti che provengono da un'origine in cui l'indirizzo IP sia composto in modo da avere i primi tre bit a uno. Infatti, 22410 si traduce nel numero binario 111000002, che esclude tutta la classe D e la classe E degli indirizzi IPv4. Segue la visualizzazione della regola attraverso iptables -L FORWARD -n.

target prot opt source destination
DROP all -- 224.0.0.0/3 0.0.0.0/0 /sbin/iptables -A FORWARD -s 224.0.0.0/3 -j DROPQuesto esempio è esattamente identico a quello precedente, perché la destinazione predefinita è proprio quella riferita a qualunque indirizzo.

/sbin/iptables -A FORWARD -p tcp -s 192.168.1.0/24 -d 0/0 23 -j ACCEPTConsente ai pacchetti TCP provenienti dalla rete 192.168.1.* di attraversare il firewall per raggiungere qualunque indirizzo, ma solo alla porta 23. In pratica concede di raggiungere un servizio TELNET. Segue la visualizzazione della regola attraverso iptables -L FORWARD -n.

target prot opt source destination
ACCEPT tcp -- 192.168.1.0/24 0.0.0.0/0 tcp dpt:23 /sbin/iptables -A FORWARD -p tcp -s 0/0 --sport 6000:6009 -d 0/0 -j DROP
/sbin/iptables -A FORWARD -p tcp -s 0/0 -d 0/0 --dport 6000:6009 -j DROPBlocca il transito delle comunicazioni riferite alla gestione remota di applicazioni per X. In questo caso, si presume di poter avere a che fare con sistemi che gestiscono fino a 10 serventi grafici contemporaneamente.

/sbin/iptables -A INPUT -p tcp -s 0/0 --sport 6000:6009 -d 0/0 -j DROP
/sbin/iptables -A OUTPUT -p tcp -s 0/0 -d 0/0 --dport 6000:6009 -j DROPBlocca l'ingresso e l'uscita di comunicazioni riferite alla gestione remota di applicazioni per X. Questo potrebbe essere utile per proteggere un sistema che non si avvale di un firewall o che semplicemente non si fida della rete circostante.

/sbin/iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
/sbin/iptables -A INPUT -m state --state NEW -i ! ppp0 -j ACCEPT
/sbin/iptables -A INPUT -j DROP
/sbin/iptables -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT
/sbin/iptables -A FORWARD -m state --state NEW -i ! ppp0 -j ACCEPT
/sbin/iptables -A FORWARD -j DROPSi consente l'ingresso e il transito di pacchetti relativi a connessioni già esistenti e di pacchetti correlati a connessioni già esistenti; si consente l'instaurazione di connessioni nuove, purché non provengano dall'interfaccia ppp0; si bloccano tutti gli altri pacchetti.

177.5 Contabilizzazione del traffico
Con i kernel Linux 2.4.*, la contabilizzazione del traffico è implicita nel sistema di filtro del firewall: ogni regola che venga inserita in un punto di controllo accumula i propri contatori. In questo senso possono essere opportune anche regole che non hanno l'indicazione di alcun obiettivo, in quanto utili solo per selezionare una parte del traffico ai fini contabili.

Con l'opzione -v si può osservare il valore raggiunto dai vari contatori. Per esempio, disponendo di un'unica regola che cattura tutto il traffico in ingresso,

# iptables -F INPUT

# iptables -A INPUT

il comando

# iptables -L INPUT -v -n

potrebbe generare un rapporto simile a quello seguente:

Chain INPUT (policy ACCEPT 57716 packets, 4848K bytes)
pkts bytes target prot opt in out source destination
57716 4848K all -- * * 0.0.0.0/0 0.0.0.0/0 Si possono notare in particolare le colonne pkts e bytes che si riferiscono rispettivamente al numero di pacchetti IP e alla loro dimensione complessiva in byte. A fianco dei numeri che esprimono queste quantità potrebbero essere aggiunte delle lettere che rappresentano dei multipli: K, M e G. È importante osservare che questi esprimono multipli del sistema di numerazione decimale: 1 000, 1 000 000 e 1 000 000 000.(5)

L'azzeramento dei conteggi si ottiene con l'opzione di comando -Z (--zero), che interviene in tutte le regole dei punti di controllo indicati. Questa può essere utilizzata anche assieme all'opzione -L, in modo da non perdere informazioni.

Esempi
# iptables -L INPUT -v -n

Mostra tutte le informazioni disponibili sulle regole di ingresso, senza tradurre i dati numerici in nome. Tra le altre cose mostra anche i contatori del traffico.

# iptables -Z INPUT

Azzera i conteggi riferiti alle regole di ingresso.

# iptables -L -Z -v -n

Mostra tutte le informazioni disponibili di tutti i punti di controllo (ed eventualmente anche di altri raggruppamenti di regole), compresi i conteggi che vengono azzerati immediatamente dopo.

177.6 Registrazione del traffico
Esiste un obiettivo speciale, denominato LOG, con il quale si ottiene l'annotazione nel registro del sistema sull'intestazione del pacchetto, ogni volta che la regola ne intercetta uno. Tuttavia, in questo caso, quando un pacchetto viene intercettato da una regola del genere, questo viene poi analizzato anche dalle regole successive, per poterlo utilizzare anche in modo differente.


--------------------------------------------------------------------------------

/sbin/iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
/sbin/iptables -A INPUT -m state --state NEW -i ! ppp0 -j ACCEPT
/sbin/iptables -A INPUT -m state --state NEW -i ppp0 -j LOG
/sbin/iptables -A INPUT -j DROP
--------------------------------------------------------------------------------

L'esempio che si vede è abbastanza articolato, per farne comprendere il senso. Lo scopo è quello di annotare nel registro le connessioni in ingresso, attraverso l'interfaccia ppp0, che non siano autorizzabili a seguito di qualche correlazione con connessioni preesistenti.

177.7 Raggruppamenti di regole al di fuori dei punti di controllo standard
Oltre ai punti di controllo normali, è possibile definire delle raccolte di regole aggiuntive, a cui si può fare riferimento quasi come se fossero delle subroutine di un linguaggio di programmazione. Queste raccolte vengono identificate da un nome, al quale si può fare riferimento attraverso altre regole in qualità di obiettivo. In pratica, una regola posta in un punto di controllo può indicare un obiettivo corrispondente al nome di un altro raggruppamento di regole, che viene così a essere incorporato idealmente in quella posizione.

Per comprendere il meccanismo, si supponga di avere creato la raccolta di regole (chain) denominata prova, con una regola all'interno del punto di controllo di ingresso che vi faccia riferimento. Per cominciare, le regole contenute all'interno di prova potrebbero essere:

target prot opt source destination
all -- 192.168.1.0/24 0.0.0.0/0
all -- 0.0.0.0/0 192.168.1.0/24
all -- 127.0.0.1 0.0.0.0/0 Come si può osservare in questo caso, si tratta di regole che servono solo alla contabilizzazione del traffico, dal momento che non sono stati indicati degli obiettivi.

Le regole di ingresso potrebbero essere quelle seguenti:

target prot opt source destination
...
prova tcp -- 0.0.0.0/0 0.0.0.0/0
...Si può osservare una regola il cui scopo è quello di individuare tutto il traffico TCP. Dal momento che l'obiettivo di questa è il raggruppamento prova, i pacchetti che rientrano nella selezione di questa regola vengono scomposti ulteriormente attraverso le regole del raggruppamento prova. I pacchetti che non vengono «catturati» da alcuna regola del raggruppamento prova tornano a essere presi in considerazione dalle regole successive nel punto di controllo di ingresso.

La creazione di un raggruppamento di regole si ottiene con l'opzione di comando -N (--new-chain) e la sua eliminazione con -X (--delete-chain). Per esempio, il comando

# iptables -N prova

serve a creare il raggruppamento prova a cui si accennava in precedenza. L'inserimento di regole avviene nel modo normale; per continuare a seguire gli esempi fatti, i comandi dovrebbero essere i seguenti:

# iptables -A prova -s 192.168.1.0/24

# iptables -A prova -d 192.168.1.0/24

# iptables -A prova -s 127.0.0.1

Così, l'inserimento della regola nel punto di controllo di ingresso che fa riferimento a questo raggruppamento, come mostrato dagli esempi in precedenza, si indica semplicemente con il comando seguente:

# iptables -A INPUT -p tcp -j prova

L'eliminazione di un raggruppamento di regole è ammissibile solo quando questo è vuoto e quando non esistono più riferimenti da parte di altre regole nei punti di controllo normali.

# iptables -D INPUT -p tcp -j prova

# iptables -F prova

# iptables -X prova

I comandi mostrati sopra servono rispettivamente a eliminare la regola di ingresso che faceva riferimento al raggruppamento prova, a svuotare il raggruppamento e infine a eliminarlo.

177.8 Tunnel IPv6 in IPv4
Quando si realizza un tunnel IPv6, come nel caso di 6to4, è necessario abilitare il traffico di questi pacchetti, che sono di tipo IPv4. Per la precisione, questi pacchetti vengono individuati da iptables come appartenenti al protocollo ipv6. Per esempio, per consentire l'ingresso e l'uscita di questi pacchetti, si possono usare i due comandi seguenti:

# iptables -t filter -A INPUT -p ipv6 -s 0/0 -d 0/0 -j ACCEPT

# iptables -t filter -A OUTPUT -p ipv6 -s 0/0 -d 0/0 -j ACCEPT

Naturalmente, volendo essere più precisi si può aggiungere l'indicazione dell'interfaccia coinvolta.

177.9 Riferimenti
Rusty Russell, Linux 2.4 packet filtering HOWTO

<http://www.linux.org/docs/ldp/howto/HOWTO-INDEX/howtos.html>

Oskar Andreasson, IPTables Tutorial

<http://iptables-tutorial.haringstad.com/>

Terry Dawson, Linux NET-3-HOWTO, Linux Networking

<http://www.linux.org/docs/ldp/howto/HOWTO-INDEX/howtos.html>

Mark Grennan, Firewalling and Proxy Server HOWTO

<http://www.linux.org/docs/ldp/howto/HOWTO-INDEX/howtos.html>

Peter Bieringer, Linux IPv6 HOWTO

<http://www.linux.org/docs/ldp/howto/HOWTO-INDEX/howtos.html>

Copyright (c) 2000-3000 by Ing. Eduardo Palena - Napolifirewall.com