25.3.1 Packet filtering
Un firewall che effettua il packet filtering (filtraggio dei pacchetti) gestisce i pacchetti che lo
attraversano in base ad opportune regole che si riferiscono ai protocolli di più basso livello del
modello OSI, dal livello fisico fino a quello di trasporto.
Il meccanismo di firewalling sui sistemi GNU/Linux (dal kernel 2.4 in poi) è
Netfilter.
Si tratta di un packet filter dotato di stateful inspection. Il packet filtering è implementato nel
kernel, ma la parte relativa al filtraggio avviene tramite dei moduli: in questo modo il sistema
di filtraggio risulta dinamicamente estensibile.
Poiché il meccanismo di firewalling è un’attività del kernel, per il suo funzionamento è
necessario che il kernel sia stato opportunamente compilato e accompagnato dagli eventuali
moduli necessari.
Per default un sistema GNU/Linux non permette ai pacchetti di transitare da
un’interfaccia di rete ad un’altra, cioè non fa da router (ovvero non permette il
forwarding dei pacchetti), ma questa caratteristica può essere abilitata facendo contenere
‘1’ al file /proc/sys/net/ipv4/ip_forward. Ciò può essere fatto con il comando
seguente
# echo "1" > /proc/sys/net/ipv4/ip_forward
Questo va bene per IPv4, ma per la versione IPv6 è necessario inserire il valore ‘1’ nel file
/proc/sys/net/ipv6/conf/all/forwarding, che, analogamente a quanto visto prima, può
essere fatto con il comando seguente
# echo "1" > /proc/sys/net/ipv6/conf/all/forwarding
Poiché tale impostazione è relativa al filesystem virtuale /proc, non viene memorizzata
sulla memoria i massa, pertanto se si desidera che tale impostazione sia attivata ad ogni avvio
del sistema, è necessario impartire tale comando ogni volta che il sistema viene riavviato
(magari per mezzo di un apposito script).
I pacchetti che transitano su Netfilter vengono esaminati, secondo un insieme di regole
(rule) raggruppate in chain (catene o punti di controllo) assegnate a tabelle (table). Le
regole determinano la politica di filtraggio dei pacchetti.
Ogni regola specifica una condizione ed un target (obiettivo), cioè l’azione che Netfilter
deve intraprendere sul pacchetto in transito, quando questo soddisfa la condizione indicata
dalla regola considerata.
Un pacchetto può essere destinato alla macchina che funge da firewall o ad un’altra
macchina collegata in rete a quest’ultima. L’instradamento corretto del pacchetto è compito
del meccanismo di routing (v. cap. 16).
Il funzionamento di Netfilter si basa sull’insieme di tabelle e chain illustrato in fig. 25.2; le
tabelle e le chain predefinite sono elencate rispettivamente in tab. 25.1 e tab. 25.2. Si possono
conunque definire altre chain per gestire in maniera più modulare le politiche di sicurezza,
ovvero le regole di filtraggio dei pacchetti.
| Tabella 25.1: | Tabelle utilizzate da Netfilter. |
|
| Tabella 25.2: | Chain predefinite di Netfilter. |
|
La tabella mangle supporta le chain INPUT, FORWARD e POSTROUTING
dal kernel 2.4.18.
|
Netfilter è un meccanismo di firewalling dotato di stateful inspection dei pacchetti, reso
possibile dal connection tracking, ovvero un meccanismo con il quale Netfilter tiene traccia
dello stato delle connessioni. Tale ruolo è implementato da Conntrack che risiede nel kernel
(oppure può essere caricato come modulo ip_conntrack) e consente di gestire gli stati
elencati in tab. 25.3.
| Tabella 25.3: | Stati su cui si basa Conntrack. |
|
Poiché il conection tracking non funziona a dovere nel caso di frammentazione
dei pacchetti, Conntrack, se attivato, provvede automaticamente a disabilitare la
deframmentazione dei pacchetti.
La gestione del connection tracking viene effettuata nelle chain PREROUTING e
OUTPUT della tabella nat.
Lo stato delle connessioni è consultabile attraverso il file /proc/net/ip_conntrack. Il suo
contenuto ha la seguente sintassi
protocol proto_num exp_time status details
dove
-
protocol è il protocollo di più alto livello (massimo livello di trasporto) riconosciuto del
pacchetto;
-
proto_num è il numero identificativo del protocollo;
-
exp_time è il numero di secondi di “vita” rimanenti per l’annotazione (timeout). Tale
valore viene decrementato automaticamente. I tempi di default sono quelli riportati
in tab. 25.4.
| Tabella 25.4: | Valori di default per exp_time. |
|
Tali valori sono comunque impostabili attraverso i file /proc/sys/net/ipv4/
netfilter/ip_ct_*. I valori sono espressi in jiffies (centesimi di secondo), quindi il
valore 3000 significa 30 secondi. In particolare, il valore contenuto nel file
/proc/sys/net/ipv4/netfilter/ip_ct_generic_timeout (che per default
corrisponde a 10 minuti) è il valore utilizzato per le connessioni relative a protocolli che
Conntrack non comprende;
-
status è lo stato attuale della connessione relativa (es. SYN_SENT);
-
details riporta i dettagli della comunicazione (es. indirizzo IP e porta del mittente ed indirizzo
IP e porta del destinatario) sia per i messaggi di richiesta che per quelli di ripsosta (i
messaggi di risposta avranno i dati relativi al mittente scambiati con quellli relativi al
destinatario);
Nel caso di PAT implicito, le porte del mittente sono divise in tre classi: 0 - 511, 512 -
1023, 1024 - 65535. Una porta che appartiene ad una di tali classe sarà sempre mappata in
un’altra appartenente alla stessa classe.
Le annotazioni vengono rimosse quando scade il loro exp_time, tranne quelle marcate come
[ASSURED]. Queste vengono eliminate soltanto quando viene raggiunto il massimo numero di
connessioni tracciabili. Tale valore dipende dalla quantità di memoria centrale presente
sulla macchina (per macchine con 256 MB di RAM è 16376) ed è contenuto nel file
/proc/sys/net/ipv4/ip_conntrack_max.
Netfilter è gestito con il comando iptables (man page
iptables(8)).
____________________________________________________________________
Comando: iptables
Path: /sbin/iptables
SINTASSI
# iptables [-h | -v | {-t | --table} table] [command] [option] [match] [target]
DESCRIPTION
-
-h visualizza un aiuto sommario di iptables;
-
-v visualizza la versione di iptables;
-
-t table indica la tabella di riferimento filter, nat o mangle (se non viene
specificato, viene considerata la tabella filter);
-
command indica il comando da far eseguire a iptables. Può assumere i seguenti
valori:
-
{-A | --append} chain rule
aggiunge una o più regole (rule) alla chain;
-
{-D | --delete} chain rule
elimina una o più regole (rule) dalla chain (rule può essere in forma di
regola o semplicemente il numero relativo alla posizione della regola
da eliminare all’interno della chain - la prima regola è la numero 1);
-
{-I | --insert} chain [rulenum] rule
inserisce una o più regole (rule) nella chain con il numero di ordine
rulenum (se non viene specificato rulenum, la regola viene inserita
come prima regola della chain);
-
{-R | --replace} chain rulenum rule
sostituisce la regola alla posizione (rulenum) nella chain con quella
specificata da rule;
-
{-L | --list} [chain]
elenca le regole contenute nella chain. Se chain non è specificata,
vengono elencate tutte le chain;
-
{-F | --flush} [chain]
elimina tutte le regole contenute nella chain. Se chain non è
specificata, vengono eliminate tutte le chain relative alla tabella
considerata;
-
{-Z | --zero} [chain]
azzera i contatori dei pacchetti e dei byte relativi a tutte le chain;
-
{-N | --new-chain} chain
crea una nuova chain con il nome specificato da chain;
-
{-X | --delete-chain} [chain]
elimina la chain specificata da chain (la chain deve essere vuota e non
può essere una di quelle predefinite). Se chain non viene specificato,
vengono eliminate tutte le chain relative alla tabella considerata;
-
{-P | --policy} [chain] [target]
imposta la politica di default per la chain specificata da chain
relativamente all’obiettivo target (soltanto le chain predefinite hanno
una politica di default);
-
{-E | --rename-chain} old-chain new-chain
rinomina la chain old-chain in new-chain (non funziona con le chain
predefinite).
-
option indica l’opzione di funzionamento di iptables. Può assumere i seguenti
valori:
-
-v | --verbose
(utilizzato con i comandi -L, -A, -I, -D e -R) indica di visualizzare
un output più verboso;
-
-x | --exact
(utilizzato con il comando -L) indica di visualizzare il numero esatto
relativemente ai contatori senza le lettere K, M e G (le lettere K, M e
G relative ai contatori si riferiscono rispettivamente a kilo-, mega- e
giga- del sistema internazionale, cioè sono moltiplicatori di 103, 106
e 109);
-
-n | --numeric
(utilizzato con il comando -L) indica di visualizzare valori numerici
relativamente a indirizzi e porte invece di usare i nomi degli host e
delle applicazioni;
-
--line-numbers
(utilizzato con il comando -L) indica di visualizzare i numeri relativi
alle regole;
-
{-c | --set-counters} packet-counter byte-counter
(utilizzato con i comandi -I, -A e -R) imposta i contatori al valore
specificato da packet-counter e byte-counter;
-
--modprobe
indica il modulo da utilizzare per aggiungere al kernel;
-
match specifica la condizione da verificare. Le condizioni possono essere dalle più
generali a quelle specifiche per i vari protocolli TCP, UDP, ICMP, a
quelle particolari relative allo stato, al proprietario ed ai limiti. Netfilter
effettuerà i controlli sulle parti del pacchetto coinvolte dalle condizioni
specificate.
-
{-p |--protocol} [!] protocol
è verificata dai pacchetti relativi al protocollo protocol ch è
un elenco di nomi di protocolli (o i relativi valori numerici)
contenuti nel file /etc/protocols separati dal carattere ‘,’. Può
contenere anche il valore all che si riferisce a qualunque protocollo
(v. tab. 25.5). Il simbolo ‘!’ indica a Netfilter di considerare la
negazione della condizione specificata (es. --protocol ! tcp indica
qualunque protocollo diverso dal TCP);
| Tabella 25.5: | Protocolli utilizzabili da netfilter. |
|
-
{-s |--source | --src} [!] address[/mask]
è verificata dai pacchetti il cui indirizzo IP del mittente (sorgente) è
specificato da address[/mask]. Può essere sia l’indirizzo di un’interfaccia
specifica che quello di una rete (con la relativa mask che può essere
specificata con un numero, che indica il numero di bit di cui si compone la
parte rete dell’indirizzo, o in forma dotted decimal). Il simbolo ‘!’
indica a Netfilter di considerare la negazione della condizione
specificata;
-
{-d |--destination | --dst} [!] address[/mask]
è verificata dai pacchetti il cui indirizzo IP del destinatario è specificato da
address[/mask]. Può essere sia l’indirizzo di un’interfaccia specifica che
quello di una rete (con la relativa mask che può essere specificata con un
numero, che indica il numero di bit di cui si compone la parte
rete dell’indirizzo, o in forma dotted decimal). Il simbolo ‘!’
indica a Netfilter di considerare la negazione della condizione
specificata;
-
{-i |--in-interface} [!] name
è verificata dai pacchetti che arrivano a Netfilter attraverso
l’interfaccia di rete specificata da name (questo match è valido
soltanto per le chain PREROUTING, INPUT e FORWARD). Se
name termina con il simbolo ‘+’, è verificata dai pacchetti che
arrivano attraverso tutte le interfacce di rete il cui nome inizia
con la parte di name che precede il simbolo ‘+’. Il simbolo ‘!’
indica a Netfilter di considerare la negazione della condizione
specificata;
-
{-o |--out-interface} [!] name
è verificata dai pacchetti che devono essere inviati da Netfilter attraverso
l’interfaccia di rete specificata da name (questo match è valido soltanto per
le chain FORWARD, OUTPUT e POSTROUTING). Se name
termina con il simbolo ‘+’, è verificata dai pacchetti che devono
uscire attravarso tutte le interfacce di rete il cui nome inizia
con la parte di name che precede il simbolo ‘+’. Il simbolo ‘!’
indica a Netfilter di considerare la negazione della condizione
specificata;
-
[!] {-f |--fragment}
è verificata dai pacchetti che sono frammenti di pacchetti IP successivi al
primo (un frammento o un pacchetto ICMP non hanno la specificazione
dell’indirizzo IP del mittente e del destinatario). Il simbolo ‘!’
indica a Netfilter che la condizione è applicabile soltanto al
primo frammento dei pachetti frammentati o a pacchetti non
frammentati;
-
{--source-port |--sport} [!] port
(applicabile soltanto ai protocolli di trasporto come TCP e UDP) è
verificata dai pacchetti la cui porta del mittente (sorgente) è specificata da
port. Questo può specificare anche un intervallo di porte con la sintassi
from_port:to_port in cui from_port indica il numero della porta che
rappresenta l’estremo inferiore dell’intervallo e to_port indica il numero di
quella che rappresenta l’estremo superiore (nel caso in cui vengano
omessi, al posto di from_port viene considerato il valore 0 ed al
posto di to_port viene considerato il valore 65535). Nel caso
in cui from_port sia maggiore di to_port, i due valori vengono
automaticamente scambiati. Le porte possono essere specificate sia con un
numero che con una stringa, contenuta nel file /etc/services, che
rappresenta l’applicazione che risponde su tale porta. Il simbolo ‘!’
indica a Netfilter di considerare la negazione della condizione
specificata;
-
{--destination-port |--dport} [!] port
(applicabile soltanto ai protocolli di trasporto come TCP e UDP) è
verificata dai pacchetti a cui porta del destinatario è specificata da port.
Questo può specificare anche un intervallo di porte con la sintassi
from_port:to_port in cui from_port indica il numero della porta che
rappresenta l’estremo inferiore dell’intervallo e to_port indica il numero di
quella che rappresenta l’estremo superiore (nel caso in cui vengano
omessi, al posto di from_port viene considerato il valore 0 ed al
posto di to_port viene considerato il valore 65535). Nel caso
in cui from_port sia maggiore di to_port, i due valori vengono
automaticamente scambiati. Le porte possono essere specificate sia con un
numero che con una stringa, contenuta nel file /etc/services, che
rappresenta l’applicazione che risponde su tale porta. Il simbolo ‘!’
indica a Netfilter di considerare la negazione della condizione
specificata;
-
--tcp-flags [!] mask comp
(applicabile soltanto al protocollo TCP) è verificata dai pacchetti TCP i cui
flag specificati da mask, sono impostati secondo quanto specificato da
comp. I parametri mask e comp sono elenchi di stringhe separate dal
carattere ‘,’ (SYN, ACK, FIN, RST, URG, PSH, ALL, NONE). Ad esempio
--tcp-flags SYN,ACK,FIN SYN si riferisce ai pacchetti TCP che hanno il
flag SYN impostato ed i flag ACK e FIN non impostato. Il simbolo ‘!’
indica a Netfilter di considerare la negazione della condizione
specificata;
-
[!] --syn
(applicabile soltanto al protocollo TCP) è verificata dai pacchetti con il flag
SYN impostato ed i flag ACK e FIN non impostato. Tali particolari
pacchetti sono utilizzati dal protocollo TCP per instaurare una connessione
(comunicazione). È equivalente a --tcp-flags SYN,RST,ACK SYN. Il
simbolo ‘!’ indica a Netfilter di considerare la negazione della condizione
specificata;
-
--tcp-option [!] number
(applicabile soltanto al protocollo TCP) è verificata dai pacchetti TCP il
cui campo Options ha il valore specificato da number. Il simbolo ‘!’
indica a Netfilter di considerare la negazione della condizione
specificata;
-
--mss value
(applicabile soltanto al protocollo TCP) è verificata dai pacchetti TCP
(SYN o SYN/ACK) il cui campo MSS contiene il valore specificato da
value (value può essere anche un intervallo di valori della forma
[min-value]:[max-value]);
-
--icmp-type [!] type
(applicabile soltanto al protocollo ICMP) è verificata dai pacchetti ICMP il
cui tipo è specificato da type. Questo può essere un valore numerico o una
stringa che identifica il tipo di pacchetto ICMP secondo quanto riportato
dal comando iptables -p icmp -h (v. tab. ??). Il simbolo ‘!’
indica a Netfilter di considerare la negazione della condizione
specificata;
Esiste la possibilità di specificare delle indicando un match esplicito con la sintassi
{-m | --match} explicit-match
dove explicit-match indica il tipo di match esplicito.
Le seguenti opzioni sono specificabili soltanto con explicit-match uguale a
mac
-
--mac-source [!] address
(applicabile soltanto a pacchetti che si basano su Ethernet
relativamente alle chain PREROUTNG, INPUT o FORWARD) è
verificata dai pacchetti il cui indirizzo MAC del mittente è specificato
da address nella forma XX:XX:XX:XX:XX:XX. Il simbolo ‘!’
indica a Netfilter di considerare la negazione della condizione
specificata;
Le seguenti opzioni sono specificabili soltanto con explicit-match uguale a
limit
-
--limit rate
indica il massimo numero di pacchetti che verificano la condizione
specificata all’interno di un determinato periodo temporale. Il valore
è specificato da rate che è espresso nella forma value[/unit] dove value
è un valore numerico e unit è una unità temporale (second, minute,
hour, day) che se non specificata è minute. Il valore di default è
3/hour;
-
--limit-burst number
indica il massimo numero di pacchetti consecutivi (number) che
soddisfano la condizione specificata nell’unità di tempo impostata
con --limit rate. Il valore di default di number è 5;
Le seguenti opzioni sono specificabili soltanto con explicit-match uguale a
mark
-
--mark value[/mask]
è verificata dai pacchetti il cui campo mark contiene il valore value
(tutti i pacchetti che attraversano Netfilter hanno asociato un campo
mark che contiene un valore numerico intero senza segno - da 0 a
4294967296). Se mask è specificato, viene effettuato un AND tra value
e mask prima di effettuare il confronto;
Le seguenti opzioni sono specificabili soltanto con explicit-match uguale a
multiport
-
{--source-ports |--sports} port[,port[,port...]]
(applicabile soltanto ai protocolli di trasporto come TCP e UDP)
indica l’elenco di porte del mittente (sorgente) specificato da
port[,port[,port...]].
-
{--destination-ports |--dports} port[,port[,port...]]
(applicabile soltanto ai protocolli di trasporto come TCP e
UDP) indica l’elenco di porte del destinatario specificato da
port[,port[,port...]].
-
--ports port[,port[,port...]]
(applicabile soltanto ai protocolli di trasporto come TCP e UDP) è
verificata se le porte del mittente e del destinatario sono le stesse e
se cadono nell’elenco specificato da port[,port[,port...]].
Le seguenti opzioni sono specificabili soltanto con explicit-match uguale a
owner
-
--uid-owner userid
è verificata dai pacchetti che sono stati creati da un processo con
l’effective user id specificato da userid;
-
--gid-owner groupid
è verificata dai pacchetti che sono stati creati da un processo con
l’effective group id specificato da groupid;
-
--pid-owner processid
è verificata dai pacchetti che sono stati creati da un processo con il
process id specificato da processid;
-
--sid-owner sessionid
è verificata dai pacchetti che sono stati creati da un processo con il
session id specificato da sessionid;
-
--cmd-owner name
è verificata dai pacchetti che sono stati creati da un processo il cui
comando è specificato da name;
Le seguenti opzioni sono specificabili soltanto con explicit-match uguale a
state
-
[!] --state state
è verificata dai pacchetti che sono negli stati specificati da state
(un elenco di stringhe separate dal carattere ‘,’ relative agli stati
del Conntrack, v. tab. 25.3). Il simbolo ‘!’ indica a Netfilter di
considerare la negazione della condizione specificata;
Le seguenti opzioni sono specificabili soltanto con explicit-match uguale a
tos
-
--tos tos
è verificata dai pacchetti il cui campo TOS (Type Of Service)
dell’header dell’IP datagram contiene il valore specificato da tos, che
può essere anche una stringa secondo quanto riportato da iptables
-m tos -h (v. tab. 25.6);
| Tabella 25.6: | Valori per filtro sul campo TOS. |
|
Le seguenti opzioni sono specificabili soltanto con explicit-match uguale a
ah
-
--ahspi [!] spi
è verificata dai pacchetti IPSec il cuoi header AH contiene il valore
specificato da spi (che può specificare un unico valore o un intervallo
di valori secondo la sintassi min_spi:max_spi). Il simbolo ‘!’ indica a
Netfilter di considerare la negazione della condizione specificata;
Le seguenti opzioni sono specificabili soltanto con explicit-match uguale a
esp
-
--espspi [!] spi
è verificata dai pacchetti IPSec il cuoi header AH contiene il valore
specificato da spi (che può specificare un unico valore o un intervallo
di valori secondo la sintassi min_spi:max_spi). Il simbolo ‘!’ indica a
Netfilter di considerare la negazione della condizione;
Le seguenti opzioni sono specificabili soltanto con explicit-match uguale a
length
-
--length length
è verificata dai pacchetti che hanno una lunghezza uguale al valore
specificato da length (che può specificare un unico valore o un
intervallo di valori secondo la sintassi min_length:max_length)
Le seguenti opzioni sono specificabili soltanto con explicit-match uguale a
ttl
-
--ttl ttl
è verificata dai pacchetti il cui campo TTL (Time To Live)
dell’header IP contiene il valore specificato da ttl;
-
target indica l’azione da intraprendere nel caso in cui il pacchetto verifichi la
condizione indicata da match. Può essere specificato per mezzo della sintassi
seguente
{-j | --jump} action
dove action specifica l’azione da intraprendere, come descritto di seguito, o il nome
di una chain (appartenente alla tabella corrente) da analizzare. Nel caso in cui
venga specificato il nome di una chain (chain_B), Netfilter prenderà in
considerazione tutte le regole presenti in tale chain per controllare il pacchetto ed
una volta scorso l’elenco di tali regole, viene ripreso il controllo dalla regola (nella
chain corrente) successiva a quella che specificava la chain_B come target
(v. fig. 25.3).
Le action possibili sono
-
ACCEPT indica di accettare il pacchetto. Per tale pacchetto non saranno
controllate ulteriori condizioni specificate in altre chain della tabella
considerata (le condizioni contenute in altre chain appartenenti ad
altre tabelle vengono comunque applicate al pacchetto).
-
DNAT (Destination Network Address Translation) indica di modificare
l’indirizzo IP del destinatario del pacchetto. Questa action è
disponibile soltanto per le chain PREROUTING e OUTPUT della
tabella nat (e per le chain chiamate da queste) e le chain che
contengono tale action non possono essere chiamate da altre chain
che non siano queste.
Con -j DNAT possono essere utilizzate le seguenti ulteriori opzioni
-
--to-destination ipaddr[:port]
indica uno specifico indirizzo IP con cui sostituire quello del
destinatario (o un intervallo di indirizzi IP specificato con
la sintassi first_ipaddr-last_ipaddr). Nel caso di un intervallo
di indirizzi IP, Netfilter provvede ad assegnare al pacchetto
uno di essi scelto a caso, il che permette la gestione del
load balancing di più macchine. Per i i protocolli a livello
di trasporto, come TCP o UDP, può essere specificata
anche la porta (o un’intervallo di porte secondo la sintassi
first_port-last_port) con la quale sostituire il valore della
porta del destinatario;
-
DROP indica di scartare il pacchetto senza inviare nessun messaggio di ritorno al
mittente (questo può avere l’effetto di lasciare “appeso” il socket sul
sistema che ha inviato il pacchetto).
-
LOG indica di scrivere nel system log (v. cap. 5) un messaggio che riporta
alcune informazioni relative al pacchetto. L’esame del pacchetto continua
comunque con le regole successive contenute nelle chain che questo deve
attraversare.
Con -j LOG possono essere utilizzate le seguenti ulteriori opzioni
-
--log-level level
indica il livello di verbosità del log, specificato da level
(v. man page syslog.conf(5));
-
--log-prefix prefix
indica di inserire nel messaggio di log una stringa (prefix) da
premettere alle informazioni relative al pacchetto;
-
--log-tcp-sequence prefix
indica di inserire nel messaggio di log i numeri di sequenza
del TCP;
-
--log-tcp-options
indica di inserire nel messaggio di log le options dall’header
TCP;
-
--log-ip-options
indica di inserire nel messaggio di log le options dall’header
IP;
-
MARK indica di impostare il campo mark che Netfilter associa ad ogni
pacchetto.
Questa action è disponibile soltanto per la tabella mangle.
Con -j MARK possono essere utilizzate le seguenti ulteriori opzioni
-
--set-mark mark
indica il valore (mark) con cui impostare il campo mark;
-
MASQUERADE
indica di sostituire l’indirizzo IP del mittente del pacchetto con quello
dell’interfaccia attraverso la quale vengono inviati (come SNAT) ma la
regola non viene considerata quando l’interfaccia non esiste (la
connessione non è attiva - connessioni dialup). Questa action è
disponibile soltanto per la chain POSTROUTING della tabella
nat.
Con -j MASQUERADE possono essere utilizzate le seguenti ulteriori
opzioni
-
--to-ports port
indica il valore della porta (o dell’intervallo di porte con
la sintassi first_port-last_port) da utilizzare per sostituire
la porta del mittente, secondo quanto specificato da port
(soltanto per i protocolli a livello di trasporto come TCP o
UDP);
-
MIRROR indica di invertire l’indirizzo IP del mittente con quello del destinatario e
ritrasmettere il pacchetto.
Questa action è disponibile soltanto per le chain PREROUTING, INPUT e
FORWARD (e per le chain chiamate da queste).
-
QUEUE indica di accodare i pacchetti verso applicazioni che girano in user-space
estranee a Netfilter come quelle che si occupano di gestione centralizzata
degli accessi o di filtri tipo proxy. Lo stato della coda è gestito tramite il file
/proc/net/ip_queue, mentre la sua lunghezza massima è memorizzata nel
file /proc/sys/net/ipv4/ip_queue_maxlen (il suo valore di default è
1024). La documentazione relativa si trova in “Netfilter Hacking
HOW-TO”.
-
REDIRECT
indica di modificare l’indirizzo IP del destinatario in modo da risultare il
destinatario del pacchetto (l’indirizzo IP del destinatario dei pacchetti
entranti viene sostituito con quello dell’interfaccia di rete attraverso la
quale sono stati ricevuti, mentre a quelli generati localmente, viene
sostituito con 127.0.0.1).
Questa action è disponibile soltanto per le chain PREROUTING e
OUTPUT (e per le chain chiamate da queste).
Con -j REDIRECT possono essere utilizzate le seguenti ulteriori
opzioni
-
--to-ports port
indica la porta (o l’intervallo di porte con la sintassi
first_port-last_port) con cui impostare la porta del
destinatario del pacchetto (soltanto per i protocolli a livello
di trasporto come TCP o UDP);
-
REJECT indica di scartare il pachetto inviando al mittente un messaggio di
errore.
Questa action è disponibile soltanto per le chain INPUT, FORWARD e
OUTPUT (e per le chain chiamate da queste) e le chain contenenti tali
action non possono essere chiamate da altre chain che non siano
queste.
Con -j REJECT possono essere utilizzate le seguenti ulteriori
opzioni
-
--reject-with type
indica il tipo (type) di messaggio di errore da inviare al
mittente. Questo può essere uno dei messaggi ICMP riportati
in tab. 25.7;
| Tabella 25.7: | I possibili messaggi di errore da ritornare
al mittente. |
|
-
--tcp-reset
indica di inviare al mittente il messaggio di errore costituito da un
pacchetto TCP RST (è valido soltanto per pacchetti del protocollo
TCP);
-
RETURN indica di non considerare la chain corrente per il controllo delle
condizioni sul pacchetto. Se la regola che contiene tale action è una
subchain (cioè una chain specificata come action di una regola
contenuta in un’altra chain) Netfilter ritornerà a prendere in
considerazione la chain principale (da cui quella corrente è stata
chiamata). Se la regola che contiene tale action è una chain
principale, le regole seguenti non vengono considerate e Netfilter
applicherà la regola relativa alla policy di default per quella
chain.
-
SNAT (Source Network Address Translation) indica di modificare l’indirizzo IP del
mittente del pacchetto. Questa action è disponibile soltanto per la chain
POSTROUTING della tabella nat (e per le chain chiamate da queste) e le
chain che contengono tale action non possono essere chiamate da altre chain
che non siano queste.
Con -j SNAT possono essere utilizzate le seguenti ulteriori opzioni
-
--to-source ipaddr[:port]
indica uno specifico indirizzo IP con cui sostituire quello del
mittente (o un intervallo di indirizzi IP specificato con la
sintassi first_ipaddr-last_ipaddr). Per i i protocolli a livello
di trasporto, come TCP o UDP, può essere specificata
anche la porta (o un’intervallo di porte secondo la sintassi
first_port-last_port) con la quale sostituire il valore della
porta del mittente;
-
TCPMSS indica di modificare il campo MSS dei pacchetti TCP SYN che
imposta la massima dimensione dei pacchetti che transitano sulla
rete (usualmente è impostato a MTU - 40). Questa action è
utile per limitare le dimensioni dei pacchetti inviati su Internet
attraverso dei server che scartano i pachetti ICMP Fragmentation
Needed.
Questa action è disponibile soltanto per pacchetti TCP.
Con -j TCPMSS può essere utilizzata una delle seguenti ulteriori
opzioni
-
--set-mss value
indica di impostare il campo MSS del pacchetto TCP con il
valore specificato da value;
-
--clamp-mss-to-pmtu
indica di impostare il campo MSS del pacchetto TCP con il
valore MTU - 40;
-
TOS indica di modificare il campo TOS (Type Of Service) del pacchetto IP per
specificare la politica di routing relativa al pacchetto stesso, ance se tale
campo non è sempre considerato (soprattutto in maniera corretta) dai
router.
Questa action è disponibile soltanto per la tabella mangle.
Con -j TOS possono essere utilizzate le seguenti ulteriori opzioni
-
--set-tos tos
indica di impostare il campo TOS del pacchetto con il valore
indicato da tos, che può essere anche una stringa secondo
quanto riportato da iptables -j TOS -h (v. tab. 25.6);
-
TTL indica di impostare il valore del campo TTL (Time To Live)
del pacchetto IP. Questo può essere utile per imopstare tutti
i pacchetti che vengono inviati su Internet da un NAT, con
lo stesso valore (in modo tale che l’ISP non possa accorgersi
facilmente che sono pacchetti relativi a più macchine: potrebbe
non gradire che più macchine utiilzzano la stessa connessione a
Internet);
Questa action è disponibile soltanto per la tabella mangle.
Con -j TTL possono essere utilizzate le seguenti ulteriori opzioni
-
--ttl-set ttl
indica di impostare il campo TTL del pacchetto con il valore
indicato da ttl;
-
--ttl-dec ttl
indica di decrementare il campo TTL del pacchetto con il
valore indicato da ttl;
-
--ttl-inc ttl
indica di incrementare il campo TTL del pacchetto con il
valore indicato da ttl;
-
ULOG indica di registrare un messaggio di log con applicazioni che girano in
user-space, inviando il messaggio stesso in multicast tramite un netlink
socket. Le applicazioni che devono gestire il log possono essere agganciate ai
netlink group relativi all’indirizzo multicast utilizzato, per ricevere il
pacchetto.
Con -j ULOG possono essere utilizzate le seguenti ulteriori opzioni
-
--ulog-nlgroup nlgroup
indica il netlink group al quale il pacchetto è inviato, secondo
quanto specificato da nlgroup, che può assumere un valore è
compreso tra 1 e 32 (il valore di default è 1);
-
--ulog-prefix prefix
indica la stringa da anteporre al messaggio da inserire nel
log (massimo 32 caratteri);
-
--ulog-cprange size
indica il numero di byte da copiare nello user-space, secondo
quanto specificato da size (il valore 0 indica di copiare l’intero
pacchetto - valore di default);
-
--ulog-qthreshold size
indica il numero di pacchetti da accodare in kernel-space
prima di inviarli come messaggio multipart del netlink,
secondo quanto specificato da size (per default è 1);
____________________________________________________________________
Nel caso di firewall stateless è opportuno aprire in ingresso le porte al di sopra della 1024
in modo da poter ricevere i pacchetti di risposta ad eventuali pacchetti di richiesta che escono
dal firewall. Questo non è necessario nel caso di firewall stateful in quanto si può permettere
l’ingresso di pacchetti con porta di destinazione maggiore di 1024 soltanto per i pacchetti di
risposta, senza essere obbligati ad aprire in ingresso tutte le porte sopra la 1024 a tutti i
pacchetti.
[da completare ...]
La configurazione del firewall impostata per mezzo di iptables non viene memorizzata sul
filesystem e quindi viene perduta al successivo riavvio del sistema. È comunque possibile
creare uno script in cui inserire i comandi necessari alla configurazione desiderata
del firewall in modo da lanciarlo in esecuzione durante la procedura di avvio del
sistema.
Si può optare anche per il salvataggio delle impostazioni del firewall per mezzo degli
appositi comandi iptables-save (man page iptables-save(8)) e iptables-restore (man
page iptables-restore(8)) che servono, rispettivamente, per salvare le impostazioni correnti
del firewall e per ripristinare il firewall con le informazioni precedentemente salvate. Le
impostazioni vengono gestite in un formato leggermente diverso da quello utilizzato dalla linea
di comando con iptables.
L’utilizzo di iptables-save e iptables-restore velocizza considerabilmente il
salvataggio ed il caricamento di un consistente insieme di regole poiché il passaggio tra
user-space e kernel-space (dove vanno a finire le regole) viene effettuato una volta soltanto e
non regola per regola come avverrebbe utilizzando uno script con varie chiamate a
iptables.
____________________________________________________________________
Comando: iptables-save
Path: /sbin/iptables-save
SINTASSI
# iptables-save [-c] [-t table]
DESCRIZIONE
-
-c indica a iptables-save di salvare anche i contatori;
-
-t table indica la tabella della quale effettuare il salvataggio. Se non è specificato,
vengono salvate tutte le tabelle;
____________________________________________________________________________________________________________________
Per default iptables-save visualizza l’output sullo standard output (terminale). Per
salvare le impostazioni su un file si può utilizzare la redirezione, come nell’esempio
seguente
# iptables-save -c > iptables.conf
che salva le impostazioni relative a tutte le tabelle ed i contatori nel file iptables.conf.
Di seguito è riportato un esempio dell’output di iptables-save.
# Generated by iptables-save v1.2.6a on Wed Apr 24 10:19:55 2002
*filter
:INPUT DROP [1:229]
:FORWARD DROP [0:0]
:OUTPUT DROP [0:0]
-A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
-A FORWARD -i eth0 -m state --state RELATED,ESTABLISHED -j ACCEPT
-A FORWARD -i eth1 -m state --state NEW,RELATED,ESTABLISHED -j ACCEPT
-A OUTPUT -m state --state NEW,RELATED,ESTABLISHED -j ACCEPT
COMMIT
# Completed on Wed Apr 24 10:19:55 2002
# Generated by iptables-save v1.2.6a on Wed Apr 24 10:19:55 2002
*mangle
:PREROUTING ACCEPT [658:32445]
:INPUT ACCEPT [658:32445]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [891:68234]
:POSTROUTING ACCEPT [891:68234]
COMMIT
# Completed on Wed Apr 24 10:19:55 2002
# Generated by iptables-save v1.2.6a on Wed Apr 24 10:19:55 2002
*nat
:PREROUTING ACCEPT [1:229]
:POSTROUTING ACCEPT [3:450]
:OUTPUT ACCEPT [3:450]
-A POSTROUTING -o eth0 -j SNAT --to-source 195.233.192.1
COMMIT
# Completed on Wed Apr 24 10:19:55 2002
Le righe relative alle tabelle hanno la seguente sintassi
*table-name
Le righe che specificano le regole sono del tipo
:chain-name chain-default-policy [packet-counter:byte-counter]
Le direttive (regole) hanno la sintassi seguente
[[packet-counter:byte-counter]] rule
dove rule è una regola come imparita con il comando iptables, tranne per il fatto che non
riporta l’indicazione del comando iptables né quella della tabella di riferimento.
La parte relativa ai contatori è presente soltanto se è stata specificata l’opzione
-c.
Ogni dichiarazione di tabella viene conclusa dalla parola chiave COMMIT.
____________________________________________________________________
Comando: iptables-restore
Path: /sbin/iptables-restore
SINTASSI
# iptables-restore [-c | --counters] [-n | --noflush]
DESCRIZIONE
-
-c | --counters indica a iptables-restore di ripristinare anche i contatori;
-
-n | --noflush indica a iptables-restore di on eliminare le regole già presenti
nelle tabelle (il comportamento di default è quello di eliminare prima tutte
le regole presenti nelle tabelle e quindi inserirci quelle specificate).
____________________________________________________________________________________________________________________
Poiché iptables-restore imposta il firewall con le direttive impostate tramite lo
standard input (tastiera), si può utilizzare la redirezione per ripristinare le impostazioni
salvate in un file, come nell’esempio seguente
# cat iptables.conf | iptables-restore -c
oppure
# iptables-restore -c < iptables.conf
che imposta il firewall ripristinando i contatori e le regole contenute nel file
iptables.conf precedentemente creato con iptables-save.
La procedura di avvio del sistema, provvede ad impostare automaticamente il firewall
con le regole contenute nel file /etc/sysconfig/iptables, tramite il comando
iptables-restore.
Si noti che iptables-restore non gestisce il caricamento di regole con valori
parametrizzati (es. l’indirizzo IP dinamico dell’interfaccia di rete) e per questo
tipo di regole si deve ricorrere comunque ad uno script.
|
25.3.1.1 Esempi
Nell’ambito della sicurezza è una buona regola bloccare l’accesso a tutti i pacchetti (policy di
default DROP) e aggiungere delle regole che premettano l’accesso soltanto per determinati
pacchetti.
[da completare ...]
È consigliabile abilitare il filtraggio dei pacchetti tramite la routing policy in modo tale che
il router stesso scarti i pacchetti che arrivano da un’interfaccia inaspettata. Ad esempio, se un
pacchetto con indirizzo IP relativo alla rete privata arriva all’interfaccia esterna,
questo viene scartato. Questo può essere fatto per l’interfaccia ppp0 con il seguente
comando
# echo "1" > /proc/sys/net/ipv4/conf/ppp0/rp_filter
Uno script di esempio che inserisce messaggi nel log di sistema man mano che i pacchetti
ICMP attraversano Netfilter è il seguente
#!/bin/bash
#
# rc.test-iptables - test script for iptables chains and tables.
#
# Copyright (C) 2001 Oskar Andreasson <blueflux@koffein.net>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; version 2 of the License.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program or from the site that you downloaded it
# from; if not, write to the Free Software Foundation, Inc., 59 Temple
# Place, Suite 330, Boston, MA 02111-1307 USA
#
#
# Filter table, all chains
#
iptables -t filter -A INPUT -p icmp --icmp-type echo-request \
-j LOG --log-prefix="filter INPUT:"
iptables -t filter -A INPUT -p icmp --icmp-type echo-reply \
-j LOG --log-prefix="filter INPUT:"
iptables -t filter -A OUTPUT -p icmp --icmp-type echo-request \
-j LOG --log-prefix="filter OUTPUT:"
iptables -t filter -A OUTPUT -p icmp --icmp-type echo-reply \
-j LOG --log-prefix="filter OUTPUT:"
iptables -t filter -A FORWARD -p icmp --icmp-type echo-request \
-j LOG --log-prefix="filter FORWARD:"
iptables -t filter -A FORWARD -p icmp --icmp-type echo-reply \
-j LOG --log-prefix="filter FORWARD:"
#
# NAT table, all chains except OUTPUT which don't work.
#
iptables -t nat -A PREROUTING -p icmp --icmp-type echo-request \
-j LOG --log-prefix="nat PREROUTING:"
iptables -t nat -A PREROUTING -p icmp --icmp-type echo-reply \
-j LOG --log-prefix="nat PREROUTING:"
iptables -t nat -A POSTROUTING -p icmp --icmp-type echo-request \
-j LOG --log-prefix="nat POSTROUTING:"
iptables -t nat -A POSTROUTING -p icmp --icmp-type echo-reply \
-j LOG --log-prefix="nat POSTROUTING:"
iptables -t nat -A OUTPUT -p icmp --icmp-type echo-request \
-j LOG --log-prefix="nat OUTPUT:"
iptables -t nat -A OUTPUT -p icmp --icmp-type echo-reply \
-j LOG --log-prefix="nat OUTPUT:"
#
# Mangle table, all chains
#
iptables -t mangle -A PREROUTING -p icmp --icmp-type echo-request \
-j LOG --log-prefix="mangle PREROUTING:"
iptables -t mangle -A PREROUTING -p icmp --icmp-type echo-reply \
-j LOG --log-prefix="mangle PREROUTING:"
iptables -t mangle -I FORWARD 1 -p icmp --icmp-type echo-request \
-j LOG --log-prefix="mangle FORWARD:"
iptables -t mangle -I FORWARD 1 -p icmp --icmp-type echo-reply \
-j LOG --log-prefix="mangle FORWARD:"
iptables -t mangle -I INPUT 1 -p icmp --icmp-type echo-request \
-j LOG --log-prefix="mangle INPUT:"
iptables -t mangle -I INPUT 1 -p icmp --icmp-type echo-reply \
-j LOG --log-prefix="mangle INPUT:"
iptables -t mangle -A OUTPUT -p icmp --icmp-type echo-request \
-j LOG --log-prefix="mangle OUTPUT:"
iptables -t mangle -A OUTPUT -p icmp --icmp-type echo-reply \
-j LOG --log-prefix="mangle OUTPUT:"
iptables -t mangle -I POSTROUTING 1 -p icmp --icmp-type echo-request \
-j LOG --log-prefix="mangle POSTROUTING:"
iptables -t mangle -I POSTROUTING 1 -p icmp --icmp-type echo-reply \
-j LOG --log-prefix="mangle POSTROUTING:"
Gli utenti di un sistema GNU/Linux con l’accesso ad Internet attraverso una connessione
dialup (modem), spesso desiderano che nessuno possa accedere dall’esterno al loro sitema. Di
seguito c’è uno script che funziona in questo modo
#
# Inserisci i moduli del connection-tracking
# (non necessari se inclusi nel kernel)
#
insmod ip_conntrack
insmod ip_conntrack_ftp
#
# Crea una catena che blocchi le nuove connessioni,
# eccetto quelle provenienti dall'interno.
#
iptables -N blockchain
iptables -A blockchain -m state --state ESTABLISHED,RELATED -j ACCEPT
iptables -A blockchain -m state --state NEW -i ! ppp0 -j ACCEPT
iptables -A blockchain -j DROP
#
# Dalle catene INPUT e FORWARD salta a questa catena
#
iptables -A INPUT -j blockchain
iptables -A FORWARD -j blockchain
Si può sentire la necessità di effettuare un NAT per le macchine presenti su
una rete privata e poterle fare accedere ad Internet tramite un’unica connessione
dialup effettuata dalla macchina che funge da gateway/firewall, tramite uno script
analogo a quello seguente (che deve essere eseguito sulla macchina che funge da
firewall)
# Abilita l'IP forwarding
echo 1 > /proc/sys/net/ipv4/ip_forward
# Carica il modulo NAT.
# (non necessario se incluso nel kernel)
modprobe iptable_nat
# NAT su ppp0 (la connessione dialup)
iptables -t nat -A POSTROUTING -o ppp0 -j MASQUERADE
È evidente che le macchine sulla rete protetta dal firewall che effettua anche il
NAT, devono avere come gateway di default una macchina della rete o il firewall
stesso.
Una cosa utile è quella di tracciare i tentativi di recapito di pacchetti “strani”, che può
essere fatta, ad esempio, con il seguente script
iptables -N no-conns-from-ppp0
iptables -A no-conns-from-ppp0 -m state --state ESTABLISHED,RELATED -j ACCEPT
iptables -A no-conns-from-ppp0 -m state --state NEW -i ! ppp0 -j ACCEPT
iptables -A no-conns-from-ppp0 -i ppp0 -m limit -j LOG --log-prefix "Bad packet from ppp0:"
iptables -A no-conns-from-ppp0 -i ! ppp0 -m limit -j LOG --log-prefix "Bad packet not from ppp0:"
iptables -A no-conns-from-ppp0 -j DROP
iptables -A INPUT -j no-conns-from-ppp0
iptables -A FORWARD -j no-conns-from-ppp0
[da completare ...]