martedì 7 gennaio 2014

Delirii e BSD - Quarto Episodio

Riepilogo delle puntate precedenti: dopo essere stato svegliato nel cuore della notte dal suo capo il nostro eroe ha installato OpenBSD su una vecchia SUN Ultra 1 tramite il boot da rete. L'alba si avvicina e ora comincia la parte più impegnativa: configurare la Ultra 1 come gateway...

Quarto episodio: La Configurazione di pf.

pf è una delle ragioni per cui mi sono avvicinato ad OpenBSD: stavo cercando un Sistema Operativo che mi permettesse di avere un gateway internet capace di girare su un vecchio Pentium a 133 MHz con 16 megabyte di RAM. All'epoca (si parla del 2006) frequentavo il secondo anno di università e facevo parte di un ristretto gruppo di pazzi scellerati a cui il Dipartimento di Matematica e Informatica aveva dato a disposizione alcuni IP pubblici e una stanza piena di catorci da usare come server per fornire alcuni servizi agli altri studenti.

Anche allora esistevano già alcune distribuzioni specifiche per trasformare un PC in un Firewall, tra cui Smoothwall. Il mio problema era la necessità di tenere traccia degli accessi degli utenti ad Internet e quella di limitare l'accesso ai soli utenti autorizzati. La soluzione che si andava prospettando all'epoca era quella del Captive Portal: un mix di regole del firewall, script lato server (di solito PHP) e database RADIUS per l'autenticazione.

Una configurazione del genere, oltre ad essere estremamente complicata, avrebbe ucciso definitivamente il vecchio Pentium 133, per tanto era fuori questione. Inoltre allora non mi fidavo molto di PHP e farlo eseguire con i privilegi di root mi sembrava un modo rapido per trovare rogne.

Così, armato di pazienza e di Google, mi misi a cercare delle alternative e fu così che venni a sapere dell'esistenza di Authpf: un programma scritto in C che si interfaccia con il firewall di OpenBSD, pf, e carica alcune regole nel firewall stesso in base alla sua configurazione. Tutto quello che bastava fare era impostare Authpf come shell dell'utente, creare una regola che aggiungesse l'IP dell'utente autenticato a quelli a cui era consentito il NAT e il gioco era fatto!

Il fatto che pf avesse una sintassi molto più sana di mente di quella che allora si usava con iptables mi convinse del tutto. A titolo di confronto eccovi le differenze di configurazione che occorreva apportare all'epoca in Linux per fare NAT e in OpenBSD per fare NAT:

iptables:
/sbin/iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
/sbin/iptables -A FORWARD -i eth0 -o eth1 -m state \
-A FORWARD -i eth1 -o eth0 -j ACCEPT
--state RELATED,ESTABLISHED -j ACCEPT /sbin/iptables
Da inserire in uno script che va avviato automaticamente ad ogni riavvio del sistema.

pf:

nat on dc0 from 192.168.0.0/24 to any -> (dc0)

Da aggiungere a /etc/pf.conf per fare NAT di tutta la sottorete, oppure da modificare leggermente ("$user_ip" al posto di "192.168.0.0/24") ed aggiungere a /etc/authpf/authpf.rules per abilitare al NAT solo gli IP degli utenti che si sono autenticati.

In entrambi i casi occorre abilitare il forwarding dei pacchetti IP, che è disabilitato nelle impostazioni predefinite sia del kernel Linux che del kernel di OpenBSD.

Le mie considerazioni sulla sintassi adesso forse non sono più valide: pf ha cambiato la sua sintassi a partire dalla versione 4.7 di OpenBSD e NetFilter è stato oggetto di numerose revisioni nella serie 3 di Linux con l'introduzione di nftables. Ma resta vero il fatto che nel 2006 la situazione era quella che vi ho descritto. Convinto di aver fatto la scelta giusta misi in piedi quel gateway con OpenBSD. Funzionò magnificamente e diede origine ad altre leggende che non racconterò in questo articolo.

La bizzarria maggiore di pf è forse il fatto che sia nato assolutamente per caso. OpenBSD infatti condivideva il firewall di FreeBSD: ipf. "Cosa li ha spinti ad abbandonare un firewall che funziona e a scriverne uno da zero?" chiederete voi. "Problemi con la licenza" risponderò io.

Darren Reed, l'autore di ipf, pose la condizione che non fosse possibile distribuire versioni modificate di ipf. Una condizione del genere va a cozzare direttamente con i principi del fondatore di OpenBSD, Theo DeRaadt, e questo fece sì che, a partire da OpenBSD 3.0 ipf venne rimosso. Coincidenza volle che, nello stesso periodo, Daniel Hartmeier stesse sperimentando con un suo packet filter e che non avesse problemi ad includere i suoi esperimenti in OpenBSD sotto licenza BSD. A Daniel si aggiunsero presto Henning Brauer e Mike Frantzen. Costoro hanno curato lo sviluppo di pf, coadiuvati dal resto del team di sviluppatori di OpenBSD.

Nel corso del tempo pf si è arricchito e, oltre alla redirezione di pacchetti con stateful inspection (necessaria per il NAT), ha aggiunto alle sue feature cosucce come il traffic shaping con instradamento dei pacchetti basato sia su code a priorità che su classi di traffico che misto, un sistema di logging binario dei pacchetti compatibile con tcpdump e perfino un protocollo intra-firewall per gestire ridondanza e failover (se un gateway-firewall va giù gli altri subentreranno a gestire anche la sua quota di traffico).

Mi rendo conto che non tutti avranno capito quanto ho elencato nel paragrafo precedente per cui mi limiterò a fare un piccolo confronto con un router CISCO systems affiancato da un firewall Cisco PIX:

  1. Servono due apparecchi: uno per fare da firewall e uno per fare da shaper.
  2. I due apparecchi vanno collegati in maniera ben precisa: mettere il router su rete pubblica vuol dire cercare rogne e mettere solo il firewall su rete privata vuol dire rinunciare alla possibilità di fare traffic shaping.
  3. Se non hai il contratto di supporto con CISCO non hai diritto agli aggiornamenti di sicurezza del firmware.
Vediamo ora un PC con OpenBSD:

  1. Basta un solo apparecchio. Tra l'altro non deve essere un PC: ci sono molte schede a basso consumo che possono reggere tranquillamente il traffico di una piccola rete.
  2. Una volta decise le interfacce basta etichettarle correttamente.
  3. Gli aggiornamenti di sicurezza sono gratis e continui per tutto il periodo di supporto di una release (ovvero un anno). Anche le release successive sono gratis.
Si può fare lo stesso con Linux? Sì, ma a quanto ne so non c'è traffic shaping e non c'è ridondanza tra i firewall nel kernel vanilla: occorre applicare una patch, con tutto quello che ne deriva (aggiorno il sistema con il gestore dei pacchetti della mia $DISTRO e mi dimentico che devo patchare il kernel... FUUUUUUUUUUU...).

Nel prossimo articolo: DHCP e DNS. Come fare in modo che i nostri utenti non debbano cercare il proprio indirizzo IP e come fare in modo che vi òdino per aver impedito loro di postare foto di gattini su Facebook.