Abstract
Questo documento tratta della normalizzazione del traffico di rete.
La prima parte affronta l'argomento dal punto di vista teorico. La
seconda parte presenta alcuni stralci di codice, ampiamente commentati,
dell'implementazione della direttiva "scrub" all'interno del Packet
Filter di OpenBSD. La terza parte illustra brevemente il sanity check
eseguito dall'estensione unclean di IPTables, il firewall dei sistemi
GNU/Linux.
Data di stesura: 29/12/2003
Data di pubblicazione:
05/04/2004
Ultima modifica: 04/04/2006
Un normalizzatore (normalizer) altro non è che un dispositivo che si
pone nei punti di ingresso della rete con l'unico scopo di rimuovere
le eventuali ambiguità presenti nel flusso di pacchetti che lo
attraversa.
PARTE I
Cosa deve fare
Lo scopo del normalizzatore è quello di convertire i pacchetti che
presentano delle "ambiguità", e che potrebbero essere interpretati in
modo differente dai vari destinatari finali, in un flusso "normalizzato"
e omogeneo, univocamente interpretato da tutti gli end-point.
A prima vista un meccanismo del genere potrebbe sembrare quantomeno
superfluo, invece risulta essere di grande utilità soprattutto se
affiancato ad un Network Intrusion Detection System o ad un firewall.
I NIDS basano la loro efficacia sul concetto che osservando i pacchetti
in transito su una interfaccia sia possibile predirne il comportamento,
e bloccarli se risultano dannosi per il destinatario finale.
Tutto questo non ha più senso quando il NIDS incontra pacchetti creati
ad-hoc da un eventuale attaccante e viene aggirato (attacchi di
inserzione ed evasione dei pacchetti [1]).
In realtà, differenze nell'interpretazione del flusso di dati, si
verificano anche quando un NIDS ha a che fare con traffico "regolare",
questo accade perché, in genere, un network IDS si trova su una macchina
diversa da quella dell'end-point e osserva un punto completamente
diverso della rete; queste discrepanze sono il frutto di diverse
implementazioni dei driver di rete e differenze fisiche tra le macchine.
In Tabella 1 c'è un esempio di quanto appena detto, è rappresentato il
comportamento dei vari sistemi operativi in presenza di overlap dei
frammenti IP.
+-------------------+--------------------------------------------+
| Sistema Operativo | Comportamento |
+-------------------+--------------------------------------------+
| Windows NT | Prende sempre in considerazione i dati che |
| | arrivano per primi |
+-------------------+--------------------------------------------+
| 4.4BSD | Prende sempre in considerazione i nuovi |
| | frammenti in caso di forward overlap |
+-------------------+--------------------------------------------+
| Linux | Prende sempre in considerazione i nuovi |
| | frammenti in caso di forward overlap |
+-------------------+--------------------------------------------+
| Solaris | Prende sempre in considerazione i dati che |
| | arrivano per primi |
+-------------------+--------------------------------------------+
| HP-UX | Prende sempre in considerazione i nuovi |
| | frammenti in caso di forward overlap |
+-------------------+--------------------------------------------+
| Irix | Prende sempre in considerazione i nuovi |
| | frammenti in caso di forward overlap |
+-------------------+--------------------------------------------+
Ebbene il normalizer rimuove le ambiguità (volute o casuali) presenti
nel flusso in ingresso, passando al NIDS un flusso normalizzato in modo
da metterlo in condizioni di prevedere correttamente il comportamento
del destinatario finale.
A grandi linee lo stesso ragionamento vale per i firewall.
Sebbene lo scopo principale del normalizer sia quello di normalizzare i
pacchetti, spesso il traffico non può essere corretto in accordo con le
specifiche del protocollo. In questi casi l'azione da intraprendere
dipende dalla configurazione del normalizzatore, non c'è bisogno di
aggiungere che una politica di sicurezza seria prevede in questi casi
il rifiuto di tutti i pacchetti illegali e non "normalizzabili".
Oltre a correggere le incongruenze, il normalizer interviene anche su
alcuni pacchetti che, benché siano perfettamente legali dal punto di
vista delle specifiche del protocollo, potrebbero creare problemi agli
end-point.
Ad esempio interviene sul campo TTL (Time-To-Live) dei pacchetti IP,
in modo da evitare che i pacchetti con un valore basso di TTL, visti dal
NIDS, non arrivino al destinatario finale.
Oltre ad intervenire sul traffico in ingresso, un normalizzatore opera
anche sui pacchetti in uscita.
Ad esempio va a sovrascrivere il valore del campo "identification" dei
pacchetti IP con un valore casuale, evitando in questo modo i port scan
di tipo stealth e rendendo più complicato il lavoro dei vari tool per il
fingerprinting.
Cosa non deve fare
Un normalizzatore deve solo normalizzare il traffico e nient'altro, non
si deve occupare né di filtrare i pacchetti né di individuare possibili
attacchi, a questo ci pensano rispettivamente i firewall e i network
intrusion detection system.
Perché quando si implementa un dispositivo di normalizzazione bisogna
prestare particolare attenzione alle performance, il rischio, non tanto
remoto, è quello di congestionare la rete.
Un normalizzatore deve garantire un buon attraversamento dei pacchetti
irregolari, che devono essere normalizzati e quindi riscritti, e
inoltre non deve avere un impatto negativo sul traffico regolare.
L'incidenza sulle prestazioni generali della rete non è facilmente
quantificabile, troppe sono le parti in gioco; bisogna tener conto del
protocollo che si va a normalizzare, del tipo di rete, del numero di
pacchetti, della complessità delle regole di scrubbing, dell'efficienza
della scheda di rete e di tutto l'hardware in generale, etc.
Come funziona
In genere un normalizzatore opera prevalentemente, ma non solo, sugli
header dei pacchetti da esaminare.
Ogni campo dell'intestazione viene confrontato con un range di valori
ammessi, e ne viene controllato il contenuto alla ricerca di ambiguità
e di valori che potrebbero avere degli effetti indesiderati sull'
end-point.
Ad esempio, nel caso di normalizzazione IP, in genere, si controlla se
la lunghezza dell'header è troppo lunga o troppo corta, se la lunghezza
totale è corretta, controlla se gli indirizzi di partenza e di
destinazione sono validi, esamina il campo TTL e le opzioni, verifica
la correttezza del checksum e così via.
Nel caso di normalizzazione TCP, oltre alle verifiche riguardanti la
lunghezza di header e la validità del checksum, vengono eseguiti
controlli sulla correttezza dei flag e sul numero di sequenza. Per gli
altri protocolli, a grandi linee, valgono le stesse considerazioni.
Di seguito vedremo in dettaglio un esempio di implementazione di un
normalizzatore, e più precisamente poseremo l'attenzione sulla direttiva
scrub del Packet Filter di OpenBSD, senza dimenticare Linux e IPTables.
PARTE II
Real World: la direttiva Scrub del Packet Filter di OpenBSD
La direttiva scrub di PF si occupa della normalizzazione e della
deframmentazione del traffico TCP/IP.
In questo documento ci occuperemo solo del primo aspetto.
La sintassi della direttiva scrub è molto simile alla sintassi per il
filtraggio, questo rende facile usare scrub selettivamente solo su
alcuni pacchetti. Un semplice esempio dell'uso di scrub all'interno
delle regole di pf è il seguente:
scrub in all
questa riga applicherà la direttiva scrub a tutti i pacchetti in
ingresso su tutte le interfacce.
Oltre all'uso barbaro visto poc'anzi, è possibile usare nelle regole di
scrubbing le seguenti opzioni riguardanti la normalizzazione:
no-df
azzera il bit "don't fragment" nell'intestazione dei
pacchetti IP, vedremo in seguito l'utilizzo di questa
opzione;
random-id
sostituisce il campo "identification" dei pacchetti IP
in uscita con un valore casuale per compensare i valori
predicibili usati da alcuni sistemi operativi;
min-ttl num
impone un valore minimo (num) del "Time To Live" (TTL)
nell'intestazione dei pacchetti IP;
max-mss num
impone un valore massimo (num) del "Maximum Segment Size"
(MSS) nell'intestazione dei pacchetti TCP.
Le opzioni che gestiscono i frammenti sono invece "fragment reassemble",
"fragment crop" e "fragment drop-ovl" che si occupano della gestione dei
frammenti e del trattamento dei frammenti duplicati o che si vanno a
sovrapporre a quelli già ricevuti.
Un esempio un po' più rappresentativo di una regola di scrubbing è il
seguente:
scrub in on rl0 all fragment reassemble min-ttl 20 max-mss 1400
Per maggiori dettagli sulla sintassi della direttiva scrub rimando alle
FAQ ufficiali di OpenBSD [3].
Senza entrare nei dettagli della deframmentazione vediamo di seguito
come è implementata la normalizzazione all'interno di PF.
Nota: il codice utilizzato nella stesura di questo articolo fa
riferimento alla versione 3.3 dei sorgenti di OpenBSD [2].
Normalizzazione IP
La funzione che si occupa di normalizzare il traffico IP [7] all'interno
di PF è pf_normalize_ip in /usr/src/sys/net/pf_norm.c [2], ecco di
seguito il prototipo:
int pf_normalize_ip(struct mbuf **, int, struct ifnet *, u_short *);
Le variabili che incontreremo negli stralci di codice hanno il seguente
significato: "h" è l'header del pacchetto da normalizzare, e "r" è una
struttura di tipo "pf_rule" definita in pfvar.h, che in sostanza
rappresenta il contenuto di una regola di PF, in questo caso è una
regola per lo scrubbing.
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|Version| IHL |Type of Service| Total Length |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Identification |Flags| Fragment Offset |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Time to Live | Protocol | Header Checksum |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Source Address |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Destination Address |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Options | Padding |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
Il pacchetto viene scartato se la lunghezza della sua intestazione (hlen)
è minore di 20 byte, ovvero se l'header, raffigurato in figura 1 è
incompleto:
if (hlen < (int)sizeof(struct ip)) goto drop;
e viene scartato anche se hlen è maggiore della lunghezza totale del
pacchetto:
if (hlen > ntohs(h->ip_len)) goto drop;
Se il flag "Don't fragment" è settato e il fragment offset è diverso da
zero il pacchetto viene scartato in quanto malformato:
if (h->ip_off & htons(IP_DF)) {
goto bad;
}
Alcuni sistemi operativi, però, generano pacchetti frammentati con il
bit "don't fragment" settato, questo succede ad esempio con NFS.
Come visto in precedenza, scrub rifiuterà tali pacchetti a meno che non
sia specificata l'opzione "no-df". Usando l'opzione "no-df" invece viene
azzerato il bit "don't fragment" nell'intestazione dei pacchetti IP.
Se viene usata l'opzione min-ttl di scrub, che impone un valore minimo
del Time To Live (TTL) nell'intestazione dei pacchetti IP, il TTL di
ogni pacchetto (h->ip_ttl) viene forzato al valore passato a scrub.
Ad esempio con la regola
scrub in on rl0 all min-ttl 20
si impone il valore 20 come TTL per tutti quei pacchetti che hanno un
valore inferiore. Questa è una opzione da usare con cautela in quanto
c'è la possibilità di creare loop infiniti, oltre a creare problemi a
traceroute e simili.
if (r->min_ttl && h->ip_ttl < r->min_ttl)
h->ip_ttl = r->min_ttl;
Se è impostata l'opzione "random-id" all'interno della regola di
scrubbing il valore del campo "identification" dei pacchetti IP in
uscita viene sostituito con un valore casuale, generato dalla funzione
ip_randomid, per compensare i valori predicibili usati da alcuni sistemi
operativi.
if (r->rule_flag & PFRULE_RANDOMID)
h->ip_id = ip_randomid();
Normalizzazione IPv6
La funzione che si occupa di normalizzare il traffico IPv6 è
pf_normalize_ip6 in /usr/src/sys/net/pf_norm.c [2], di seguito il
prototipo:
int pf_normalize_ip6(struct mbuf **, int, struct ifnet *, u_short *)
Anche nel caso di pacchetti IPv6 [7], figura 2, è possibile gestire il
Time To Live attraverso l'opzione min-ttl di scrub.
Il valore passato come argomento a min-ttl va a modificare il campo
"Hop limit" (ip6_hlim).
if (r->min_ttl && h->ip6_hlim < r->min_ttl)
h->ip6_hlim = r->min_ttl;
Anche in questo caso, come per i pacchetti IP, l'opzione min-ttl è da
usare con estrema cautela.
Oltre ai soliti controlli sulle dimensioni delle intestazioni dei
pacchetti e delle estensioni, particolare attenzione viene rivolta ai
jumbogram.
Senza entrare troppo nei dettagli, non è questa la sede adatta, un
jumbogram è un pacchetto IPv6 contenente un payload di dimensione
superiore ai 65.535 byte. Tali pacchetti sono segnalati dalla presenza
dell'opzione "Jumbo Payload" di tipo "hop-by-hop".
L'header di un pacchetto IPv6 ha un campo "Payload Length" di 16 bit,
mentre l'opzione "Jumbo Payload", figura 3, mette a disposizione il campo
"Jumbo Payload Length" di 32-bit e permette quindi di gestire i cosidetti
jumbogram.
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Option Type | Opt Data Len |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Jumbo Payload Length |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
In sintonia con le specifiche del protocollo (RFC2675) [7], il campo
"Payload Length" (ip6_plen) dell'intestazione IPv6 deve essere posto a
zero in ogni pacchetto che presenta l'opzione "Jumbo Payload", in caso
contrario il pacchetto viene scartato.
if (h->ip6_plen != 0)
goto drop;
Se è presente l'opzione "Jumbo Payload" e la lunghezza (jumbolen) del
pacchetto IPv6 (senza l'intestazione), è minore di IPV6_MAXPACKET, che
vale 65535, il pacchetto viene scartato.
if (jumbolen <= IPV6_MAXPACKET)
goto drop;
Il pacchetto viene scartato anche se il campo "Payload Length" del
pacchetto IPv6 è posto a zero e non è presente l'opzione Jumbo Payload.
if (ntohs(h->ip6_plen) == 0)
plen = jumbolen;
else
plen = ntohs(h->ip6_plen);
if (plen == 0)
goto drop;
Come detto in precedenza "jumbolen" è la lunghezza del pacchetto IPv6
con "Jumbo Payload", e vale zero se non è presente tale opzione.
In conclusione il pacchetto IPv6 viene rifiutato anche se oltre
all'opzione "Jumbo Payload" è presente l'estensione "Fragment".
Normalizzazione TCP
La funzione che si occupa di normalizzare i pacchetti TCP [7], figura 4,
è pf_normalize_tcp in /usr/src/sys/net/pf_norm.c [2], di seguito il
prototipo:
Per i nomi delle variabili abbiamo che "th" è una struttura di tipo
"tcphdr", e "flags" corrisponde a "th->th_flags".
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Source Port | Destination Port |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Sequence Number |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Acknowledgment Number |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Data | |U|A|P|R|S|F| |
| Offset| Reserved |R|C|S|S|Y|I| Window |
| | |G|K|H|T|N|N| |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Checksum | Urgent Pointer |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Options | Padding |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| data |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
Se sono settati i flag SYN e RST il pacchetto è illegale e viene
scartato, se invece oltre a SYN è settato il flag FIN, quest'ultimo
viene posto a zero e il pacchetto prosegue per la sua strada.
Il pacchetto viene scartato anche se si ha allo stesso tempo SYN=0,
ACK=0 e RST=0.
if (flags & TH_SYN) {
if (flags & TH_RST)
goto tcp_drop;
if (flags & TH_FIN)
flags &= ~TH_FIN;
} else {
if (!(flags & (TH_ACK|TH_RST)))
goto tcp_drop;
}
Poiché i flag FIN, PUSH e URG sono validi solo se anche ACK è settato,
in tutti gli altri casi il pacchetto viene rifiutato, ad esempio se
FIN=1 e ACK=0.
if (!(flags & TH_ACK)) {
if ((flags & TH_FIN) || (flags & TH_PUSH) || (flags & TH_URG))
goto tcp_drop;
}
Se il flag URG non è settato viene rimosso l'urgent pointer.
Il pacchetto viene scartato anche se la lunghezza dell'header TCP non è
corretta.
if (th->th_off < (sizeof(struct tcphdr) >> 2))
goto tcp_drop;
Eseguendo uno scanning con Nessus su un firewall con PF + SCRUB
viene fuori da Nessus questo messaggio:
"The remote host does not discard TCP SYN packet which have the FIN flag
set. Depending on the kind of firewall you are using, an attacker may use
this flaw to bypass its rules."
Brevemente dice che i pacchetti TCP SYN con il flag FIN settato non
vengono scartati dall'host remoto e che di conseguenza è possibile usarli
per bypassare le regole del firewall.
A questo punto uno potrebbe chiedersi "allora scrub non serve a niente o
non funziona", in realtà il problema è tutto di Nessus.
Vediamo cosa succede.
Se la regola di scrubbing è verificata, di fronte ad un pacchetto con i
flag SYN e FIN settati, scrub azzera il bit FIN.
Dopodiché il pacchetto, che adesso non ha più il flag FIN settato, passa
alle regole di filtraggio.
Se nessuna regola lo blocca, prosegue il suo cammino e molto
probabilmente sarà generato in risposta un SYN+ACK.
È questo comportamento che fa credere a Nessus che il pacchetto con
SYN+FIN ha avuto successo, ma in realtà non è vero.
Nessus non può sapere che il flag FIN è stato rimosso, non fa altro che
inviare un SYN+FIN e ricevere un SYN+ACK in risposta, e questo gli basta
per trarre le conclusioni, in questo caso sbagliate.
Maggiori informazioni sul test di Nessus si trovano nel file
/nessus-plugins/scripts/tcpip_ambiguities.nasl
che non fa altro che "Sends a SYN+FIN packet and expects a SYN+ACK".
Ascolto e dimentico, vedo e ricordo, faccio e capisco
Ed ora, dopo tante parole e tanto codice, andiamo a vedere come si
comporta il nostro dispositivo sul campo.
Per farlo creeremo dei pacchetti ad hoc e li invieremo al nostro
end-point facendoli passare attraverso una macchina che fungerà da
firewall. Per creare i pacchetti "ambigui" useremo Nemesis [8].
Sul firewall, realizzato ovviamente con OpenBSD e PF, sono caricate solo
le regole di scrubbing, in particolare per i pacchetti in ingresso
abbiamo impostato un valore minimo di TTL pari a 20:
# pfctl -s rules
@0 scrub in all min-ttl 20 fragment reassemble
@1 scrub out all fragment reassemble
Di seguito vedremo tre esempi di normalizzazione:
1) Pacchetto con i flag SYN e FIN settati.
Come abbiamo visto in precedenza tale pacchetto non viene scartato,
ma scrub interviene ponendo a zero il flag FIN.
Creiamo il pacchetto con nemesis-tcp
# tcpdump -n -t -vv -i rl0
tcpdump: listening on rl0
192.168.1.1.42069 > 192.168.2.1.23: S [tcp sum ok] 420:420(0)
win 512 (DF) [tos 0x18] (ttl 254, id 11367)
come si vede dall'output di TcpDump [8], il pacchetto arriva con il solo
flag SYN settato.
2) Time To Live inferiore al valore di min-ttl.
Quando al firewall arriva un pacchetto con un TTL inferiore al valore
passato come argomento a min-ttl nella regola di scrubbing, nel nostro
caso 20, il firewall riscrive il pacchetto con un nuovo valore per TTL.
Creiamo un pacchetto con un Time To Live pari a 12
e vediamo che al destinatario finale arriva un pacchetto con un valore
di TTL pari a 20
# tcpdump -n -t -vv -i rl0
tcpdump: listening on rl0
192.168.1.1.42069 > 192.168.2.1.23: S [tcp sum ok] 420:420(0)
win 512 (DF) [tos 0x18] (ttl 20, id 61302)
3) Pacchetto con il solo flag FIN settato.
Per concludere "iniettiamo" nella rete un pacchetto non valido, avente
il solo flag FIN settato.
Creiamo il nostro pacchetto con il solito Nemesis:
# nemesis-tcp -fF -S 192.168.1.1 -D 192.168.2.1
e vediamo cosa accade.
Stavolta TcpDump, posto in ascolto sull'end-point, non ci è d'aiuto
poiché il pacchetto ha terminato la sua corsa sul firewall.
È stato scartato perché non corretto, il flag FIN è ritenuto valido
solo se anche il flag ACK è settato.
Ovviamente non si esauriscono qui le prove che si possono fare per
vedere all'opera il normalizzatore, ma le lascio al lettore come
utile esercizio per la comprensione delle reti e dello scrubbing.
PARTE III
Real World: unclean, il sanity check di IPTables
Per concludere facciamo una breve panoramica sulla normalizzazione
eseguita da IPTables, evitando di ripetere i concetti già espressi
nella trattazione di PF e OpenBSD.
All'interno di IPTables è il modulo Unclean che si occupa della
normalizzazione, anche se in questo caso, forse, è più corretto parlare
di sanity check.
Per poter usufruire delle funzionalità di unclean occorre caricare il
modulo usando l'opzione "-m unclean" all'interno della regola che
comprende il traffico che si vuole normalizzare, ad esempio:
iptables -A INPUT -i eth0 -m unclean -j DROP
non sono previste opzioni per tale modulo.
L'unico scopo del modulo unclean è quello di individuare i pacchetti
sospetti, e a tale proposito sono implementati una serie di check che
operano sui diversi protocolli.
In dettaglio le funzioni che si occupano dei suddetti controlli sono
check_icmp, check_udp, check_tcp e check_ip definite nel file
/net/ipv4/netfilter/ipt_unclean.c all'interno del kernel di Linux [6].
Le operazioni eseguite da queste funzioni sono quelle elencate nella
prima parte di questo articolo, alcune le abbiamo viste in dettaglio
nella descrizione di scrub, ed in sostanza restano ancora valide per
IPTables.
Il coreteam di Netfilter ha deciso di rimuovere il modulo ipt_unclean
dal kernel 2.6 di Linux.
Ecco come spiega questa decisione Harald Welte, sulla mailing list
netfilter-devel@, in risposta ad una domanda riguardante unclean:
From: laforge<at>gnumonks<dot>org (Harald Welte)
Date: Mon, 15 Sep 2003 11:52:04 +0200
Subject: missing ipt_unclean support in 2.6test5
In-Reply-To: <20030914200347.GA811@baryon>
References: <20030914200347.GA811@baryon>
Message-ID: <20030915095204.GC777@obroa-skai.de.gnumonks.org>
On Sun, Sep 14, 2003 at 10:03:47PM +0200, garde<at>benben<dot>com wrote:
> I just saw ipt_unclean matching support was removed from the 2.6 tree,
> is there a place I can find some background on the reason behind this?
> Couldn't find anything on the lkml or google that provided a better
> reason than "we feel it's a rather insecure part of the netfilter code".
What more background do you want to have? The netfilter coreteam has
made this decision at the recent netfilter developer conference, because
we think it is a dangerous match.
Filtering like the unclean match can easily introduce
forwards-compatibility problems. Just look what happened when the ECN
bits in the ip and tcp header had been defined for congestion
notification by the IETF: suddenly everybody sending packets adhering to
this new standard was unable to reach any machine/network protected by a
netfilter/iptables firewall that used the unclean match.
We just want to make sure that this doesn't ever happen again. We were
unable to remove ipt_unclean in 2.4.x because of compatibility reasons.
But now in 2.6 it is easy to have it removed.
Harald Welte
Conclusioni
Abbiamo visto che la direttiva scrub di PF e il modulo unclean di
IPTables (che ad essere precisi, non è un normalizzatore nel vero senso
del termine), non sono confrontabili per funzionalità e stabilità (il
modulo unclean è ancora indicato come "experimental").
Abbiamo anche visto che basta un dispositivo, relativamente semplice,
per evitare numerosi grattacapi ai NIDS e ai firewall, ma anche alle
normali applicazioni; è anche chiaro che messo da solo a guardia di una
rete, un normalizer, serve davvero a ben poco.
Request for Comments
RFC0791: Internet Protocol Specification
RFC0793: Transmission Control Protocol Specification
RFC2460: Internet Protocol, Version 6 (IPv6) Specification
RFC2675: IPv6 Jumbograms
http://www.ietf.org/rfc/