
Oggi parliamo di un argomento che sicuramente ogni amministratore di rete avrà affrontato almeno una volta nella vita: il firewall. L'obiettivo di questo articolo è illustrare come realizzare un firewall che protegga due reti: una LAN ed una DMZ. La realizzazione non è difficile e non richiede neanche tanto tempo, per l'obiettivo che ci siamo preposti una delle tante soluzioni è Shorewall su Debian. In questo articolo faremo una brevissima introduzione di come funziona il firewalling su linux, poi passeremo alla realizzazione del firewall e alla fine faremo alcune considerazioni finali.
Firewall su Linux - Introduzione rapidissima
Il sistema di firewalling su Linux è basato su iptables e netfilter (iproute sui sistemi RedHat, pf su BSD Like). Netfilter è un componente del kernel che permette di intercettare e manipolare i pacchetti in transito sul sistema. iptables è un programma che permette la gestione di netfilter attraverso l'inserimento di regole, iptables sostituisce i vecchi ipfwadm e di ipchains. Per fortuna con la soluzione che abbiamo scelto non dobbiamo scrivere regole, ma giusto per conoscenza facciamo un piccolo esempio di come funziona iptables. Per esempio, vogliamo far in modo che sull'indirizzo 127.0.0.1 non sia possibile fare il ping.
Prima
# ping -c 1 127.0.0.1 PING 127.0.0.1 (127.0.0.1): 56 data bytes 64 bytes from 127.0.0.1: icmp_seq=0 ttl=64 time=0.2 ms --- 127.0.0.1 ping statistics --- 1 packets transmitted, 1 packets received, 0% packet loss round-trip min/avg/max = 0.2/0.2/0.2 ms
Settiamo la regola
# iptables -A INPUT -s 127.0.0.1 -p icmp -j DROP
Risultato
# ping -c 1 127.0.0.1 PING 127.0.0.1 (127.0.0.1): 56 data bytes --- 127.0.0.1 ping statistics --- 1 packets transmitted, 0 packets received, 100% packet loss
Le regole iptables vengono concatenate l'una dopo l'altra dentro dei "contenitori" detti catene ed essi sono: INPUT, FORWARD e OUTPUT. Le catene come impostazione di default sono impostate su ACCEPT. Nel nostro esempio, la regola che abbiamo appena scritto appende (-A) alla catena 'INPUT', una regola che indichi che i pacchetti provenienti dall'indirizzo 127.0.0.1 (-s 127.0.0.1) con protocollo ICMP (-p icmp) devono essere ignorati (-j DROP).
Per ora, può bastare. Questo è un sunto del riassunto, detto in maniera rapida, per quello che dobbiamo fare ci può bastare. Invece, chi volesse approfondire può leggere la documentazione di netfilter su www.netfilter.org.
I tool per iptables/netfilter su debian
Le operazioni più comuni con iptables sono la gestione delle catene creando nuove regole (-N), cancellare una catena vuota (-X), cambiare le policy di una catena esistente (-P), elencare le regole di una catena (-L), svuotare una catena (-F), azzerare i contatori (-Z), appendere una nuova regola ad una catena (-A), e tante altre operazioni. Gestire un firewall in questo modo richiede un lavoro continuo e a tempo inderminato, per fortuna estistono numerosi script e tools che inseriscono e "modificano" le regole al posto nostro. Possiamo fare una metafora, se assumiamo che le regole iptables sono simile all'assembly, invece il tool permette di utilizzare funzioni simile C. Di seguito i tools disponibili su Debian
Package and Upstream URL |
Interface |
Programming Language |
Size of Source (as of 2005-10) |
Releases (as of 2005-10) |
edit (debconf) |
sh |
60K |
< 2003-08 - 2005-09 |
|
edit |
perl |
80K |
< 2001-04 - 2005-06 |
|
edit |
bash |
320K |
< 2003-01 - 2004-02 |
|
edit |
C |
150K |
< 2002-10 - 2004-08 |
|
gui |
C |
230K |
2002-02 - 2005-09 |
|
edit |
bash |
210K |
< 2003-05 - 2005-01 |
|
gui (gnome) |
C |
1170K |
< 2003-01 - 2005-01 |
|
gui (kde) |
C++ |
1190K |
< 2003-12 - 2005-09 |
|
gui (kde) |
C++ |
960K |
2000-06 - 2005-08 |
|
gui (kde) |
C++ |
590K |
2001-11 - 2003-11 |
|
edit |
C |
100K |
< 2000-07 - 2003-10 |
|
edit |
sh |
40K |
2002-09 - 2003-10 |
|
gui (kde) |
C++ |
1060K |
2002-08 - 2005-03 |
|
gui (kde) |
C++ |
960K |
< 2001-01 - 2005-04 |
|
shell (autolearning) |
bash |
500K |
< 1999-03 - 2002-05 |
|
netscript-2.4 |
edit, iptables |
sh |
70K |
< 2000-11 - 2004-10 |
edit, webmin |
sh |
130K |
< 2001-12 - 2005-09 |
|
edit (debconf) |
perl |
34K |
2002-02 - 2005-04 |
|
edit |
sh |
80K |
2003-03 - 2005-07 |
|
curses |
C |
1877K |
2004-07 - 2005-11 |
|
edit |
python |
247K |
2009-5 - (NEW) |
Tra tutti questi tools, il più usato dalla comunità Debian è Shoreline Firewall (detto Shorewall) ed è il tool che useremo per realizzare il nostro firewall.
Scenario
Abbiamo il seguente scenario, una linea ADSL, una LAN interna e una DMZ con servizi esposti sulla rete. Dall'esterno verso la LAN non deve passare alcun pacchetto, dall'esterno verso la DMZ passano i pacchetti solo per le porte che noi lasciamo libere, dalla LAN verso la DMZ e dalla LAN verso internet non esiste alcun filtro, infine, dalla DMZ verso la LAN l'accesso è impedito.
Impostiamo la classe del router su 100, la DMZ sulla classe 2 e la LAN sulla 1.
Installare e configurare Shorewall
Naturalmente dobbiamo aver una versione di Debian installata, dobbiamo avere 3 schede di rete ed impostare eth0 come scheda predefinita, un router ADSL collegato ad eth0, uno switch collegato a eth1 e un'altro switch collegato a eth2. Si potrebbe usare una sola scheda impostando più IP su una scheda, e un solo switch utilizzando in modo opportuno la maschera di rete, ma è meglio non percorrere questa soluzione se non vogliamo uscire pazzi con la configurazione ed avere problemi di sicurezza, anche se si sta usando uno switch moderno che invia i pacchetti in base all'accoppiata IP/MAC address.
Successivamente installiamo shorewall con:
# apt-get install shorewall # apt-get install shorewall-doc
Successivamente copiamo dalla documentazione l'esempio a tre schede di rete (facile :D ) :
# cp -R /usr/share/doc/shorewall/examples/three-interfaces/* /etc/shorewall/
Logicamente dobbiamo configurare eth0 con un indirizzo statico, e non dhcp, in quanto dobbiamo reindirizzare tutto il traffico proveniente dal router verso eth0. Il file di configurazione come al solito si trova a "/etc/network/interfaces", la configurazione sarà simile a:
iface eth0 inet static address 192.168.100.2 netmask 255.255.255.0 gateway 192.168.100.254 # se vogliamo possiamo impostare un indirizzo ipv6 iface eth0 inet6 static address fe80::192.168.100.2 netmask 64 gateway fe80::c0a8:64fe # inoltre se per caso ci ritroviamo improvvisamete a corto di schede di rete # possiamo impostare più indirizzi IP su una scheda (sconsigliatissimo) iface eth0 inet static address 192.168.1.254 netmask 255.255.255.0 gateway 192.168.1.254 iface eth0 inet static address 192.168.2.254 netmask 255.255.255.0 gateway 192.168.2.254
e per impostare i nameserver modifichiamo "/etc/resolv.conf"
nameserver 208.67.222.222 nameserver 208.67.220.220
ordinaria amministrazione fino ad ora. Successivamente dobbiamo editare "/etc/default/shorewall" e impostare la prima linea in:
# prevent startup with default configuration # set the below varible to 1 in order to allow shorewall to start startup=1
e avviare il firewall con
/etc/init.d/shorewall start
Ora dobbiamo associare le nostre zone (vedi figura precedente) alle interfaccie di rete, lo facciamo editando "/etc/shorewall/interface", in realtà il file è già impostato preché abbiamo copiato i file di esempio:
#ZONE INTERFACE OPTIONS net eth0 tcpflags,nosmurfs,routefilter,logmartians,sourceroute=0 loc eth1 tcpflags,nosmurfs,routefilter,logmartians dmz eth2 tcpflags,nosmurfs,routefilter,logmartians
Ogni volta che salviamo un file di configurazione di Shorewall accertiamoci che ci sia una riga vuota alla fine. Nel file di configurazione abbiamo impostato le interfaccie di rete alle seguenti zone: "net" la zona dell'interfaccia esposta; "loc" la zona della LAN privata; la "dmz" la zona con i server esposti. Per chi vuole approfondire questo aspetto più informazioni li può reperire su questa pagina. D'ora in poi, alcune volte chiamerò interfaccia/rete Red l'interfaccia/zona esposta su internet (net, eth0); interfaccia/zona Green la LAN (loc, eth1) ed Orange l'interfaccia/zona della zona demilitarizzata (dmz, eth2).
Il prossimo passo è la configurazione delle zone "/etc/shorewall/zones", anche questo file è già configurato
############################################################# #ZONE TYPE OPTIONS IN OUT # OPTIONS OPTIONS fw firewall net ipv4 loc ipv4 dmz ipv4
La prima zona è obbligatoria "fw" e rappresenta il firewall, le altre zone vanno inserite nello stesso ordine del precedente file di configurazione specificado il tipo di zona. Questo aspetto si può approfondire consultando la questa pagina.
Il prossimo passo sarà quello di impostare le "policy" di sicurezza per ogni zona, quindi per ogni zona che abbiamo dichiarato dobbiamo impostare una "policy" di sicurezza, lo facciamo editando il file "/etc/shorewall/policy":
#SOURCE DEST POLICY LOG BURST:LIMIT # LEVEL loc net ACCEPT info net all DROP info # THE FOLLOWING POLICY MUST BE LAST all all REJECT info
Le policy che abbiamo impostato permettono alla zona Green di poter accedere all'esterno (loc -> net), di ignorare tutto quello che proviene dall'esterno su tutte le zone ed infine di respingere tutto ciò che resta verso tutto. Per approfondire questo aspetto si può consultare questa pagina.
Arrivati a questo punto abbiamo dato un'impostazione grossolana al nostro firewall, ora possiamo andare a definire le regole con più precisione andando ad editare il file "/etc/shorewall/rules" subito dopo di "SECTION NEW":
#ACTION SOURCE DEST PROTO DEST PORT(S) SECTION NEW Web(DNAT) net dmz:192.168.2.2 - 80 Web(ACCEPT) loc dmz:192.168.2.2 - 80
abbiamo fatto un port forwarding (DNAT) in modo che per la porta 80 fosse raggiungibile sia dall'esterno e dalla rete Green. Per far funzionare questa opzione dobbiamo controllare che in "/etc/shorewall/shorewall.conf" l'opzione "IP_FORWARDING" sia impostata su "On". Per le porte più usate, shorewall mette a disposizione delle macro già pronte, esse sono disponibili in "/usr/share/shorewall" senza doverle specificare dentro rules.
Siamo quasi alla fine, arrivati a questo punto dobbiamo soltanto far "comunicare" le diverse interfaccie, questo lo facciamo con l'IP Masquerading, è una forma di NAT che ci permette di condividere la connessione di una rete con un'altra (o di una scheda di rete con un'altra), è semplice, ci basta editare il file "/etc/shorewall/masq" nel seguente modo:
#INTERFACE SOURCE ADDRESS PROTO eth0 192.168.100.0/24 \ 192.168.1.0/24 \ 192.168.2.0/24
a questo punto abbiamo finito.
Conclusioni
Come abbiamo visto, la configurazione di un firewall su linux non è complicata, basta editare un po' di file. Questo tipo di soluzione è buona per lo scenario che abbiamo proposto, se invece si sta pensando ad altri scenari, come un server di hosting, con molti servizi esposti, questa non è la soluzione da seguire. Per un server di hosting serve qualcosa di molto più complesso e reattivo, serve un firewall che in base agli eventi (login falliti, ddos, spamlist ecc) modifichi le regole in maniera dinamica, magari ne parlerò prossimamente.
Oltre a shorewall, per lo stesso scenario, esistono numerose soluzioni "chiavi in mano", che sinceramente sono molto più flessibili del firewall "fai da te". Le distribuzioni più usate sono IPCop e pfSense, ma esse lasciano meno spazio alla personalizzazione e alla fantasia.
Ciao :)