                           Filtering Bridges

  Alex Dupre

   <ale@FreeBSD.org>

   $FreeBSD:
   doc/it_IT.ISO8859-15/articles/filtering-bridges/article.sgml,v
   1.14 2008/01/27 15:29:47 ale Exp $

   FreeBSD e un marchio registrato della FreeBSD Foundation.

   3Com e HomeConnect sono marchi registrati della 3Com Corporation.

   Intel, Celeron, EtherExpress, i386, i486, Itanium, Pentium, e Xeon
   sono marchi o marchi registrati della Intel Corporation o delle
   sue sussidiarie negli Stati Uniti e in altri paesi.

   Molti dei nomi identificativi usati dai produttori e dai venditori
   per distinguere i loro prodotti sono anche dei marchi. Quando
   questi nomi appaiono nel libro, e il FreeBSD Project e al corrente
   del marchio, vengono fatti seguire dal simbolo "(TM)" o "(R)".

   Spesso e utile dividere una rete fisica (come una Ethernet) in due
   segmenti separati, senza dover creare sottoreti e usare un router
   per collegarli assieme. Il dispositivo che collega due reti
   insieme in questo modo e chiamato bridge. Un sistema FreeBSD con
   due interfacce di rete e sufficiente per raggiungere lo scopo.

   Un bridge funziona individuando gli indirizzi del livello MAC
   (indirizzi Ethernet) dei dispositivi collegati ad ognuna delle sue
   interfacce di rete e inoltrando il traffico tra le due reti solo
   se il mittente e il destinatario si trovano su segmenti
   differenti. Sotto molti punti di vista un brigde e simile a uno
   switch Ethernet con solo due porte.

     --------------------------------------------------------------

1 Perche usare un filtering bridge?

   Sempre piu frequentemente, grazie all'abbassamento dei costi delle
   connessioni a banda larga (xDSL) e a causa della riduzione del
   numero di indirizzi IPv4 disponibili, molte societ`a si ritrovano
   collegate ad Internet 24 ore su 24 e con un numero esiguo (a volte
   nemmeno una potenza di 2) di indirizzi IP. In situazioni come
   queste spesso e desiderabile avere un firewall che regoli i
   permessi di ingresso e uscita per il traffico da e verso Internet,
   ma una soluzione basata sulle funzionalit`a di packet filtering
   dei router puo non essere applicabile, vuoi per problemi di
   suddivisione delle sottoreti, vuoi perche il router e di
   propriet`a del fornitore di accesso (ISP), vuoi perche il router
   non supporta tali funzionalit`a. E in questi casi che l'utilizzo
   di un filtering bridge diventa altamente consigliato.

   Un firewall basato su bridge puo essere configurato e inserito
   direttamente tra il router xDSL e il vostro hub/switch Ethernet
   senza alcun problema di assegnazione di indirizzi IP.

     Nota: La traduzione italiana di "firewall" e "muro anti
     incendio", non "muro di fuoco" come molti pensano. Nel corso
     dell'articolo, comunque, manterro i termini tecnici nella loro
     lingua originale in modo da non creare confusione o ambiguit`a.

     --------------------------------------------------------------

2 Metodi d'installazione

   Aggiungere le funzionalit`a di bridge a una macchina FreeBSD non e
   difficile. Dalla release 4.5 e possibile caricare tali
   funzionalit`a come moduli anziche dover ricompilare il kernel,
   semplificando di gran lunga la procedura. Nelle prossime
   sottosezioni spieghero entrambi i metodi di installazione.

     Importante: Non seguite entrambe le istruzioni: le procedure
     sono a esclusione. Scegliete l'alternativa che meglio si adatta
     alle vostre esigenze e capacit`a.

   Prima di continuare e necessario assicurarsi di avere almeno due
   schede di rete Ethernet che supportino la modalit`a promiscua sia
   in ricezione che in trasmissione, difatti devono essere in grado
   di inviare pacchetti Ethernet con qualunque indirizzo, non solo il
   loro. Inoltre, per avere un buon rendimento, le schede dovrebbero
   essere di tipo PCI bus mastering. Le scelte migliori sono ancora
   le Intel EtherExpress(TM) Pro seguite dalle 3Com(R) 3c9xx subito
   dopo. Per comodit`a nella configurazione del firewall puo essere
   utile avere due schede di marche differenti (che usino drivers
   differenti) in modo da distinguere chiaramente quale interfaccia
   sia collegata al router e quale alla rete interna.

     --------------------------------------------------------------

  2.1 Configurazione del Kernel

   Cos`i avete deciso di utilizzare il piu vecchio e collaudato
   metodo di installazione. Per prima cosa bisogna aggiungere le
   seguenti righe al file di configurazione del kernel:

 options BRIDGE
 options IPFIREWALL
 options IPFIREWALL_VERBOSE

   La prima riga serve a compilare il supporto per il bridge, la
   seconda il firewall e la terza le funzioni di logging del
   firewall.

   Adesso e necessario compilare e installare il nuovo kernel. Si
   possono trovare le istruzioni nella sezione Building and
   Installing a Custom Kernel dell'handbook.

     --------------------------------------------------------------

  2.2 Caricamento dei Moduli

   Se avete deciso di usare il nuovo e piu semplice metodo di
   installazione, l'unica cosa da fare e aggiungere la seguente riga
   al file /boot/loader.conf:

 bridge_load="YES"

   In questo modo all'avvio della macchina verr`a caricato insieme al
   kernel anche il modulo bridge.ko. Non e necessario invece
   aggiungere una riga per il modulo ipfw.ko in quanto verr`a
   caricato in automatico dallo script /etc/rc.network dopo aver
   seguito i passi della prossima sezione.

     --------------------------------------------------------------

3 Preparativi finali

   Prima di riavviare per caricare il nuovo kernel o i moduli
   richiesti (a seconda del metodo che avete scelto in precedenza),
   bisogna effettuare alcune modifiche al file /etc/rc.conf. La
   regola di default del firewall e di rifiutare tutti i pacchetti
   IP. Per iniziare attiviamo il firewall in modalit`a open, in modo
   da verificare il suo funzionamento senza alcun problema di
   filtraggio pacchetti (nel caso stiate eseguendo questa procedura
   da remoto, tale accorgimento vi consentir`a di non rimanere
   erroneamente tagliati fuori dalla rete). Inserite queste linee nel
   file /etc/rc.conf:

 firewall_enable="YES"
 firewall_type="open"
 firewall_quiet="YES"
 firewall_logging="YES"

   La prima riga serve ad attivare il firewall (e a caricare il
   modulo ipfw.ko nel caso non fosse gi`a compilato nel kernel), la
   seconda a impostarlo in modalit`a open (come descritto nel file
   /etc/rc.firewall), la terza a non visualizzare il caricamento
   delle regole e la quarta ad abilitare il supporto per il logging.

   Per quanto riguarda la configurazione delle interfacce di rete, il
   metodo piu utilizzato e quello di assegnare un IP a solo una delle
   schede di rete, ma il bridge funziona egualmente anche se entrambe
   o nessuna delle interfacce ha IP settati. In quest'ultimo caso
   (IP-less) la macchina bridge sar`a ancora piu nascosta in quanto
   inaccessibile dalla rete: per configurarla occorrer`a quindi
   entrare da console o tramite una terza interfaccia di rete
   separata dal bridge. A volte all'avvio della macchina qualche
   programma richiede di accedere alla rete, per esempio per una
   risoluzione di dominio: in questo caso e necessario assegnare un
   IP all'interfaccia esterna (quella collegata a Internet, dove
   risiede il server DNS), visto che il bridge verr`a attivato alla
   fine della procedura di avvio. Questo vuol dire che l'interfaccia
   fxp0 (nel nostro caso) deve essere menzionata nella sezione
   ifconfig del file /etc/rc.conf, mentre la xl0 no. Assegnare IP a
   entrambe le schede di rete non ha molto senso, a meno che durante
   la procedura di avvio non si debba accedere a servizi presenti su
   entrambi i segmenti Ethernet.

   C'e un'altra cosa importante da sapere. Quando si utilizza IP
   sopra Ethernet ci sono due protocolli Ethernet in uso: uno e IP,
   l'altro e ARP. ARP permette la conversione dell'indirizzo IP di
   una macchina nel suo indirizzo Ethernet (livello MAC). Affinche
   due macchine separate dal bridge riescano a comunicare tra loro e
   necessario che il bridge lasci passare i pacchetti ARP. Tale
   protocollo non fa parte del livello IP, visto che e presente solo
   con IP sopra Ethernet. Il firewall di FreeBSD agisce
   esclusivamente sul livello IP e quindi tutti i pacchetti non IP
   (compreso ARP) verranno inoltrati senza essere filtrati, anche se
   il firewall e configurato per non lasciar passare nulla.

   Ora e arrivato il momento di riavviare la macchina e usarla come
   in precedenza: appariranno dei nuovi messaggi riguardo al bridge e
   al firewall, ma il bridge non sar`a attivato e il firewall,
   essendo in modalit`a open, non impedir`a nessuna operazione.

   Se ci dovessero essere dei problemi, e il caso di scoprire ora da
   cosa derivino e risolverli prima di continuare.

     --------------------------------------------------------------

4 Attivazione del Bridge

   A questo punto, per attivare il bridge, bisogna eseguire i
   seguenti comandi (avendo l'accortezza di sostituire i nomi delle
   due interfacce di rete fxp0 e xl0 con i propri):

 # sysctl net.link.ether.bridge.config=fxp0:0,xl0:0
 # sysctl net.link.ether.bridge.ipfw=1
 # sysctl net.link.ether.bridge.enable=1

   La prima riga specifica tra quali interfacce va attivato il
   bridge, la seconda abilita il firewall sul bridge ed infine la
   terza attiva il bridge.

     Nota: Se hai FreeBSD 5.1-RELEASE o precedenti le variabili
     sysctl sono chiamate in modo differente. Guarda bridge(4) per i
     dettagli.

   A questo punto dovrebbe essere possibile inserire la macchina tra
   due gruppi di host senza che venga compromessa qualsiasi
   possibilit`a di comunicazione tra di loro. Se e cos`i, il prossimo
   passo e quello di aggiungere le parti
   net.link.ether.bridge.[blah]=[blah] di queste righe al file
   /etc/sysctl.conf, in modo che vengano eseguite all'avvio della
   macchina.

     --------------------------------------------------------------

5 Configurazione del Firewall

   Ora e arrivato il momento di creare il proprio file con le regole
   per il firewall, in modo da rendere sicura la rete interna. Ci
   sono delle complicazioni nel fare questo, perche non tutte le
   funzionalit`a del firewall sono disponibili sui pacchetti
   inoltrati dal bridge. Inoltre, c'e una differenza tra i pacchetti
   che stanno per essere inoltrati dal bridge e quelli indirizzati
   alla macchina locale. In generale, i pacchetti che entrano nel
   bridge vengono processati dal firewall solo una volta, non due
   come al solito; infatti vengono filtrati solo in ingresso, quindi
   qualsiasi regola che usi out oppure xmit non verr`a mai eseguita.
   Personalmente uso in via che e una sintassi piu antica, ma che ha
   un senso quando la si legge. Un'altra limitazione e che si possono
   usare solo i comandi pass e drop per i pacchetti filtrati dal
   bridge. Cose avanzate come divert, forward o reject non sono
   disponibili. Queste opzioni possono ancora essere usate, ma solo
   per il traffico da e verso la macchina bridge stessa (sempre che
   le sia stato assegnato un IP).

   Nuovo in FreeBSD 4.0 e il concetto di stateful filtering. Questo e
   un grande miglioramento per il traffico UDP, che consiste
   tipicamente di una richiesta in uscita, seguita a breve termine da
   una risposta con la stessa coppia di indirizzi IP e numeri di
   porta (ma con mittente e destinatario invertiti, ovviamente). Per
   i firewall che non supportano il mantenimento di stato, non c'e
   modo di gestire questo breve scambio di dati come una sessione
   unica. Ma con un firewall che puo "ricordarsi" di un pacchetto UDP
   in uscita e permette una risposta nei minuti successivi, gestire i
   servizi UDP e semplice. L'esempio seguente mostra come fare. La
   stessa cosa e possibile farla con i pacchetti TCP. Questo permette
   di evitare qualche tipo di attacco denial of service e altri
   sporchi trucchi, ma tipicamente fa anche crescere velocemente la
   tabella di stato.

   Vediamo un esempio di configurazione. Bisogna notare che
   all'inizio del file /etc/rc.firewall ci sono gi`a delle regole
   standard per l'interfaccia di loopback lo0, quindi non ce ne
   occuperemo piu ora. Le regole personalizzate andrebbero messe in
   un file a parte (per esempio /etc/rc.firewall.local) e caricate
   all'avvio modificando la riga del file /etc/rc.conf dove era stata
   definita la modalit`a open con:

 firewall_type="/etc/rc.firewall.local"

     Importante: Bisogna specificare il path completo del file,
     altrimenti non verr`a caricato con il rischio di rimanere
     tagliati fuori dalla rete.

   Per il nostro esempio immaginiamo di avere l'interfaccia fxp0
   collegata all'esterno (Internet) e la xl0 verso l'interno (LAN).
   La macchina bridge ha assegnato l'IP 1.2.3.4 (e impossibile che il
   vostro ISP vi assegni un indirizzo simile a questo, ma per
   l'esempio va bene).

 # Le connessioni di cui abbiamo mantenuto lo stato vengono fatte passare subito
 add check-state

 # Esclude le reti locali definite nell'RFC 1918
 add drop all from 10.0.0.0/8 to any in via fxp0
 add drop all from 172.16.0.0/12 to any in via fxp0
 add drop all from 192.168.0.0/16 to any in via fxp0

 # Permette alla macchina bridge di connettersi con chi vuole
 # (se la macchina e IP-less non includere questi comandi)
 add pass tcp from 1.2.3.4 to any setup keep-state
 add pass udp from 1.2.3.4 to any keep-state
 add pass ip from 1.2.3.4 to any

 # Permette agli host della rete interna di connettersi con chi vogliono
 add pass tcp from any to any in via xl0 setup keep-state
 add pass udp from any to any in via xl0 keep-state
 add pass ip from any to any in via xl0

 # Sezione TCP
 # Permette SSH
 add pass tcp from any to any 22 in via fxp0 setup keep-state
 # Permette SMTP solo verso il mail server
 add pass tcp from any to relay 25 in via fxp0 setup keep-state
 # Permette i trasferimenti di zona solo dal name server secondario [dns2.nic.it]
 add pass tcp from 193.205.245.8 to ns 53 in via fxp0 setup keep-state
 # Lascia passare i controlli ident:
 # e meglio che aspettare che vadano in timeout
 add pass tcp from any to any 113 in via fxp0 setup keep-state
 # Permette connessioni nel range di "quarantena".
 add pass tcp from any to any 49152-65535 in via fxp0 setup keep-state

 # Sezione UDP
 # Permette DNS solo verso il name server
 add pass udp from any to ns 53 in via fxp0 keep-state
 # Permette connessioni nel range di "quarantena".
 add pass udp from any to any 49152-65535 in via fxp0 keep-state

 # Sezione ICMP
 # Abilita le funzioni di 'ping'
 add pass icmp from any to any icmptypes 8 keep-state
 # Permette il passaggio dei messaggi di errori del comando 'traceroute'
 add pass icmp from any to any icmptypes 3
 add pass icmp from any to any icmptypes 11

 # Tutto il resto e sospetto
 add drop log all from any to any

   Coloro che hanno configurato un firewall in precedenza potrebbero
   aver notato che manca qualcosa. In particolare, non ci sono regole
   contro lo spoofing, difatti non abbiamo aggiunto:

 add deny all from 1.2.3.4/8 to any in via fxp0

   Ovvero, non far entrare dall'esterno pacchetti che affermano di
   venire dalla rete interna. Questa e una cosa che solitamente viene
   fatta per essere sicuri che qualcuno non provi a eludere il packet
   filter, generando falsi pacchetti che sembrano venire
   dall'interno. Il problema e che c'e almeno un host
   sull'interfaccia esterna che non si puo ignorare: il router.
   Solitamente, pero, gli ISP eseguono il controllo anti-spoof sui
   loro router e quindi non ce ne dobbiamo preoccupare.

   L'ultima riga sembra un duplicato della regola di default, ovvero
   non far passare nulla che non sia stato specificatamente permesso.
   In verit`a c'e una differenza: tutto il traffico sospetto verr`a
   loggato.

   Ci sono due regole per permettere il traffico SMTP e DNS verso il
   mail server e il name server, se ne avete. Ovviamente l'intero set
   di regole deve essere personalizzato per le proprie esigenze,
   questo non e altro che uno specifico esempio (il formato delle
   regole e spiegato dettagliatamente nella man page ipfw(8)).
   Bisogna notare che, affinche "relay" e "ns" siano interpretati
   correttamente, la risoluzione dei nomi deve funzionare prima che
   il bridge sia attivato. Questo e un chiaro esempio che dimostra
   l'importanza di settare l'IP sulla corretta scheda di rete. In
   alternativa e possibile specificare direttamente l'indirizzo IP
   anziche il nome host (cosa necessaria se la macchina e IP-less).

   Le persone che sono solite configurare un firewall probabilmente
   avranno sempre usato una regola reset o forward per i pacchetti
   ident (porta 113 TCP). Sfortunatamente, questa non e una scelta
   applicabile con il bridge, quindi la cosa migliore e lasciarli
   passare fino alla destinazione. Finche la macchina di destinazione
   non ha un demone ident attivo, questa tecnica e relativamente
   sicura. L'alternativa e proibire le connessioni sulla porta 113,
   creando qualche problema con servizi tipo IRC (le richieste ident
   devono andare in timeout).

   L'unica altra cosa un po' particolare che potete aver notato e che
   c'e una regola per lasciar comunicare la macchina bridge e
   un'altra per gli host della rete interna. Ricordate che questo e
   dovuto al fatto che i due tipi di traffico prendono percorsi
   differenti attraverso il kernel e di conseguenza anche dentro il
   packet filter. La rete interna passer`a attraverso il bridge,
   mentre la macchina locale user`a il normale stack IP per le
   connessioni. Percio due regole per gestire due casi differenti. Le
   regole in via fxp0 funzionano in entrambi i casi. In generale, se
   usate regole in via attraverso il packet filter, dovrete fare
   un'eccezione per i pacchetti generati localmente, in quanto non
   entrano tramite nessuna interfaccia.

     --------------------------------------------------------------

6 Contributi

   Alcune parti di questo articolo sono state prese, tradotte e
   adattate da testi sui bridge, appartenenti alla documentazione di
   FreeBSD in lingua inglese, a cura di Nick Sayer e Steve Peterson.

   Un grosso ringraziamento va a Luigi Rizzo per l'implementazione
   delle funzionalit`a di bridging in FreeBSD e per il tempo che mi
   ha dedicato rispondendo ad alcune mie domande a riguardo.

     --------------------------------------------------------------

        Questo, ed altri documenti, possono essere scaricati da
                ftp://ftp.FreeBSD.org/pub/FreeBSD/doc/.

  Per domande su FreeBSD, leggi la documentazione prima di contattare
                        <questions@FreeBSD.org>.
        Per domande su questa documentazione, invia una e-mail a
                           <doc@FreeBSD.org>.
