Introduzione
Configurare un firewall IPFW sulla vostra macchina, soprattutto se viene usata spesso in rete e se è un gateway di una rete interna. Questo articolo vi mostrerà anche come settare NATd per fare “masquerading” ed uscire con i client interni alla vostra LAN in Internet con un unico IP pubblico (quello del gateway a cui connetterete il vostro modem o altro apparecchio).
CASI (classici in cui va bene l’applicazione di un simile firewall):
Caso 1: macchina con installato FreeBSD 4.X, collegata ad Internet tramite modem analogico 56k o ISDN.
Caso 2: macchina con installato FreBSD 4.x, collegata ad Internet tramite modem o router ADSL con PPPoE o tecnologie PointToPoint analoghe (PPPoA, ecc.).
Caso 3: macchina collegata ad Internet in uno dei modi di cui sopra, a cui in più è collegata una piccola rete interna (LAN casalinga o piccolo ufficio per intenderci, ma potrebbe anche essere più grossa… è il concetto che conta) o anche un semplice PC su cavo crossed (o invertito).
In pratica:
- Interfaccia verso l’esterno = tun0 (sarebbe l’IP di “me” nelle rules)
- interfaccia verso l’interno (SE CASO 3) = rl0
- interfaccia su cui fare NAT dalle macchine client (SE CASO 3) = tun0
- nome del file di conf delle rules del kernel = /etc/rc.fire
- nome del file di conf di natd = /etc/natd.conf
- nome del file di conf generale = /etc/rc.conf
FreeBSD ha a disposizione 2 differenti tipologie di dispositivi firewall nei suoi sorgenti: IPFW (quello “storico” presente da sempre nelle *BSD, e IPFILTER).
Naturalmente in questo articolo analizzeremo ed implementeremo IPFW.
1) La prima cosa da fare è ricompilare il KERNEL. Le opzioni che andranno aggiunte nel nostro file di configurazione del kernel stesso (nell’art. sarebbe il “MY_PANDORA”) sono:
options IPFIREWALL
#abilita il firewall nel kernel
options IPFIREWALL_VERBOSE
#abilita il logging per il firewall, solitamente in /var/log/security.
Non indispensabile per il funzionamento ma vivamente consigliato.
options IPFIREWALL_VERBOSE_LIMIT=200
#Limita il numero di logs in /var/log/security per non saturare la partizione con messaggi ripetitivi di ipfw.
Si rilancia il logging di volta in volta in automatico con cron solitamente, per farlo ripartire.
options IPDIVERT
#abilita il divert socket, in pratica il NATD, che vedremo poi.
Queste invece sono “options” aggiuntive che io consiglio, anche in previsione di un futuro ampliamento del firewall (ad es. per IPv6). Ricordate che un firewall va costantemente mantenuto, controllato ed aggiornato… non sedetevi sugli allori sentendovi ultraprotetti dopo aver “tirato su” un qualsiasi firewall.
options IPFIREWALL_DEFAULT_TO_ACCEPT
#setta il firewall di base “Tutto aperto” (è soprattutto utile per gestire firewall su macchine remote, in modo da non rimanere “tagliati fuori” dopo un flush). Questa opzione la si ottiene comunque anche nelle rules settando come penultima rule:
" ipfw add 635534 allow ip from any to any "
Viceversa, se abilitiamo (lo consiglio) l’options di cui sopra, metteremo, per chiudere tutto: “ipfw add 65534 deny all from any to any“.
#options IPV6FIREWALL
#come IPFIREWALL, ma per ipv6: NON METTETELA SE NON VOLETE UN SERVER V6
#options IPV6FIREWALL_DEFAULT_TO_ACCEPT
#come IPFIREWALL_VERBOSE ma per ipv6
options TCP_DROP_SYNFIN
#serve ad ignorare i pacchetti in arrivo con flags SYN+FIN. Questo previene gli scan con nmap et similia identificandoli.
Non è raccomandato per macchine con web servers installati e funzionanti (Apache), perchè viola delle specifiche TCP/IP.
options ICMP_BANDLIM
#abilita la protezione dai tipici attacchi D.O.S. (Denial Of Service).
Una volta salvato il nostro file di testo del kernel compiliamo con i “soliti” comandi:
#cd /usr/src #make buildkernel KERNCONF=MY_PANDORA && make installkernel KERNCONF=MY_PANDORA && shutdown -r now "
2) Nel frattempo che la macchina sta compilando il kernel, noi ci preoccuperemo di creare e/o sistemare i nostri files di configurazione di IPFW. Cominciamo da /etc/rc.conf (come ho già detto in altri docs, il file di conf direi più importante per FreeBSD o perlomeno quello con più riferimenti e settaggi di primaria importanza), ed aggiungiamo le righe seguenti:
firewall_enable="YES" firewall_type="filename" firewall_logging="YES" firewall_quite="NO" firewall_script="/etc/rc.fire" #firewall_flags="" #ATTENZIONE:QUESTE RIGHE SOLO PER "CASO 3" natd_enable="YES" natd_interface="tun0" natd_flags="-f /etc/natd.conf"
3) ATTENZIONE: QUESTO FILE E’ SOLO PER “CASO 3”
Creiamo il file di conf del natd ossia /etc/natd.conf:
dynamic yes #per indirizzi dinamici use_sockets yes same_ports yes #esempi: il primo indirizzo+porta #(es.192.168.0.2:8003) è la macchina interna #nella lan, il secondo la porta reale sul GW in cui la si troverà dall'esterno #redirect_port tcp 192.168.0.2:8003 83 #redirect_port tcp 192.168.0.3:80 8088 #redirect_port tcp 192.168.0.3:110 450 #redirect_port tcp 89.0.0.14:110 110
4) Dato che con l’opzione (options IPDIVERT) e le ultime 3 righe di cui sopra in /etc/rc.conf, abbiamo abilitato il NATD, dobbiamo assicurarci di non avere in precedenza abilitato il ppp_natd. Possiamo averlo fatto in 2 differenti modi: nel file /etc/rc.conf fra le opzioni che abilitano PPP ad attivarsi automaticamente al boot della macchina: preoccupiamoci quindi di porre un bel simbolo di commento # davanti a ppp_nat=”YES” :
ppp_enable=”YES”
ppp_mode=”auto”
ppp_profile=”papchap”
#abbiamo già natd, disabilitiamo ppp-nat
ppp_nat=”NO”
L’altro sistema in cui ppp_natd potrebbe essere stato abilitato è nel file di configurazione di PPP stesso in /etc/ppp/ppp.conf. Se editando il suddetto file riscontrassimo la presenza della riga:
nat enable yes
preoccupiamoci anche questa volta di commentarla con il solito simbolo di commento # e l’opzione verra’ completamente ignorata. Si fa questo perchè sul sistema NON possono esistere diverse implementazioni di “network address translation” (nat appunto), ma una solamente e, potendo scegliere è sicuramente migliore, piu’ stabile e maggiormente configurabile quella presente nel kernel compilato con le istruzioni di cui sopra (natd), anche se è VALIDISSIMA, veloce e ben configurabile pure l’implementazione in ppp.conf (ppp-nat). Sta a voi quindi scegliere!
N.B.: IN PRATICA, LA DIFFERENZA FRA UN SEMPLICE PC CON SOLA CONNESSIONE AD INTERNET CON MODEM ANALOGICO O ROUTER -MODEM ADSL, ED UNO CON ANNESSA UNA PICCOLA LAN, DI CUI IL PC STESSO IN ESAME NE E’ IL GATEWAY, STA APPUNTO NEL FATTO CHE QUEST’ULTIMO, PER FAR “USCIRE” VERSO L’ESTERNO (IN INTERNET) LE MACCHINE DELLA RETE INTERNA (LA LAN), HA BISOGNO DEL “NATD”. IGNORATE IL DISCORSO NATD SE NON AVETE QUINDI NESSUNA RETE E/O PC CONNESSI ALLA VOSTRA MACCHINA-GATEWAY!
5) A questo punto, possiamo iniziare a creare il nostro file delle rules di IPFW, chiamato anche file delle “ruleset”. Naturalmente ognuno lo modifichera’ per le proprie esgenze, soprattutto per quanto riguarda l’apertura o meno di servizi e porte sul proprio sistema. Esistono comunque di solito una serie di rules iniziali chiamate da me “standard”, che van di solito bene per tutti: servono ad eliminare tentativi di spoofing o altro, ad abilitare i server DNS ad uscire/entrare, le chiamate sull’indirizzo di loopback e le ns. interfacce di rete ecc.
N.B: Leggete BENE i commenti fra le righe e sistemate di conseguenza. NON dovete copiare ed incollare questo file cosi’ com’è, NON FUNZIONEREBBE a dovere, o addiritura non funzierà per nulla !
---------------------/etc/rc.fire ESEMPIO--------------------- #!/bin/sh # Firewall rules #fare un "flush" prima di ricaricare le rules ipfw -f flush ipfw add allow ip from any to any via lo0 ipfw add allow ip from any to any via rl0 ipfw add divert 8668 ip from any to any via tun0 ipfw add deny log logamount 500 ip from any to 127.0.0.0/8 ipfw add deny log logamount 500 ip from 127.0.0.0/8 to any ipfw add check-state #Regole varie per "attacchi" ipfw add deny ip from any to any ipoptions rr ipfw add deny ip from any to any ipoptions ts ipfw add deny ip from any to any ipoptions lsrr ipfw add deny ip from any to any ipoptions ssrr ipfw add deny tcp from any to any tcpflags syn,fin ipfw add deny tcp from any to any tcpflags syn,rst ipfw add deny tcp from any 0 to any ipfw add deny tcp from any to any 0 ipfw add deny udp from any 0 to any ipfw add deny udp from any to any 0 #mia rete -miei hosts interni ipfw add allow ip from 192.168.0.0/24 to any via tun0 ipfw add allow ip from any to 192.168.0.0/24 via tun0 ipfw add allow ip from 192.168.0.1 to 10.0.0.138 setup ipfw add allow ip from 192.168.0.0/24 to 10.0.0.0/24 via dc0 #sempre per spoofing ipfw add deny all from 192.168.0.0/16 to any ipfw add deny all from 172.16.0.0/12 to any ipfw add deny all from 10.0.0.0/8 to any ipfw add deny all from 169.254.0.0/16 to any ipfw add deny all from 192.0.2.0/24 to any ipfw add deny all from 240.0.0.0/4 to any ipfw add deny all from 0.0.0.0/8 to any ipfw add allow tcp from me to any out setup ipfw add allow tcp from any to any established ipfw add allow ip from any to any frag ipfw add allow tcp from me to any setup #servers dns ipfw add allow udp from me to any 53 keep-state #xntpd - ntpdate (se lo usate) ipfw add allow udp from me to any 123 keep-state #ssh ipfw add allow tcp from any to me 22 via tun0 setup #server web (apache e simili.. se lo usate) ipfw add allow tcp from any to me 80 via tun0 setup #server pop3 in locale (se l'avete) ipfw add allow tcp from any to me 110 via tun0 setup #server mail smtp (sendmail, postfix ecc.) ipfw add allow tcp from any to me 25 via tun0 setup #connessioni a/per ftpd (ns. eventuale server ftpd) ipfw add allow tcp from any to me 20,21 via tun0 setup ipfw add allow log tcp from any to me 49152-65535 via tun0 in setup #poter far traceroute ipfw add pass udp from any to any 33434-33523 out via tun0 #regole di "chiusura/apertura" finali ipfw add deny log logamount 500 tcp from any to any setup ipfw add allow ipv6 from any to any ipfw add allow log logamount 400 icmp from any to any icmptypes 0,3,8,11 ipfw add 65534 deny all from any to any ------------------------------fine------------------------------
Salviamo il file delle rules appena scritto con l’editor che volete ed assicuriamoci che abbia i permessi uguali al file di esempio “/etc/rc.firewall” (dateci un occhio a questo file e se volete implementatelo!)
chmod 644 /etc/rc.fire
ATTENZIONE: Per avviare correttamente il nostro firewall con NATd sia ora (all’avvio pero’ dovrebbe avviarsi tutto correttamente come da opzioni descritte sopra in /etc/rc.conf e con ppp oppure pppoe ecc. in automatico anc’esso al boot), che in futuro, dobbiamo dare PRIMA il comando per far partire natd, e solo successivamente lanciare ipfw con le nostre rules. Quindi i comandi da root sarebbero:
#/sbin/natd -interface tun0 -f /etc/natd.conf " #sh /etc/rc.fire
A questo punto se abbiamo già riavviato la macchina (shutdown -r now) dopo la compilazione del kernel bene, altrimenti facciamolo ora. Dopo il login verifichiamo che tutto sia OK con il comand “ps”:
#ps ax|grep natd 136 ?? Ss 0:00,10 /sbin/natd -f /etc/natd.conf -n tun0
#ipfw list (output completo relativo alle rules di cui sopra) 00100 allow ip from any to any via lo0 00200 allow ip from any to any via rl0 00300 divert 8668 ip from any to any via tun0 00400 deny log logamount 500 ip from any to 127.0.0.0/8 00500 deny log logamount 500 ip from 127.0.0.0/8 to any 00600 check-state 00700 deny ip from any to any ipoptions rr 00800 deny ip from any to any ipoptions ts 00900 deny ip from any to any ipoptions lsrr 01000 deny ip from any to any ipoptions ssrr 01100 deny tcp from any to any tcpflags syn,fin 01200 deny tcp from any to any tcpflags syn,rst 01300 deny tcp from any 0 to any 01400 deny tcp from any to any dst-port 0 01500 deny udp from any 0 to any 01600 deny udp from any to any dst-port 0 01700 allow ip from 192.168.0.0/24 to any via tun0 01800 allow ip from any to 192.168.0.0/24 via tun0 01900 allow ip from 192.168.0.1 to 10.0.0.138 setup 02000 allow ip from 192.168.0.0/24 to 10.0.0.0/24 via dc0 02100 deny ip from 192.168.0.0/16 to any 02200 deny ip from 172.16.0.0/12 to any 02300 deny ip from 10.0.0.0/8 to any 02400 deny ip from 169.254.0.0/16 to any 02500 deny ip from 192.0.2.0/24 to any 02600 deny ip from 240.0.0.0/4 to any 02700 deny ip from 0.0.0.0/8 to any 02800 allow tcp from me to any out setup 02900 allow tcp from any to any established 03000 allow ip from any to any frag 03100 allow tcp from me to any setup 03200 allow udp from me to any dst-port 53 keep-state 03300 allow udp from me to any dst-port 123 keep-state 03400 allow tcp from any to me dst-port 22 via tun0 setup 03500 allow tcp from any to me dst-port 80 via tun0 setup 03600 allow tcp from any to me dst-port 25 via tun0 setup 03700 allow tcp from any to me dst-port 20,21 via tun0 setup 03800 allow log tcp from any to me dst-port 49152-65535 via tun0 in setup 03900 allow udp from any to any dst-port 33434-33523 out via tun0 04000 deny log logamount 500 tcp from any to any setup 04100 allow ipv6 from any to any 04200 allow log logamount 400 icmp from any to any icmptypes 0,3,8,11 65534 deny ip from any to any 65535 allow ip from any to any
etcera. SE dovesse esserci qualcosa tipo: 00110 divert 8668 ip from any to any via rl0 ipfw: missing “to 00200 deny log logamount 400 ip from any to 127.0.0.0/8 01110 check-state ecc. ecc. quel ipfw: missing “to significa errore, in questo caso ci siam dimenticati di mettere la parola “to” nella rule in questione!
Un’altra cosa di importanza fondamentale è il discorso della numerazione delle “rules”. Come noterete, nel file vero e proprio (/etc/rc.fire) delle rules, queste ultime sono elencate in un certo ordine che NON E’ CASUALE. Se notate infine, quando date il comando “#ipfw list” vedete in pratica lo stesso elenco di rules ma stavolta numerate. Ebbene, ci son infatti 2 modi per creare il proprio file rules: quello di metterle nell’ordine logico come ho fatto nell’esempio indicato in questo articolo, e quello invece di metterle pure una dietro l’altra senza un apparente ordine, ma NUMERANDOLE da 1 a 65535. In entrambi i casi il risultato deve essere lo stesso.
Questo sistema della numerazione torna comodo quando si deve aggiungere al volo una rule, magari per chiudere una porta o un IP NON_desiderato senza dover “restartare” (ipfw -f flush && /etc/rc.fire) il firewall in questione.
Ad esempio se volessi aprire la porta 6667 al volo per magari collaudare un server IRC che sto testando, senza toccare nulla di quello che già è attivo e funzionanate darò da root il comando:
ipfw add 3750 allow tcp from any to me 6667 via tun0 setup
In questo modo la rule in questione, facendo un “ipfw list” la vedremo collocata far la rule 3700 e la 3800.
Per toglierla da li finite le nostre prove:
ipfw delete 3750
SE NON avessimo numerato la regola in questione, essa sarebbe stata collocata automaticamente da ipfw appena prima della rule di default (ossia la numero 65535, cioè l’ultima, quindi quella che decide se il firewall è TUTTO OPEN oppure TUTTO CLOSED), quindi alla numero 65534, che già è occupata da “deny ip from any to any” (di findamentale importanza). Ha si, per la cronaca, come si dovrebbe aver già capito, il sistema ordina automaticamente le rules in ordine incrementale di 100, quando esse non son numerate ma messe in ordine logico nel vs. file delle regole (regole=rules … per non far troppe ripetizioni!).
In pratica e detto in parole molto povere, ma forse per questo molto chiare per alcuni, la regola successiva è conseguenza della precedente…solitamente. esempio pratico. Se consideriamo questa serie di rules:
03600 allow tcp from any to me dst-port 25 via tun0 setup 03700 allow tcp from any to me dst-port 20,21 via tun0 setup 03800 allow log tcp from any to me dst-port 49152-65535 via tun0 in setup 03900 allow udp from any to any dst-port 33434-33523 out via tun0 65534 deny ip from any to any
…e ne analizziamo il significato. In breve vuole dire: “Accetta in ingresso da tun0 quelli che entrano dalla porta 25, 20, 21, e dai range di porte 49152-65535 e 33434-33523 … pero’ tutto il resto chiudilo (regola 65534). Spero di esser stato abbastanza chiaro !)
Consigli
Non sediamoci qui però… un firewall, se avete letto un pò di docs in rete (sennò fatelo prossimamente), si dice essere sempre da verificare e da aggiornare, da adattare quindi alle nostre esigenze. Loggate, leggete i logs e cercate di capire se qualcosa non va. Se tutto va bene, (!) prossimamente questo doc sara’ probabilmente integrato da altri piu’ esplicativi e complessi, che comprenderanno varie tipologie e configurazioni su macchine con diverse esigenze. E poi NON scordatevi di dare una buona lettura a man ipfw che fra l’altro è piuttosto chiaro da leggere.