PDA

View Full Version : sempre sul firewalling...


NA01
08-05-2006, 07:35
funziona così. ho sviluppato un firewall a livello applicativo (che qualcuno conoscerà come Minox, qualcuno come Viciux, e molti non lo conosceranno per nulla :sofico: ).
quando arriva una nuova connessione la intercetto, risalgo al processo che la ha generata girando a babbo su /proc a caccia dell'inode della socket e una volta che la ha beccata controlla che il suo eseguibile e le librerie condivise abbiano l'autorizzazione a collegarsi (e eventualmente la richiede al client).
funziona più o meno tutto, come note metterei che il berkeley che uso per memorizzarle è un pò troppo delicatuccio e che ogni tanto dà qualche segfault (che conto di sistemare :sofico: ).

problemi:
è peeeeeeesantissimo!!!! codice non ottimizzato sul mio 2000+ mi porta il processore al 90% quando navigo su browser, codice ottimizzato ( livello 2) lo porta la 30%.
il browser è l'attività più pesante che ho trovato (anche perchè apre una connessione per ogni comp'onente se ricordo bene il protocollo), con il resto il carico è accettabile.

i problemi sono probabilmente 2
- l'md5 che uso per controllare le librerie è troppo lento (e in programmazione ho chiesto un sostituto veloce)
- dovrei evitare di controllare tutte queste new...
dopo la prima connessione valida potrei far uscire il pid utilizzando il modulo owner, ( ) il problemuccio è che quando il processo si chiude il pid potrebbe essere assegnato a un'altro processo che avrebbe così un'autorizzazione a babbo... :eek:
e questo non va per nulla bene :sofico:
sarebbe interesante poter sapere quando il programma muore per toglierlo dalle catene.
non so se posso diventare il papà dei miei processi per ricevere un segnale quando uno muore e comunque non mi sembra una soluzione pulita (o no? ).

non saprei che altro fare...
idee?

ilsensine io ti invoco! :sofico:

grazie, ciao!

W.S.
08-05-2006, 08:38
Ma l'hai implementato estendendo iptables (via netlink) o con una socket raw?

Comunque, al posto di cercare il pid di ogni processo all'arrivo di una new, non ti sarebbe più comodo una struttura dati ottimizzata aggiornata continuamente da un processo che fa solo quello?
Controlli l'owner solo all'avvio della connessione? E se il processo crea un figlio e la passa (la stessa cosa di un bof che invoca /bin/sh) che succede?

Le librerie le controlli periodicamente o all'avvio dell'applicazione? Comunque anche in questo caso un processo dedicato con bassa priorità potrebbe tornarti utile, altrimenti usa una funzione meno pesante (xor) ma anche molto meno sicura.

Scusa se ho detto cose inutili o a cui hai gia pensato, ma senza conoscere altro ho dovuto sparare alla cieca...

P.S.: berkeley delicatuccio ????

NA01
08-05-2006, 10:25
Ma l'hai implementato estendendo iptables (via netlink) o con una socket raw?

mi sembrava da sboroni sia l'uno che l'altro :D
al primo non ci ho nemmeno pensato, l'idea di scrivere unmodulo per il kernel mi fa venire brutti incubi :sofico:
il tentativo che ho fatto e` stato a dir poco un disastro :cool:
il secondo mi sembrava un reinventare la ruota...
iptables era gia` pronto, e sa passarmi i pacchetti che voglio in userspace.
e del resto a me basta ricevere le new...
quello che ho fatto e` ricevere i pacchetti di una connessione aperta tramite le libipq con -m --state NEW -j QUEUE (o simile, non vorrei sbagliare la sintassi cosi` a memoria). poi da li` risalgo al pid nel modo in cui ho detto prima, non ono riuscito a trovare altro modo.
ilsensine mi aveva proposto una patch per il kernel che metteva il pid nella struttura che mi passava il programma, ma sulle catene di output freezava tutto...
le modifiche che avevo provato a farci non avevano fatto altro che peggiorare la situazione :D

Comunque, al posto di cercare il pid di ogni processo all'arrivo di una new, non ti sarebbe più comodo una struttura dati ottimizzata aggiornata continuamente da un processo che fa solo quello?

intendi memorizzarmi tutte le connessioni e tirarle fuori dalla mia struttura?
il problema e` che non so come implementarla. il mio unico riferimento attuale sulle connessioni sono
/proc/net/tcp
/proc/net/udp
e non saprei come tenerle sincronizzate in modo affidabile con le mie strutture (a quanto ne so non posso sapere quando un file di /proc cambia).
questo credo che sarebbe piu` semplice con un socket raw, ma mi sa anche che il resto sarebbe ben piu` complesso...

Controlli l'owner solo all'avvio della connessione? E se il processo crea un figlio e la passa (la stessa cosa di un bof che invoca /bin/sh) che succede?

mmmmmh...
io la controllo ogni volta che qualcuno avvia una sequenza di connessione, e poi lascio il permesso di uscita alle RELATED e alla connessione che ha qul pid ed e` aviata con quella riga di comando (tramite il modulo owner di iptables).
qindi non dovrebbe essere un problema.
l'assunzione comunque e` che hai permesso all'applicazione di uscire e la hai marcata come integra. se nulla e` stato modificato quest'applicazione ha il diritto di fare tutto quello che vuole. (rimanendo sul presupposto che tute le new saranno controllate se il pid o il comando che le ha lanciate e` cambiato.

Le librerie le controlli periodicamente o all'avvio dell'applicazione? Comunque anche in questo caso un processo dedicato con bassa priorità potrebbe tornarti utile, altrimenti usa una funzione meno pesante (xor) ma anche molto meno sicura.

le librerie ora come ora le controllo solo in avvio, e suppongo che non sia safe su un sistema come linux che ti permette di scrivere su file aperti...
io avevo pensato di appoggiarmi a un demone che mi rilevasse le modifiche sui file (ne avevo visti un paio su cui si appoggiano i vari filemanager), e solo allora avviae i miei controlli.
lo xor e` un po` tanto poco sicuro, no?

Scusa se ho detto cose inutili o a cui hai gia pensato, ma senza conoscere altro ho dovuto sparare alla cieca...

e che ti scusi a fare? anzi, dovrei ringraziarti ;) ogni idea e` sempre utile :)
appena quella burlona della telecom si riattacca e mi da` un ip pubblico e fisso (ora sono su fastweb) metto tutto l'svn online, cosi` chi vuole puo` dare un occhio ai sorgenti (che intanto saranno sotto gpl ;))

P.S.: berkeley delicatuccio ????
bho, ho recuperato sempre il database, ma intervenendo a mano...
tieni conto che l'applicazione e` in fase di sviluppo e e` alquanto instabile (poi da quando ieri ho cambiato tutto il parser e` diventata MOLTO instabile :sofico: ), quindi e` abbastanza all'ordine del giorno che il programma si chiuda con un segfault senza avvertire nessuno :cool: .
sinceramente pero` mi aspettavo che proteggendo le scritture con delle transazioni mi desse molti meno problemi anche chiudendo tutto in punti a babbo...

grazie di nuovo, ciao!

W.S.
08-05-2006, 11:22
sisi, il QUEUE comunica via netlink in userspace, pure io penso sia la soluzione migliore.

l'idea era avere una struttura (lista/albero/quello che ti pare organizzato in base ad un parametro che ti passa queue, es porta locale) nel programma contenente i dati di /proc che ti servono e un processo dedicato ad aggiornare questa lista ogni volta che cambia qualcosa nelle directory che dicevi (udp e tcp) in modo da evitare di ravanare tutte le volte alla ricerca del file giusto, il problema potrebbe essere che una connessione nuova arriva prima dell'aggiornamento, bisognerebbe rallentare un po la risposta per essere sicuri di aver aggiornato la struttura... bho, magari pensandoci un po ste cosa si rivela una st*****ta :stordita:

La domanda sull'owner m'è venuta per il controllo delle librerie, come funziona? Registri da qualche parte che libreria usa il processo e ti assicuri che non ne esegua altre e che siano sempre quelle o hai una lista di librerie "abilitate" che controlli? Comunque, per evitare quello che dicevo basta usare il modulo owner di iptables, c'ho pensato dopo :D

si, lo xor è un po tanto poco sicuro, ma è una scheggia ;) dipende quanto vuoi controllare le librerie, secondo me hai una buona possibilità di beccare le modifiche, basta usare dei segmenti abbastanza lunghi... poi pure questo è da verificare. L'idea è quella di ricavare l'hash spezzettando la libreria in tanti segmenti lunghi quanto l'hash e xorandoli tutti... ripeto: bho :D
Comunque il demone penso sia la soluzione migliore

NA01
10-05-2006, 14:04
mmmmmh...
vedro` che fare con lo xor...
magari lascio l'opzione per l'md5 per chi ha voglia di perdere dei cicli di calcolo :sofico:

pero` ho un problemuccio....
ho letto giusto ora che i moduli owner di iptables funzionano solo sulle chains di output, tanto vale usare la patch del kernel per ilsensine...
nelle catene di input come me la gestisco???
potrebbe essere un problemaccio...
andare a mettere le mani sul kernel per scoprire dove assegna il pacchetto al pid potrebbe essere un grossissimo problema (almeno per me)...
senza contare che a ogni revisione del kernel rischierei di avere delle patch incompatibili e che l'idea di patchare e ricompilare il kernel ben pocco si sposa con l'idea di fare qualcosa per chi non ha le competenze o la voglia per imparare la sintassi di iptables...

porca pupazzola...
tante new in entrata porterebbero il sistema a un carico non indifferente se le scansiono una a una per cercare gli hash delle librerie.

ci sono altri modi che voi sappiate?

ciao!