Newsgroup: it.comp.os.linux.sys
Titolo: Numero regole iptables

Salve a tutti.
Mi chiedevo se c'è un numero di regole oltre il quale iptables inizia
a barcollare. Lo so che è una domanda un po' strana, ma ho una
macchina sulla quale è caricato un insieme di regole con quasi 250.000
(250mila) regole di DROP, e mi sono accorto che il processore fa un
po' di fatica.
La macchina è un server non proprio malaccio (Pentiun 4 3 GHz, con 2
GB di RAM in 4 banchi dual-channel), e se attivo le regole il
processore si fissa al 25% di media, L'I/O rallenta e le ventole
inizano a ronzare sensibilmente (prima si sentivano a malpena).
Dite che il numero di regole è un po' troppo alto, e il match de i
pacchetti in ingresso non è proprio un giochetto? C'è modo di
ottimizzare il processo?
Grazie per l'attenzione, ciao!
GePs

 ottimizzare il processo?
Sicuramente ridurre il numero delle regole; ma per ridurre non intendo
toglierne un centinaio .. Certo che riscrivere le regole, giunti a questo
punto, non sarà cosa semplice né breve. Per prima cosa invertirei la
politica, passando da una "-P accept" ad una "-P drop"; poi però
bisognerebbe evitare di scrivere migliaia di regole di accept. Una prima
tecnica è senz'altro quella di cercare elementi in comune a molte regole in
modo di raggrupparle, per esempio individuare intervalli di indirizzi o di
porte: invece di scrivere una regola per ognuno di 254 indirizzi
consecutivi se ne scrive una soltanto per la sottorete. Un secondo passo
necessario potrebbe essere ristrutturare la rete; se, sempre per esempio,
hai una sottorete di classe B di cui gli indirizzi pari devono poter
accedere al web e gli indirizzi dispari no .. Bene, il resto si capisce:
questo secondo passo potrebbe essere necessario per applicare il primo in
modo efficace.
-- 
Lorenzo Vaina, MCP

 (250mila) regole di DROP, e mi sono accorto che il processore fa un
 
azz ... io avevo scritto a mano circa 600 regole ... ma le tue 250.000 
sono al di la' di ogni immaginazione.
le hai scritte tutte una per una ?
perdona la curiosita'
-- 
-------------------------------------------------
linux slackware
tutto il resto e' inutile
-------------------------------------------------

 Il punto e' che ogni regola deve essere analizzata per ogni pacchetto.
A questo punto credo che cercherò un'altra soluzione...

 perdona la curiosita'
No, le ho prese da una black list...

 C'č modo di ottimizzare il processo?
Sě, usare correttamente le chain e tentare di diminuire sensibilmente il
numero di check per ogni pacchetto.
Potresti per esempio cominciare a mettere in piedi un tree di chain; quindi
cominci a suddividere le regole di blacklisting in piů chain e attraversi
solo una parte di esse.
Un esempio č il seguente: supponi di voler bloccare gli indirizzi IP:
1.2.3.4,  2.3.4.5,  3.4.5.6,  4.5.6.7,  5.6.7.8,  6.7.8.9
Crei le chain cosě:
iptables -N C1
iptables -N C2
iptables -N C11
iptables -N C12
iptables -N C21
iptables -N C22
iptables -A INPUT -s 
0.0.0.0/6
 -j C1
iptables -A INPUT -s 
4.0.0.0/6
 -j C2
iptables -A C1 -s 
0.0.0.0/7
 -j C11
iptables -A C1 -s 
2.0.0.0/7
 -j C12
iptables -A C2 -s 
4.0.0.0/7
 -j C21
iptables -A C2 -s 
6.0.0.0/7
 -j C22
iptables -A C11 -s 1.2.3.4 -j DROP
iptables -A C11 -s 2.3.4.5 -j DROP
iptables -A C12 -s 3.4.5.6 -j DROP
iptables -A C21 -s 4.5.6.7 -j DROP
iptables -A C21 -s 5.6.7.8 -j DROP
iptables -A C21 -s 6.7.8.9 -j DROP
A questo punto il numero di check per pacchetto č asintotico a O(log n)
invece che a O(n). Se fai una dicotomica perfetta hai massimo 32 controlli
al posto dei medi 125000 del metodo lineare.
-- 
Flavio Visentin
Scientists have finally discovered what's wrong with the female brain:
On the left side, there is nothing right, and on the right side, there
is nothing left.

 al posto dei medi 125000 del metodo lineare.
:)
Sarebbe proprio interessante scrivere qualcosa che mi riorganizza le
regole in modo più intelligente... peccato non avere né tempo né
capacità (ma più il tempo, che sono sicuro che alla fine potrei anche
farcela...)

 
potresti mettere un firewall a parte rispetto al sistema da proteggere.

 Il punto e' che ogni regola deve essere analizzata per ogni pacchetto.
Solo se il ruleset č scritto da uno scimpanzč.

 Solo se il ruleset è scritto da uno scimpanzè.
O generato da uno script perl...

 farcela...)
#!/bin/bash
[ -z "$1" ] && echo "Usage: $0 blacklist_file" && exit 1
IPTABLES="echo iptables"
for ((i=0;i<8;i++)); do
    $IPTABLES -N C$i
    $IPTABLES -A INPUT -s $(($i*32)).0.0.0/3 -j C$i
    for ((j=0;j<8;j++)); do
        $IPTABLES -N C$i$j
        $IPTABLES -A C$i -s $(($i*32)).$(($j*32)).0.0/11 -j C$i$j
        for ((k=0;k<8;k++)); do
            $IPTABLES -N C$i$j$k
            $IPTABLES -A C$i$j -s $(($i*32)).$(($j*32)).$(($k*32)).0/19 \
                      -j C$i$j$k
        done
    done
done
cat $1 | while read ip
do
    for ((i=0;i<4;i++)); do
       I[$i]=$(echo $ip | cut -f$(($i+1)) -d'.')
    done
    $IPTABLES -A C$((${I[0]}/32))$((${I[1]}/32))$((${I[2]}/32)) -s $ip \
              -j DROP
done
Ovviamente non ha la pretesa né di essere perfetto né di essere veloce, ma
dovrebbe funzionare (provare per credere). Basta dargli in pasto un file con
un indirizzo IP per ogni riga.
Dovrebbe ridurre a circa 4100 il numero medio di verifiche per pacchetto; Le
catene C7* potresti evitare di crearle ovviamente ;-)


 attraversi solo una parte di esse.
Io sono convinto che netfilter non sia stato progettato per questo scopo:
anche in questo modo (sicuramente il più corretto) le 250000 regole vanno
ugualmente caricate in memoria, anzi, col sistema bit a bit
(attraversamento di 32 regole) il numero delle regole esistenti cresce
discretamente. Penso che un programma user space che confrontasse
l'indirizzo contro un database sarebbe più efficiente. 
Comunque se deciderai di continuare ad usare netfilter ricorda di aggiungere
IN TESTA una regola accept per --state related, established; una
comunicazione nuova dovrà comunque superare la blacklist, una comunicazione
già stabilita non sarebbe stata stabilita se fosse appartenuta alla
blacklist; questo dovrebbe già migliorare parecchio le cose però non
pensare neppure per un attimo che basti e se lascerai le cose come sono per
piacere non dare la colpa a me.
-- 
Lorenzo Vaina, MCP

 O generato da uno script perl...
Non cambia nulla. Anche lo script puň esser scritto per generare un
ruleset un minimo ottimizzato.
Il fatto che lo script -di per sč- non sia dotato di ragione non
significa che non debba esserne dotato chi lo script lo scrive...
Anzi: realizzare ruleset con struttura ad albero del tipo che citava
ZipMan č *enormemente* piů facile se lo si fa da script che non se lo si
fa a mano...

 po' di fatica.
per ogni pacchetto deve controllare nel caso peggiore 250.000 regole e
ti stupisci il server ne risenta?
Prova nfqueue, probabilmente ti risolve molti problemi, un semplice
howto: 
http://www.debian-administration.org/articles/540
HTH, Micky
-- 
What's this hash prompt on my terminal mean?
Micky Del Favero  -  System Manager  &  BOFH

 po' di fatica.
Forse ipset o nf-hipac possono aiutarti. Il primo potrebbe essere
sufficiente, se l'uso e' del tipo blacklist.
Fabio

 di infima qualita' (altrimenti si fermerebbe prima). claro?
Non è tanto per la qualità dell'automatismo: come dice il messaggio
precedente per fare quello che servirebbe a me la cosa migliore
sarebbe un programma in userspace che confronti i source con un db: e
infatti la blacklist che ho io è appunto un export di un db di un
programma che fa questo. Lo script non fa altro che tradurre la cosa
in regole digeribili da netfilter/iptables, magari lo fa male, ma
sicuramente ci sono margini di miglioramento, come ad esempio lo
script proposto da THe_ZiPMaN.

 fa a mano...
Ne sono convinto.


Grazie a bio e Micky per i suggerimenti, mi informerò