2008-09-20 9 views
36

Ho bisogno di interrogare le regole esistenti, oltre ad essere in grado di aggiungere e cancellare facilmente le regole. Non ho trovato alcuna API per farlo. C'è qualcosa che mi manca?Come posso gestire in modo programmatico le regole di iptables al volo?

Il più vicino a una soluzione è l'utilizzo di iptables-save | iptables-xml per l'interrogazione e la chiamata manuale del comando iptables stesso per aggiungere/eliminare regole. Un'altra soluzione che ho considerato è semplicemente la rigenerazione dell'intero set di regole dal database della mia applicazione e il lavaggio dell'intera catena, quindi l'applicazione di nuovo. Ma voglio evitare questo perché non voglio rilasciare alcun pacchetto, a meno che non ci sia un modo per farlo atomicamente. Mi chiedo se c'è un modo migliore.

Un'AP in C sarebbe ottima; tuttavia, poiché sto pianificando di creare questo in un programma suideo autonomo, anche le librerie che fanno questo in QUALUNQUE lingua vanno bene.

+0

Apparentemente è possibile passare da XML a iptables-restore 'xsltproc iptables.xslt my-iptables.xml | iptables-restore'. Vedi la pagina di manuale di 'iptables-xml'. – CMCDragonkai

risposta

3

Non esiste deliberatamente alcuna API per gestire queste regole. Non dovresti volerlo fare. O qualcosa.

Se avete bisogno di regole che sono sufficientemente dinamico vi preoccupate per le prestazioni di esecuzione/sbin/iptables, ci sono altri modi per farlo:

  • usando qualcosa come il "recente" corrispondenza partita o set IP , è possibile aggiungere/rimuovere gli indirizzi IP dagli elenchi in bianco/nero senza modificare il set di regole.
  • È possibile passare i pacchetti in userspace per il filtraggio utilizzando NFQUEUE
+4

Mi sembra sciocco che non ci siano API per questo. Non mi interessa davvero le prestazioni in quanto tali, ma chiamare iptables sembra un modo orribilmente hacky di fare le cose. – Ycros

+0

Hmm, potrei usare ipset - e dal punto di vista delle prestazioni è davvero una buona idea. Sfortunatamente dovrei girare il mio kernel, e questo non è possibile in quanto alcuni dei posti in cui verrà eseguito questo software sono su macchine virtuali in cui non riesco a fare confusione con il kernel facilmente. E ancora non forniscono una bella API. – Ycros

+0

ipt_recent è una destinazione di corrispondenza standard di iptables che consente di aggiungere/rimuovere dinamicamente gli indirizzi IP da un set scrivendo in un file in/proc senza modificare le regole. D'altra parte, non è destinato a grandi serie di IP e sembra avere un limite massimo fisso. – MarkR

0

diritto di MarkR, non si dovrebbe fare questo. Il modo più semplice è chiamare iptables dallo script o scrivere la configurazione di iptables e "ripristinarla".

Ancora, se si desidera, leggere la fonte di iptables. iptables usa le corrispondenze e le tabelle come oggetti condivisi. Puoi usare la fonte o loro.

Il netfilter Linux ha anche alcuni file include in/usr/include/netfilter *. Queste sono funzioni un po 'di basso livello. È quello che usa iptables. Questa è l'API più vicina a quella che si può ottenere senza iptables.

Ma questa API è "disordinata". Ricordare che è stato progettato per essere utilizzato solo da iptables. Non è molto ben documentato, è possibile riscontrare problemi molto specifici, l'API può cambiare abbastanza rapidamente senza alcun preavviso, quindi un aggiornamento può spezzare il codice, ecc.

+2

Posso accettare che l'utilizzo di API interne sia negativo, ma perché è così grave che non includano deliberatamente un'API pubblica? Potrei andare a fare un ripristino se posso fare un ripristino di una singola catena: dovrò fare dei test. – Ycros

+0

Sì, è possibile ripristinare una singola catena. :-) –

+0

Lì, nella risposta. – terminus

4

Per quanto ne so (anche se nessun riferimento sembra menzionare it), iptables-restore è atomico. Alla fine, quando la riga COMMIT viene letta, iptables chiama iptc_commit in libiptc (che in un'interfaccia interna non si suppone di utilizzare), che quindi chiama setsockopt(SO_SET_REPLACE) con i nuovi set di regole.

Questo sembra il più atomico possibile: con una chiamata al kernel. Tuttavia, le parti più informate sono invitate a contestarlo. :-)

Modifica: Posso confermare che la descrizione è corretta. iptables-restore viene eseguito come operazione atomica nel kernel.

Per essere ancora più specifico l'operazione "solo" è atomica su base CPU. Mentre immagazziniamo l'intero BLOB delle regole per CPU (a causa delle ottimizzazioni della cache).

16

Dal netfilter FAQ:

La risposta, purtroppo, è: No.

Ora si potrebbe pensare 'ma per quanto riguarda libiptc?'. Come è stato sottolineato numerose volte sulla mailinglist (s), libiptc era MAI pensato per essere usato come interfaccia pubblica. Non garantiamo un'interfaccia stabile e si prevede di rimuoverlo nella prossima incarnazione del filtraggio dei pacchetti linux. libiptc è troppo troppo basso per essere usato in ogni caso ragionevolmente.

Siamo consapevoli che esiste una mancanza fondamentale per tale API e stiamo lavorando per migliorare tale situazione. Fino ad allora, si consiglia di utilizzare system() o aprire una pipe in stdin di iptables-restore. Quest'ultimo ti darà un modo di migliorare le prestazioni.

+0

Mi chiedo perché le FAQ non affrontano il problema dell'atomicità. Dovrebbe; Mi sono preso la briga di guardare all'implementazione di iptables-restore solo per essere sicuro che sia atomico. È importante per l'OP qui, e ho anche avuto un progetto che lo richiedeva. –

+1

Questo post sulla mailing list di netfilter dice che iptables-restore è atomico: http://www.mail-archive.com/[email protected]/msg00456.html –

+0

Per i più coraggiosi che vogliono ancora farlo, ci sono alcune informazioni qui: http://www.netfilter.org/documentation/HOWTO/netfilter-hacking-HOWTO-4.html#ss4.2 – Roman

12

L'utilizzo di iptables-save e iptables-restore per eseguire query e rigenerare le regole è facilmente il modo più efficiente per farlo. Questi, una volta, erano gli script di shell, ma ora sono programmi C che funzionano in modo molto efficiente.

Tuttavia, devo sottolineare che esiste uno strumento che è possibile utilizzare per semplificare la manutenzione di iptables. La maggior parte dei set di regole dinamiche sono in realtà la stessa regola ripetuti molte volte, come ad esempio:

iptables -A INPUT -s 1.1.1.1 -p tcp -m --dport 22 -j ACCEPT 
iptables -A INPUT -s 2.2.2.0/24 -p tcp -m --dport 22 -j ACCEPT 
iptables -A INPUT -p tcp -m tcp --dport 22 -j REJECT 

Invece di sostituire quelle regole ogni volta che si desidera cambiare ciò che le porte possono accedere alla porta 22 (utile per esempio, porta bussare), è possibile utilizzare ipset. Viz:

ipset -N ssh_allowed nethash 
iptables -A ssh_allowed -m set --set ssh_allowed src -p tcp -m --dport 22 -j ACCEPT 
ipset -A ssh_allowed 1.1.1.1 
ipset -A ssh_allowed 2.2.2.0/24 

I set possono contenere indirizzi IP, reti, porte, indirizzi mac e hanno timeout nei loro record. (Hai mai voluto aggiungere qualcosa per solo un'ora?).

C'è persino un modo atomico di scambiare un set con un altro, quindi un aggiornamento significa creare un nuovo set temporaneo, quindi sostituirlo con il nome del set esistente.

+0

Aye, la risposta in alto ha menzionato ipset, ma come ho detto in un commento lì - richiede un modulo del kernel che non è in Ubuntu di default, e non è qualcosa che posso installare su una qualsiasi VM che utilizzo. – Ycros

+1

Sì, ho segnalato questo bug nel gennaio '07. https://bugs.launchpad.net/ubuntu/+source/ipset/+bug/79182 – Jerub

+2

Ubuntu ora supporta ipset in modo adeguato. – Jerub

1

Questa mattina mi sono svegliato per scoprire che stava ottenendo un attacco Denial Of Service (DOS) dalla Russia. Mi stavano colpendo da dozzine di blocchi IP. Devono avere o un ampio pool di IP o una sorta di elenco/servizio proxy. Ogni volta che ho bloccato un IP, ne è spuntato un altro. Alla fine, ho cercato uno script e ho scoperto che avevo bisogno di scrivere la mia soluzione. Quanto segue è un po 'aggressivo, ma stavano eseguendo il mio LIVELLO DI CARICO SUPERIORE a più di 200.

Ecco uno script veloce che ho scritto per bloccare il DOS in tempo reale.

cat **"output of the logs"** | php ipchains.php **"something unique in the logs"** 

==> PHP Script:

<?php 

$ip_arr = array(); 

while(1) 
{ 
    $line = trim(fgets(STDIN)); // reads one line from STDIN 
    $ip = trim(strtok($line, " ")); 

    if(!array_key_exists($ip, $ip_arr)) 
     $ip_arr[$ip] = 0; 

    $regex = sprintf("/%s/", $argv[1]); 

    $cnt = preg_match_all($regex, $line); 

    if($cnt < 1) continue; 

    $ip_arr[$ip] += 1; 

    if($ip_arr[$ip] == 1 ) 
    { 
//  printf("%s\n", $argv[1]); 
//  printf("%d\n", $cnt); 
//  printf("%s\n", $line); 

     printf("-A BLOCK1 -s %s/24 -j DROP\n", $ip); 

     $cmd = sprintf("/sbin/iptables -I BLOCK1 -d %s/24 -j DROP", $ip); 
     system($cmd); 
    } 
} 

?> 

Ipotesi:

1) BLOCK1 is a Chain already created. 
2) BLOCK1 is a Chain that is run/called from the INPUT CHAIN 
3) Periodically you will need to run "ipchains -S BLOCK1" and put output in /etc/sysconfig file. 
4) You are familiar with PHP 
5) You understand web log line items/fields and output. 
0

Questo è un esempio di utilizzo bash e iptables di bloccare dinamicamente hacker abusano sshd su CentOS . In questo caso, ho configurato sshd per disabilitare il login della password (consente le chiavi). Guardo in/var/log/secure per le voci di "Bye Bye", che è il modo educato di sshd di dire f-off ...

IP=$(awk '/Bye Bye/{print $9}' /var/log/secure | 
    sed 's/://g' |sort -u | head -n 1) 

[[ "$IP" < "123" ]] || { 

    echo "Found $IP - blocking it..." >> /var/log/hacker.log 

    /sbin/iptables -A INPUT -s $IP -j DROP 

    service iptables save 

    sed -i "/$IP/d" /var/log/secure 

} 

Lo eseguo in un ciclo ogni secondo o minuto o qualsiasi cosa mi renda felice. Verifica il valore di $ IP per verificare che abbia trovato un valore utile, in tal caso invoco iptables per rilasciarlo, e uso sed per eliminare il file di log di $ IP in modo che la voce non venga aggiunta di nuovo.

Faccio un po 'di pre-elaborazione (non mostrato) alla lista bianca di alcuni IP importanti che sono sempre validi e che potrebbero aver avuto problemi di connessione (a causa di un errore dell'utente).

Di tanto in tanto, classifico l'elenco di filtri iptables e creo intervalli IP da essi (utilizzando uno script diverso - e quando selezionato, sono solitamente intervalli IP da India, Cina e Russia). Pertanto, la mia regola generale del filtro iptables rimane tra 50 e 500 voci; Ipset non migliora molto su una lista così breve.

+1

Qual è il significato del numero 123? Se si desidera verificare di avere un indirizzo IP valido esaminando il valore del primo ottetto, credo che potrebbe essere qualsiasi cosa fino a 223. – tripleee

+0

Questo non è un test di alcun ottetto. Se durante l'analisi di/var/log/secure si finisce con un campo vuoto o corrotto, si verifica il valore per non eseguire il comando iptables. Il valore "123" era piuttosto arbitrario. Nel test di questo un po 'di più, ho trovato probabilmente dovrebbe sostituire' 123 'con' 1 'per includere un intervallo IP completo, però. Quando si verifica un IP inferiore a '123', sarà vero per gli indirizzi IP nell'intervallo da 2.0.0.0 a 255.255.255.255, quindi non bloccherà gli IP nell'intervallo 1.x.x.x. Quando il test di IP è inferiore a "1", corrisponde a 0.0.0.1 a 255.255.255.255. – Andrew

5

Si può considerare l'utilizzo di rfw che è l'API REST per iptables. Sta serializzando i comandi di iptables da varie fonti potenzialmente concorrenti e esegue in remoto iptables al volo.

rfw è progettato per sistemi distribuiti che tentano di aggiornare le regole del firewall su più caselle ma può essere eseguito anche su una singola macchina sull'interfaccia localhost. Quindi consente di evitare l'overhead SSL e di autenticazione in quanto può essere eseguito su un semplice HTTP in questo caso.

Comando di esempio:

PUT /drop/input/eth0/11.22.33.44 

che corrisponde a:

iptables -I INPUT -i eth0 -s 11.22.33.44 -j DROP 

È possibile inserire ed eliminare le regole così come query per lo stato attuale per ottenere le regole esistenti in formato JSON:

GET /list/input 

Disclaimer: Ho iniziato questo progetto. È open source con licenza MIT.

+0

Se è su HTTP, non è pericoloso per un firewall? –

+0

Come indicato sopra, il valore predefinito è HTTPS. Esiste un'opzione per disabilitare SSL e usare un semplice HTTP, utile quando si esegue su localhost in un singolo ambiente utente. –

+0

Tutto ciò che manipola il firewall "programmaticamente"/in remoto e/o automaticamente è pericoloso. Tuttavia, un'adeguata sicurezza in atto può mitigare questo, cioè i token/2fa di sso dietro un gateway API (come il kong) farebbero molto per soddisfare i propri bisogni di sicurezza. –