stopsoftwarepatents.eu petition banner
  HOME    CHi SiAMO    CONTATTi    PROGETTi    DOCUMENTi    SECURiTY    NEWS    iMAGES    ...    >EVENTi    >BLiNDOLiNUX   
 
Breve panoramica sul nuovo codice di packet filtering nel kernel 2.4
Bertera Pietro (dr.iggy@iol.it)


Nei kernel dalla serie 2.2 era incluso ipchains che era una riscrittura del codice di firewalling di BSD.
In iptables il codice è stato riscritto quasi da capo.

La particolarità di iptables è quella di poter manipolare i pacchetti in diversi "punti" della nostra macchina.
Infatti ci sono 3 tabelle: FILTER, NAT e MANGLE.

Filter è composta da tre catene predefinite uguali a quelle di ipchains:

le quali controllano i pacchetti che sono diretti all'userspace (i programmi), escono o transitano dall'userspace.

Nat è utilizzata per i pacchetti che stanno per crere una nuova connessione (i pacchetti SYN) anche qui ci sono tre catene: Prerouting serve a stabilire le regole sui pacchetti che giungono prima della "routing decision" (l'analisi del pacchetto e la determinazione se è destinato alla macchina stessa o è da forwardare ad un'altra macchina), Output si riferisce ai pacchetti che sono in uscita e sono stati generati in locale, Postrouting regola i pacchetti che stanno per lasciare la macchina.

Mangle serve a manipolare i pacchetti in entrata o in uscita infatti ha due catene: la prima modifica i pacchetti in entrata prima della decisione del routing, la seconda interviene sui pacchetti in uscita dalla macchina prima del routing decision.

Nelle singole catene occorre stabilire delle regole tramite le quali il firewal decide la sorte del pacchetto.
Le regole di una catena hanno un target ovvero un'istruzione che stabilisce cosa fare del pacchetto, esistono quattro target fondamentali: la prima lascia passare il pacchetto, drop scarta il pacchetto senzadare avvisi al mittente, queue accoda il pacchetto verso l'userspace, return fa analizzare il pacchetto alla catena chiamante (se return è chamato da una catena predefinita, la sorte del pacchetto è determinato dalla policy della catena chiamante), reject rifiuta il pacchetto.
E' importante dire che come target si puo' utilizzare una catena definita dall'utente.

Precedentemente è stato accennato alla policy di una catena, per chiarire il concetto occorre fare una piccola premssa sul funzionamento di un firewall.
Il filtraggio sotto Linux 2.4 si basa come nelle versioni precedenti sui concetti di catene (chain), obiettivi (target) e tattiche (policy).
Ciascuna catena consiste di una tattica (policy), e di una o più regole che stabiliscono quali pacchetti sono accettati e quali no.
Una regola si compone in genere di una serie di caratteristiche che servono ad individuare un pacchetto e da un obiettivo (target) che indica cosa fare del pacchetto se la regola è soddisfatta. L'obiettivo corrisponde ai target sopra descritti.

Una catena si può rappresentare in questo modo (qui prendiamo ad esempio la catena INPUT):
  |      INPUT
  | +---------------+
  | |    Regola 1   |
  | -----------------
  | |    Regola 2   |
  | -----------------
  | |    Regola 3   |
  v +---------------+
        Tattica
I pacchetti che giungono dalla rete e che sono destinati alla catena INPUT verranno filtrati dalle regole della catena:
se la regola 1 non è soddisfatta si passa alla regola 2, se non è soddisfatta nemmeno la 2 si passa alla successiva, la prima regola soddisfatta accetta, rifiuta o scarta il pacchetto, se non viene soddisfatta nessuna regola si applica la policy che dice a sua volta se accettare, scartare o rifiutare il pacchetto.
Generalmente si utilizzano due filosofie di policy, brutalmente: "accetta tutto tranne..." o "rifiuta tutto tranne...".
Per comprendere la configurazione di iptables costruiremo un semplice scpript dimostrativo.

Per potere implementare lo script occorre conoscere le opzioni che si possono utilizare:

Le ultime 4 opzioni, se non viene specificata una catena, agiscono su tutte le catene:

# Rimuovi tutte le regole della catena OUTPUT
iptables -F OUTPUT

# Rimuovi tutte le regole presenti in TUTTE le catene
iptables -F


l'opzione -L può essere utilizzata inoltre per visualizzare tutte le catene o una sola (se si desiderano anche i numeri di linea utilizzare
l'opzione '--line-numbers'):
# iptables -L

Chain INPUT (policy ACCEPT)
target     prot opt source               destination
DROP       tcp  --  anywhere             anywhere           tcp dpt:telnet

Chain FORWARD (policy ACCEPT)
target     prot opt source               destination 

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination 

# iptables -L INPUT
Chain INPUT (policy ACCEPT)
target     prot opt source               destination 
DROP       tcp  --  anywhere             anywhere           tcp dpt:telnet

# iptables --line-numbers -L INPUT
Chain INPUT (policy DROP)
num  target     prot opt source               destination         
1    DROP       tcp  --  anywhere             anywhere      tcp dpt:telnet


OPERAZIONI DI SELEZIONE:

Le seguenti opzioni (alcune già accennate) permettono di realizzare delle regole per il filtraggio dei pacchetti

E' possibile specificare inoltre le opzioni '--tcp-flags', '--tcp-option', e '--syn' oltre a '--sport' e '--dport'.

Ora che sappiamo le principali opzioni di iptables possiamo cimentarci nella scrittura di un semplice script

Per semplicità mettiamo il path di iptables nella variabile IPTABLE e in IP il nostro IP

IPTAB=/usr/local/sbin/iptables IP=`ifconfig ppp0 | grep inet | cut -d : -f 2 | cut -d\ -f 1`

Definiamo ora le policy della catena filter:

$IPTAB -P INPUT DROP $IPTAB -P FORWARD DROP $IPTAB -P OUTPUT ACCEPT


Ora stabiliamo le regole della tabella nat:
$IPTAB -t nat -A PREROUTING -i ppp0 -s 127.0.0.0/8 -j DROP
$IPTAB -t nat -A PREROUTING -i ppp0 -s 192.168.0.0/16 -j DROP
$IPTAB -t nat -A PREROUTING -i ppp0 -d ! $IP -j DROP
### SPERIMENTALE ###
#$IPTAB -t nat -A PREROUTING -i ppp0 -m unclean -j DROP
Con la prima regola scartiamo tutti i pacchetti che dicono di provenire dalla nosta macchina (127.x.x.x) (il numero dopo '/' è la maschera) perchè questi dovrebbero viaggiare solo sull'interfaccia lo e non sul modem (ppp0).
La seconda regola elimina tutti i pacchetti provenienti dalla rete locale poichè sono sull'interfaccia del modem.
La terza scarta tutti ipacchetti che non sono rivolti a noi (dato che un router non li invierebbe certo a noi questi pacchetti sono sospetti).
La terza istruzione attiva un controllo sulla sanità del pacchetto scartandopacchetti ambigui.
La regola è commentata dato che potrebbe scartare qualche pacchetto non dannoso.

$IPTAB -N ppp_in
$IPTAB -N services

Vengono create due catene alle quali verranno rimandati i pacchetti.
$IPTAB -A INPUT -i lo -j ACCEPT
$IPTAB -A INPUT -i ppp0 -j ppp_in

La prima lascia passare tuti i pacchetti local-to-local sull'interfaccia lo
La seconda rimanda tutti i pacchetti che provengono dal modem alla catena ppp_in precedenteente creata.

Catena ppp_in:

$IPTAB -A ppp_in -p icmp --icmp-type ! echo-request -j ACCEPT

Questa linea lascia passare tutti i pacchetti ICMP tranne le echo-request (i ping).
Questa regola lascia comunque inviare pacchetti di ping perchè siamo nella catena chiamata da INPUT, quindi un ping sul nostro IP non produrrà alcun risultato.
$IPTAB -A ppp_in -p tcp --dport 6000:6010 -j DROP
$IPTAB -A ppp_in -p udp --dport 6000:6010 -j DROP
$IPTAB -A ppp_in -p tcp --dport 7000:7010 -j DROP
$IPTAB -A ppp_in -p udp --dport 7000:7010 -j DROP
$IPTAB -A ppp_in -p tcp --dport 1:1024 -j services
$IPTAB -A ppp_in -p udp --dport 1:1024 -j services
Queste regole bloccano tutti i pacchetti destinati alle porte del X11 e Xfont Server perchè i pacchetti su queste porte potrebbero danneggiare i rispettivi servizi.
I pacchetti diretti alle porte riservate (inferiori alla 1024) vengono controllati dalla catena services.

#DNS
$IPTAB -A ppp_in -p udp --sport 53 -j ACCEPT
$IPTAB -A ppp_in -p tcp --sport 53 -j ACCEPT

#smtp
$IPTAB -A ppp_in -p tcp --sport 25 -j ACCEPT

#nntp
$IPTAB -A ppp_in -p tcp --sport 119 -j ACCEPT

#telnet
$IPTAB -A ppp_in -p tcp --sport 23 -j ACCEPT

#ftp (dati e linea di controllo)
$IPTAB -A ppp_in -p tcp --sport 20 -j ACCEPT
$IPTAB -A ppp_in -p tcp --sport 21 -j ACCEPT

#irc
$IPTAB -A ppp_in -p tcp --sport 6666:7000 -j ACCEPT
$IPTAB -A ppp_in -p udp --sport 6666:7000 -j ACCEPT

#talk
$IPTAB -A ppp_in -p tcp --sport 518:519 -j ACCEPT
$IPTAB -A ppp_in -p udp --sport 518:519 -j ACCEPT

#http e https
$IPTAB -A ppp_in -p tcp -m multiport --sport 80,443 -j ACCEPT

#pop3
$IPTAB -A ppp_in -p tcp --sport 110 -j ACCEPT

#imap
$IPTAB -A ppp_in -p tcp -m multiport --sport 143,220 -j ACCEPT
Queste regole fanno passare i pacchetti relativi a: DNS, posta in uscita, news, telnet in uscita, ftp, irc, talk, web, server pop3, server imap2 e imap3.
il modulo multiport serve a scrivere più porte non consecutive nella stessa regola.

Catena service:

$IPTAB -A services -p tcp --dport 113 -j REJECT
$IPTAB -A services -j DROP

La prima regola indica di non accettare i pacchetti sulla porta 113 ma macchina che li ha generati (solitamente un server irc) verrà avvisata che il servizio non è disponibile.
La seconda regola scarta tutti gli altri pacchetti senza avvisare nessuno.
Se invece volessimo lasciare aperti dei servizi occorre inserire tra le due regole (l'istruzione DROP deve essere sempre l'ultima)

$IPTAB -A services -p tcp --dport 80 -j ACCEPT

Così facendo il nostro server web sarà accessibile dall'esterno.

Funzionalità avanzate

Fino ad ora sono state utilizzate delle istruzioni abbastanza semplici che per la maggior parte erano compatibili con ipchains, in questa sezione vengono trattate regole che forniscono mggiore protezione ma che esistono solo in iptables e con le apposite opzioni del kernel compilate (o installate come moduli).
$IPTAB -N conn_state
$IPTAB -N tcp_flags

Queste tabelle verranno utilizzate per il controllo dello stato del pacchetto e i flags del pacchetto
$IPTAB -A conn_state -m state --state INVALID -j DROP
$IPTAB -A conn_state -m state --state RELATED,ESTABLISHED -j ACCEPT

In queste regole è inserita l'opzione avanzata state che verrà descritta brevemente di seguito:
Questa opzione è inserita nel modulo ip_conntrack.o e seve a tenere traccia delle connessione e a stabilire se un pacchetto appartiene a una di esse o meno.
Per connessioni si intendono anche quelle UDP, ICMP che non necessitano di un meccanismo di richiesta/conferma ("three-way handshake").
Una volta caricato il modulo ip_conntrack.o appena viene stabilita una nuova connessione esso provvede a prendere nota delle informazioni più importanti (indirizzo sorgente, indirizzo destinazione, porta sorgente, porta destinazione ...) e a memorizzarle.
E' in grado così per ogni pacchetto che giunge dalla rete o è generato dalla Linux box stessa di stabilire a quale delle seguenti categorie appartiene:


NEW
ESTABLISHED
RELATED
INVALID

NEW
Pacchetti che cercano di stabilire una nuova (NEW) connessione

ESTABLISHED
Pacchetti appartenenti ad una connessione esistente e nota.

RELATED
Pacchetti relativi ad una connessione esistente ma di cui non ne fanno parte, potrebbero essere pacchetti ICMP di errore o altro.

INVALID
Pacchetti non appartenenti a connessioni note, quindi in genere da rifiutare..

Quindi è possibile interrogare il "connection tracking" per conoscere che tipo di pacchetto è stato ricevuto (NEW,ESTABLISHED,RELATED,INVALID) e decidere l'azione da intraprendere (ACCEPT,DROP,...).

A questo scopo è necessario specificare l'opzione 'm state --state' seguita da una o più degli stati appena descritti: NEW, ESTABLISHED, RELATED, INVALID.

Conoscendo il funzionamento di state, si capisce che la prima regola scarta i pacchetti che non appartengono a nessuna connessione o che non sono dei SYN.
La seconda invece lascia passare i pacchetti appartenenti o relativi ad una connessione.
Per i pacchetti SYN la decisione viene lasciata alla catena ppp_in.

La seguenta catena verifica i flags dei pacchetti per decidere se accettarli o meno.
$IPTAB -A tcp_flags -p tcp --tcp-flags ALL FIN,URG,PSH -j DROP
$IPTAB -A tcp_flags -p tcp --tcp-flags ALL ALL -j DROP
$IPTAB -A tcp_flags -p tcp --tcp-flags ALL SYN,RST,ACK,FIN,URG -j DROP
$IPTAB -A tcp_flags -p tcp --tcp-flags ALL NONE -j DROP
$IPTAB -A tcp_flags -p tcp --tcp-flags SYN,RST SYN,RST -j DROP
$IPTAB -A tcp_flags -p tcp --tcp-flags SYN,FIN SYN,FIN -j DROP
$IPTAB -A tcp_flags -p tcp --tcp-flags FIN FIN -j DROP
Queste regole servono ad impedire gli scan Xmas tree di nmap ( prima, seconda e terza), la quarta blocca i pacchetti senza flags, la quinta blocca i pacchetti SYN+RST, l'ultima blocca i pacchetti SYN+FIN.
Quest'ultima, contro gli scan FIN, è sensata solo se è presente anche la catena conn_state e se viene chiamata per prima.

Queste due catene dovranno essere inserite all'inizio della catena ppp_in con queste istruzioni:
$IPTAB -I ppp_in 1 -j conn_state
$IPTAB -I ppp_in 1 -j tcp_flags

La catena conn_state rende superflua la catena ppp_in in quanto un normale utente non vorrà permettere connessioni sul proprio computer.
I SYN che tornano da una connessiione TCP verranno riconosciuti come parte della connessione e fatti passare.

Il firewall si potrebbe sintetizzare:

$IPTAB -P INPUT DROP
$IPTAB -F
$IPTAB -X
$IPTAB -t nat -A PREROUTING -i ppp0 -s 127.0.0.0/8 -j DROP
$IPTAB -t nat -A PREROUTING -i ppp0 -s 192.168.0.0/16 -j DROP
$IPTAB -t nat -A PREROUTING -i ppp0 -d ! $IP -j DROP
### SPERIMENTALE ###
#$IPTAB -t nat -A PREROUTING -i ppp0 -m unclean -j DROP
$IPTAB -N ppp_in
$IPTAB -N services
$IPTAB -N conn_state
$IPTAB -N flags
$IPTAB -N blocked
$IPTAB -A INPUT -i lo -j ACCEPT
$IPTAB -A INPUT -i ppp0 -j ppp_in
$IPTAB -A conn_state -m state --state INVALID -j DROP
$IPTAB -A conn_state -m state --state RELATED,ESTABLISHED -j ACCEPT
$IPTAB -A tcp_flags -p tcp --tcp-flags ALL FIN,URG,PSH -j DROP
$IPTAB -A tcp_flags -p tcp --tcp-flags ALL ALL -j DROP
$IPTAB -A tcp_flags -p tcp --tcp-flags ALL SYN,RST,ACK,FIN,URG -j DROP
$IPTAB -A tcp_flags -p tcp --tcp-flags ALL NONE -j DROP
$IPTAB -A tcp_flags -p tcp --tcp-flags SYN,RST SYN,RST -j DROP
$IPTAB -A tcp_flags -p tcp --tcp-flags SYN,FIN SYN,FIN -j DROP
$IPTAB -A tcp_flags -p tcp --tcp-flags FIN FIN -j DROP
$IPTAB -A services -j DROP
$IPTAB -A ppp_in -j blocked
$IPTAB -A ppp_in -j conn_state
$IPTAB -A ppp_in -j flags
$IPTAB -A ppp_in -p tcp --dport 1:1024 -j services
$IPTAB -A ppp_in -p udp --dport 1:1024 -j services
$IPTAB -A ppp_in -p icmp --icmp-type ! echo-request -j ACCEPT
$IPTAB -A ppp_in -p tcp --sport 20 -j ACCEPT

Ovviamente questo è un firewall minimo e senza logging. Lo script avanzato che potete scaricare è invece più completo ed è configurabile tramite il file /etc/firewall.conf.


LA RIPRODUZIONE DI QUESTO DUCUMENTO O DI SUE PARTI E' LIBERAMENTE CONSENTITA ALLE PERSONE FISICHE, PURCHE' NON EFFETTUATA A FINI DI LUCRO
  HOME    CHi SiAMO    CONTATTi    PROGETTi    DOCUMENTi    SECURiTY    NEWS    iMAGES    ...    >EVENTi    >BLiNDOLiNUX   
© valtellinux.it 1999...2005
Tutti i marchi citati appartengono alle rispettive compagnie
non l'ho fatto con phpnuke!

L:0.19563 :: Q:0 :: P:0 :: T:0.21701