Gentoo Logo

Disclaimer : La versione originale di questo articolo è stata pubblicata da IBM developerWorks ed è di proprietà di Westtech Information Services. Questo documento è una versione aggiornata dell'articolo originale, e contiene numerosi miglioramenti apportati dal Gentoo Linux Documentation team.
Questo documento non è mantenuto attivamente.


Firewall dinamici con iptables

Indice:

1.  Introduzione

Sicurezza delle Reti flessibile (e divertente)

Il modo migliore per vedere i benefici di script dinamici per il firewall è vederli in azione. Per fare ciò, si immagini che io sia un amministratore di sistema presso un ISP, e che io abbia recentemente configurato un firewall "Linux-based" per proteggere i miei clienti e i sistemi interni da utenti malvagi presenti in Internet. Per fare ciò, il mio firewall usa la nuova funzionalità stateful di iptables di Linux 2.4 per consentire alle connessioni in uscita dei miei clienti e dei miei server di essere stabilite, e per consentire naturalmente nuove connessioni in entrata, ma solo verso servizi "pubblici", come web, ftp, ssh, e SMTP. Poiché ho utilizzato una configurazione deny-by-default, ogni connessione proveniente da Internet verso servizi non pubblici, come la cache del proxy Squid o il server Samba, sono automaticamente rifiutate. A questo punto, ho un firewall piuttosto buono che offre un buon livello di protezione a chiunque sia connesso al mio ISP.

Per la prima settimana o poco più, il firewall funziona benone, ma poi accade qualcosa di terribile. Bob, la mia nemesi maligna (che lavora ad un ISP concorrente) decide di inondare la mia rete con pacchetti nel tentativo di negare il servizio ai miei clienti. Sfortunatamente, Bob ha studiato con attenzione il mio firewall e sa che mentre io sto proteggendo molti servizi interni, le porte 25 e 80 devono essere disponibili pubblicamente, in modo da poter ricevere la posta e servire richieste HTTP. Bob decide di trarre vantaggio da questo fatto lanciando un attacco "assorbi-banda" contro il mio server di posta e il server web.

Circa un minuto dopo che Bob ha incominciato il suo attacco, mi accorgo che i nostri uplinks incominciano a diventare saturi di pacchetti. Dopo aver dato un'occhiata alla situazione con tcpdump mi accorgo che questo è un altro attacco di Bob, e capisco quali indirizzi IP sta usando per lanciarlo. Ora che ho questa informazione, tutto quello che devo fare è bloccare questi indirizzi IP, e ciò dovrebbe risolvere il problema -- una soluzione semplice, o almeno così credo.

Rispondere ad un attacco

Carico velocemente il mio script di setup del firewall in vi e incomincio a smanettare con le mie regole di iptables, modificando il mio firewall in modo tale che blocchi i pacchetti malvagi di Bob in entrata. Dopo un minuto o giù di lì, trovo il punto esatto dove effettuare le aggiunte appropriate delle regole di DROP, e le aggiungo. Poi, fermo e riavvio il firewall...ooops, ho fatto un po' di casino quando ho aggiunto le regole. Riapro gli script del firewall un'altra volta, correggo il problema, e trenta secondi dopo il firewall viene colpito dall'attacco del mese di Bob. A prima vista, sembra che io abbia contrastato l'attacco con successo...finché i telefoni del servizio d'assistenza incominciano a suonare. Apparentemente, Bob è stato in grado di interrompere il servizio nella mia rete per circa 10 minuti, e ora i miei clienti stanno chiamando per scoprire che cosa sta succedendo. Cosa ancora più grave, trascorsi alcuni minuti, mi accorgo che i nostri uplink ricominciano ad essere saturi. Questa volta, Bob sembra usare un insieme di indirizzi IP completamente nuovo per questo attacco. In risposta, incomincio febbrilmente a mettere le mani nei nostri script del firewall, ma questa volta, sono un po' nel panico -- forse la mia soluzione non è così buona dopo tutto.

Ecco quello che è andato storto nello scenario appena presentato. Sebbene io abbia messo in piedi un firewall decente e abbia velocemente identificato la causa del problema della mia rete, non sono stato in grado di modificare il comportamento del mio firewall per rispondere al pericolo in tempo utile. Naturalmente, quando la propria rete è sotto attacco, si vuole essere in grado di rispondere immediatamente ed essere forzati a mettere mano allo script di setup del proprio firewall principale in uno stato di panico non è solamente stressante, ma anche molto inefficiente.

2.  Script

ipdrop

Sarebbe molto meglio se avessi uno script speciale ipdrop specificamente designato per inserire solamente le regole di c'è bisogno per bloccare gli indirizzi IP che specifico. Con un tale script, bloccare un firewall non è più una sofferenza più lunga di due minuti; anzi, richiede cinque secondi. E siccome lo script mi evita il compito di editare le regole del firewall a mano, elimina una delle principali sorgenti di errori. Tutto quello che mi rimane da fare è determinare gli indirizzi IP che vorrei bloccare, e poi scrivere:

Codice 2.1: Bloccare un IP

# ipdrop 129.24.8.1 on
IP 129.24.8.1 drop on.

Immediatamente, lo script ipdrop bloccherebbe 129.24.8.1, l'indirizzo IP della settimana utilizzato correntemente da Bob. Questo script migliora drammaticamente le proprie difese, poiché ora un blocco di IP non richiede nessuno sforzo. Ora diamo uno sguardo alla mia implementazione dello script ipdrop:

Codice 2.2: script ipdrop

#!/bin/bash

source /usr/local/share/.sh

args 2 $# "${0} IPADDR {on/off}"

# Blocca i pacchetti da/verso reti/host/DoS fastidiosi

if [ "$2" == "on" ]
then
# Le regole sono aggiunte o inserite normalmente
 APPEND="-A"
  INSERT="-I"
  rec_check ipdrop $1 "$1 già bloccato" on
  record ipdrop $1
elif [ "$2" == "off" ]
then
# Le regole vengono cancellate
 APPEND="-D"
  INSERT="-D"
  rec_check ipdrop $1 "$1 non è correntemente bloccato" off
  unrecord ipdrop $1
else
  echo "Error: \"off\" or \"on\" richiesto come secondo argomento"
  exit 1
fi

# Blocca l'indirizzo IP esterno che sta causando problemi
# Le connessioni TCP in ingresso dell'attaccante richiederanno
  all'incirca un minuto per andare in time out, riducendo l'efficacia del
  DoS

iptables $INSERT INPUT   -s $1 -j DROP
iptables $INSERT OUTPUT  -d $1 -j DROP
iptables $INSERT FORWARD -d $1 -j DROP
iptables $INSERT FORWARD -s $1 -j DROP

echo "IP ${1} drop ${2}."

ipdrop: la spiegazione

Se si da uno sguardo alle ultime quattro righe evidenziate, si possono notare i comandi reali che inseriscono le regole appropriate nelle tabelle del firewall. Come si può vedere, la definizione della variabile d'ambiente $INSERT cambia, in base all'utilizzo della modalità "on" o "off". Quando le linee iptables vengono eseguite, le regole vengono inserite o cancellate in maniera appropriata.

Ora, guardiamo alla funzione delle stesse regole, le quali dovrebbero funzionare perfettamente con ogni tipo di firewall esistente, o perfino con un sistema privo di firewall; tutto quello di cui si ha bisogno è il supporto ad iptables built-in nel proprio kernel 2.4. Vengono bloccati i pacchetti in ingresso in arrivo dall'IP malvagio (la prima linea iptables), i pacchetti in uscita diretti all'ip malvagio (la linea iptables successiva), e poi si disattiva il forwarding in ogni direzione per questo particolare IP (le ultime due linee iptables). Una volta che queste regole saranno attive, il proprio sistema scarterà semplicemente ogni pacchetto che cadrà in una di queste categorie.

Un'altra nota veloce: si saranno sicuramente notate chiamate a "rec_check", "unrecord", "record", e "args". Queste sono delle funzioni bash speciali di supporto definite in dynfw.sh. La funzione "record" registra l'ip bloccato in /root/.dynfw-ipdrop, mentre "unrecord" rimuove la voce da /root/.dynfw-ipdrop. La funzione "rec_check" è utilizzata per abortire lo script con un messaggio di errore se si tenta di ribloccare un IP già bloccato, o se si tenta di sbloccare un IP che non è correntemente bloccato. La funzione "args" si prende cura di assicurarsi di ricevere il numero corretto di argomenti sulla linea di comando, e inoltre si occupa di stampare informazioni utili per l'utilizzo. Ho creato un dynfw-1.0.tar.gz che contiene tutti questi tools; si controlli la sezione Resources alla fine di questo articolo per ulteriori informazioni.

tcplimit

Il prossimo script dinamico per il firewall è utile se si vuole limitare l'utilizzo di un particolare servizio di rete basato su TCP, ad esempio qualcosa che genera molto carico di cpu su una delle proprie macchine. Questo script "tcplimit" prende una porta TCP, una frequenza, una scala e "on" o "off" come argomento:

Codice 2.3: Limitare l'utilizzo di un particolare servizio di rete basato su TCP

# tcplimit 873 5 minute on
Porta 873: nuovo limite di connessioni  (5/minute, burst=5) on.

tcplimit usa il nuovo modulo "state" di iptables (ci si assicuri di averlo abilitato all'interno del kernel o di aver caricato il modulo) per consentire solo un certo numero di nuove connessioni in entrata in uno specifico periodo di tempo. In questo esempio, il firewall ammetterà solo cinque nuove connessioni al mio server rsync (porta 873) al minuto -- ed è possibile specificare il numero desiderato di connessioni che volete accettare ogni secondo/minuto/ora o giorno, come si desidera.

tcplimit offre un buon modo per limitare i servizi non essenziali -- in modo che un'inondazione di traffico verso un servizio non essenziale non faccia crollare la propria rete o il proprio server. Nel mio caso, utilizzo tcplimit per settare un limite di utilizzo massimo per rsync per prevenire la mia linea dal venir saturata da troppe connessioni rsync. I servizi con limite di connessioni sono registrati in /root/.dynfw-tcplimit, e in caso che voglia rimuovere il nuovo limite di connessioni, posso semplicemente scrivere:

Codice 2.4: Disattivare il limite di connessioni

# tcplimit 873 5 minute off
Porta 873: nuovo limite di connessioni off.

tcplimit funziona creando una catena completamente nuova nella tabella "filter". Questa nuova catena rifiuterà tutti i pacchetti in ingresso che eccedono il limite da noi specificato. Poi, un'unica regola viene aggiunta nella catena di INPUT che redirige tutti i pacchetti in ingresso relativi a connessioni nuove dirette alla porta specificata (in questo caso 873) a questa speciale catena, mettendo effettivamente un limite sulle connessioni nuove in ingresso senza influenzare i pacchetti che appartengono a connessioni già stabilite.

Quando tcplimit è disattivato, la regola nella catena di INPUT e la catena speciale sono eliminate. Questo è il genere di materiale bizzarro che evidenzia realmente l'importanza di avere uno script affidabile e ben testato che gestisca le regole del firewall al posto vostro. Come con ipblock, lo script tcplimit dovrebbe essere compatibile con ogni tipo di firewall o perfino in assenza di firewall, a patto che si abbiano le funzionalità appropriate di iptables attivate nel proprio kernel.

host-tcplimit

host-tcplimit è molto simile a tcplimit, ma limita le nuove connessioni TCP provenienti da un particolare indirizzo IP e dirette ad una specifica porta sul vostro server. host-tcplimit è particolarmente utile per prevenire che una particolare persona abusi delle proprie risorse di rete. Per esempio, supponiamo che si stia facendo girare un server CVS, e che si scopra che un certo nuovo sviluppatore abbia messo in piedi uno script che aggiorna i suoi sorgenti sul repository ogni 10 minuti, usando un eccessiva quantità di risorse di rete non necessarie durante il corso del giorno. Tuttavia, mentre gli si sta inviando un'email per spiegargli i problemi del suo approcio, si riceve un messaggio che riporta il testo seguente:

Codice 2.5: Messaggio in arrivo

Salve ragazzi!

Sono molto contento di essere parte del vostro progetto di sviluppo. Ho
appena configurato uno script per aggiornare la mia copia locale del codice
ogni dieci minuti. Sto per partire per una crociera di due settimane, ma
quando tornerò i miei sorgenti saranno completamente aggiornati e sarò pronto
per darvi una mano!  Sto per uscire dalla porta in questo istante...ci si
vede in due settimane!

Cordialmente vostro,

Mr. Novellino

Per tali situazioni, un semplice comando host-tcplimit risolverà il problema:

Codice 2.6: script host-tcplimit

# host-tcplimit 1.1.1.1 2401 1 day on

Ora, Mr. Novellino (indirizzo IP 1.1.1.1) è limitato ad una connessione CVS (porta 2401) al giorno, risparmiando grandi quantità di banda.

user-outblock

L'ultimo e forse più intrigante di tutti gli script dinamici per il firewall è user-outblock. Questo script offre un modo perfetto per consentire ad un particolare utente di collegarsi tramite telnet o ssh all'interno del proprio sistema, non consentendo però a questo utente di stabilire nessuna connessione in uscita dalla linea di comando. Segue un esempio di una situazione dove user-outblock potrebbe venire in aiuto. Supponiamo che una particolare famiglia abbia un account sul mio ISP. La madre e il padre usano un client grafico per leggere le email e occasionalmente navigare nel Web, ma il loro figlio sembra essere un aspirante hacker, ed in genere utilizza il suo accesso shell per fare cose sgradevoli verso i computer di altre persone.

Un giorno, ci si accorge che ha stabilito connessioni ssh con molti sistemi che sembrano appartenere ai militari pakistani -- ahi! Si vorrebbe dirigere questo giovane verso attività migliori, così si agisce nel modo seguente:

Per prima cosa, si fa un controllo del proprio sistema e ci si assicura di rimuovere il bit suid da tutti i binari di rete, come ssh:

Codice 2.7: Rimuovere il bit suid da tutti i binari di rete

# chmod u-s /usr/bin/ssh

Ora, ogni processo che lui tenti di usare per interagire con la rete sarà posseduto dal suo UID. A questo punto è possibile usare user-outblock per bloccare tutte le connessioni TCP in uscita create dal suo UID (che supponiamo essere 2049):

Codice 2.8: Bloccare tutte le connessioni TCP in uscita iniziate da un particolare UID

# user-outblock 2049 on
UID 2049: blocco on.

Adesso, potrà loggarsi e leggere la sua email, ma non sarà in grado di usare i server per stabilire connessioni ssh o per fare cose simili. Ora potrà installare un client ssh sul suo PC casalingo. Comunque, non è difficile configurare un altro script dinamico per il firewall che limiti il suo PC a Web, posta e connessioni ssh in uscita (solamente verso il server dell'ISP).

3.  Risorse

Tarballs

Poiché ho trovato questi script per il firewall così utili, ho messo insieme un bel tarball (dynfw-1.0.1.tar.bz2) che è possibile scaricare e installare sul proprio sistema.

Per installare, estrarre il tarball e avviare lo script incluso install.sh. Questo script installerà uno script bash condiviso su /usr/local/share/dynfw.sh, e installerà gli script dinamici per il firewall su /usr/local/sbin. In caso si desiderasse installarli invece in /usr/share e /usr/sbin, si scriva semplicemente questo prima di avviare install.sh:

Codice 3.1: Esportare la locazione della directory di installazione

# export PREFIX=/usr

Ho inoltre aggiunto una pagina script dinamici per il firewall sul sito di Gentoo Linux che è possibile visitare per ottenere la versione più recente del tarball. Vorrei continuare a migliorare e ad aggiungere script alla collezione, creando una risorsa veramente utile per gli amministratori di sistema di tutto il mondo. Dato che abbiamo iptables nel kernel, è ora di trarne vantaggio!

Se questo materiale riguardante il firewall iptables risulta essere nuovo ai propri occhi, si raccomanda fortemente il mio Linux 2.4 stateful firewall tutorial (registrazione richiesta), contenente istruzioni complete su come configurare il proprio stateful firewall basato su iptables.

tcpdump è uno strumento essenziale per esplorare scambi di pacchetti a basso livello e per verificare che il proprio firewall stia funzionando correttamente. Se non lo si ha, è il caso di procurarselo. Se lo si ha, si incominci ad usarlo. Se lo si sta usando... meglio :)

Si visitino l'home page del team di netfilter per trovare grandi quantità di risorse eccellenti, inclusi i sorgenti di iptables, e le eccellenti guide inaffidabili di Rusty. Queste includono un HOWTO sui concetti base di networking, un HOWTO su netfilter (iptables), un HOWTO sul NAT, e un HOWTO riguardante l'hacking di netfilter per sviluppatori. Inoltre è disponibile tra le altre cose una FAQ di netfilter.

Fortunatamente, c'è una gran quantità di buon materiale riguardante netfilter online; ad ogni modo, non ci si dimentichi la cosa fondamentale. La man page di iptables è molto dettagliata e costituisce un esempio lampante di come dovrebbe essere una man page.

E' inoltre disponibile un HOWTO riguardante il routing avanzato sotto linux e il controllo del traffico. C'è una buona sezione che mostra come usare iptables per marcare pacchetti e usare poi le funzionalità di routing di Linux per effettuare il routing dei pacchetti basandosi su tali mark.

E' disponibile una mailing list di netfilter (iptables) così come una per gli sviluppatori di netfilter. Potete inoltre accedere agli archivi di queste mailing list presso gli stessi indirizzi.



Stampa

Aggiornato il 9 ottobre 2005

Oggetto: I firewall sono utili e divertenti, ma che fare quando c'è bisogno di apportare cambiamenti rapidi e complessi alle regole del proprio firewall? Facile. Si utilizzino gli script dinamici per il firewall di Daniel Robbins che sono mostrati in questo articolo. Questi script possono essere utilizzati per aumentare la sicurezza e la responsività della propria rete e per ispirare le proprie configurazioni creative.

Daniel Robbins
Autore

Gianni Costanzi
Traduttore

Donate to support our development efforts.

Copyright 2001-2014 Gentoo Foundation, Inc. Questions, Comments? Contact us.