Questo documento è un viaggio che in alcune parti sarà molto comodo mentre
in altre vi farà sentire abbandonati a voi stessi.
Il miglior consiglio che vi posso dare è di prendere una grossa, intima
tazza di caffè o di cioccolata calda, di procurarvi una confortevole sedia e,
prima di avventurarvi nel mondo a volte pericoloso del network hacking, di assorbirne il contenuto.
Per comprendere meglio come utilizzare l'infrastruttura presente
al di sopra del framework netfilter, raccomando di leggere il
Packet Filtering HOWTO e il NAT HOWTO.
Per informazioni riguardanti la programmazione del kernel suggerisco
la Rusty's Unreliable Guide to Kernel Hacking e la Rusty's Unreliable
Guide to Kernel Locking.
netfilter è un framework per il manipolamento dei pacchetti, esterno
alla normale interfaccia socket Berkeley.
Consta di 4 parti. Prima parte, ogni protocollo definisce degli
"hook" (IPv4 ne definisce 5) i quali sono punti ben definiti in una traversata
dei pacchetti nel protocol stack.
In ciascuno di questi punti, il protocollo richiamerà il framework netfilter
fornendo il pacchetto e il numero dell'hook.
Seconda parte, porzioni del kernel possono registrarsi per "ascoltare",
per ogni protocollo, differenti hook.
Perciò quando un pacchetto è passato al framework netfilter, esso
controlla se qualcuno si è registrato per quel determinato protocollo e hook;
se sì, a ciascuno di essi è data, in ordine, una chance per esaminare (e possibilmente alterare)
il pacchetto, eliminarlo (NF_DROP), consentirgli di proseguire
(NF_ACCEPT), indicare a netfilter di dimenticarsi di esso (NF_STOLEN),
oppure ancora di chiedere a netfilter di accodarlo per lo userspace (NF_QUEUE).
Terza parte, i pacchetti che sono stati accodati sono sistemati (dal driver
ip_queue) per essere inviati allo userspace; questi pacchetti sono gestiti
in modo asincrono.
La parte finale consiste in splendidi commenti sul codice e nella documentazione.
Questa è strumentale per ogni progetto sperimentale.
Il motto di netfilter (rubato spudoratamente a Cort Dougan) è:
``Orbene... quanto è meglio di KDE?''
(Questo motto si affianca a `Frustami, colpiscimi, fammi utilizzare ipchains').
In aggiunta a questo framework grezzo sono stati realizzati
vari moduli che forniscono funzionalità simili ai kernel
precedenti (pre-netfilter), in particolare un sistema NAT e uno di filtraggio dei pacchetti
(iptables) entrambi estendibili.
infrastruttura per il passaggio dei pacchetti allo userspace non radicata:
Programmare il kernel è complicato
Il codice per il kernel deve essere sviluppato in C/C++
Tattiche di filtraggio dinamico non sono collocate nel kernel
2.2 ha introdotto la copia dei pacchetti verso lo userspace attraverso
netlink, ma la reintroduzione è lenta e soggetta a controlli di `sanità'.
Ad esempio, non è possibile avere pacchetti reimmessi che sostengono di
arrivare da un'interfaccia esistente.
Il proxy trasparente è un "accrocchio":
ogni pacchetto è controllato per stabilire se esiste
un legame socket con questo indirizzo
Al root è consentito di collegarsi ad indirizzi estranei
Non è possibile redirigere i pacchetti generati localmente
REDIRECT non gestisce le risposte UDP: redirigere pacchetti UDP named
verso 1153 non funziona in quanto alcuni client non gradiscono risposte
provenienti da una porta che non sia la 53.
REDIRECT non è coordinata con l'allocazione delle porte tcp/udp:
un utente può ottenere una porta shadow attraverso una regola REDIRECT.
E' risultato corrotto almeno due volte durante la serie 2.1.
Il codice è estremamente intrusivo. Si considerino le statistiche
del numero di #ifdef CONFIG_IP_TRANSPARENT_PROXY presenti nella 2.2.1:
34 occorrenze in 11 file.
Le si confrontino con CONFIG_IP_FIREWALL, il quale ha 10 occorrenze in 5 file.
Creare regole di filtraggio dei pacchetti indipendenti dagli indirizzi
delle interfacce non è possibile:
E' necessario conoscere gli indirizzi locali delle interfacce per
distinguere pacchetti generati localmente o destinati localmente, da
quelli in transito.
Non è sufficiente però nei casi di redirezione o mascheramento.
La catena forward ha solo l'informazione riguardante l'interfaccia di uscita,
ciò significa che è necessario immaginare da dove arriva un pacchetto
in base alle conoscenze sulla topografia della rete.
Il mascheramento è incluso nel filtraggio dei pacchetti:
interazioni tra filtraggio dei pacchetti e mascheramento rendono
complessa la realizzazione del firewall:
Al filtraggio in input, i pacchetti in risposta appaiono destinati alla
box stessa
Al filtraggio nella forward, i pacchetti demascherati non sono visti del tutto
Al filtraggio in output, i pacchetti appaiono provenienti dalla box locale
manipolazione TOS, redirezione, ICMP unreachable e marcamento
(che riguarda port forwarding, instradamento e QoS) sono collocati
assieme al codice di filtraggio.
il codice di ipchains non è né modulare, né estendibile (per esempio
filtraggio per indirizzo, filtraggio in base alle opzioni, ecc.).
La mancanza di un'infrastruttura adeguata ha portato alla proliferazione di
differenti tecniche:
Mascheramento, più moduli per protocollo
Fast static NAT attraverso il codice di instradamento (senza gestione per protocollo)
Port forwarding, redirezione, auto forwarding
Linux NAT e progetti Server Virtuale.
Incompatibilità tra CONFIG_NET_FASTROUTE e filtraggio dei pacchetti:
Pacchetti in transito attraversano in ogni caso tre catene
Nessun modo per segnalare se queste catene possono essere oltrepassate.
L'ispezione dei pacchetti scartati a causa della protezione di instradamento
(es. Source Address Verification) non è possibile.
Nessun modo per leggere atomicamente i contatori delle regole di filtraggio dei pacchetti.
L'opzione CONFIG_IP_ALWAYS_DEFRAG è da selezionare in fase di compilazione,
ciò rende difficile la vita alle distribuzioni che desiderano un kernel con funzionalità generiche.
Sono l'unico tanto insensato disponibile a farlo.
Come coautore di ipchains e attuale manutentore del Linux Kernel IP Firewall
ho conosciuto molti dei problemi incontrati dalle persone con l'attuale sistema,
in aggiunta mi sono anche esposto a cercare di comprendere cosa cercavano di fare.
Siccome non sono un così grande programmatore, come noi tutti potremmo desiderare,
sicuramente non ho esaminato tutti gli scenari, a causa di mancanza di tempo,
attrezzatura e/o ispirazione.