<- SL: GNU/Linux e autoloader - Archivio Generale - Copertina - SL: Sicurezza ->

Sistemi Liberi


Il Mio "Personal Firewall"

di Giuseppe Lucente


L'articolo...

La storia di uno script per la configurazione di un firewall casalingo dalla sua nascita fino alle rifiniture conclusive, sottolineando le varie modifiche intercorse durante la stesura e passando attraverso le motivazioni che hanno spinto ad effettuare questi piccoli cambiamenti. Chiunque intenda configurarsi un firewall per la propria postazione casalinga troverà probabilmente in questo breve articolo diversi spunti per poter iniziare.



Indice


Introduzione: lo script iniziale

Piccola premessa:... tutto incomincia una cupa domenica pomeriggio, quando non sai cosa fare tutto il giorno e il PC diventa il miglior amico dell'uomo. Era da tanto che ci stavo pensando, ma non ero mai riuscito a concretizzare niente; finalmente avevo trovato l'occasione buona!!! Ecco quindi che seduto davanti alla mia scrivania con una buona dose di caffè e di voglia mi accingo a scrivere un personal firewall per la mia configurazione casalinga, sfruttando l'oramai noto tool IPTABLES incluso oggi giorno in qualsiasi distro Linux. Dopo aver sudato sette camice ecco i primi risultati, anche se lasciavano molto a desiderare. A questo punto entra in gioco Tommy, che dopo esser stato contattato via e-mail dal sottoscritto, dà la sua disponibilità totale, aiutandomi in questa ardua impresa. Fatta questa premessa, il mio compito (se così si può chiamare) è quello di mettere a confronto il mio primo script con quello che attualmente sto utilizzando. Quindi poche chiacchiere... ecco come si presentava all'inizio:

#!/bin/sh
# mio script per il settaggio di iptables
IPTABLES=/sbin/iptables
LOOPACK=127.0.0.1
# disabilita l'inoltro dei pacchetti durante la config. dell'Fw
echo 0 > /proc/sys/net/ipv4/ip_forward
# impostazione della politica di default
iptables -t filter -P INPUT DROP
iptables -t filter -P OUTPUT ACCEPT
iptables -t filter -P FORWARD DROP
iptables -A INPUT -m unclean -j DROP
#sezione regole
# consento traffico su loopback
iptables -A INPUT -i lo -j ACCEPT
# abilito connessioni Web
iptables -t filter -A INPUT -p tcp --sports 80 -j ACCEPT
# abilito connessioni SMPT e POP3
iptables -t filter -A INPUT -p tcp --sport 25 -j ACCEPT
iptables -t filter -A INPUT -p tcp --sport 110 -j ACCEPT
# abilito servizio DNS per protocolli UDP e TCP
iptables -t filter -A INPUT -p tcp --sport 53 -j ACCEPT
iptables -t filter -A INPUT -p udp --sport 53 -j ACCEPT
# abilito connessioni SSH con attivazione Log
iptables -t filter -A INPUT -o ppp0 -p tcp --sport 22 -j ACCEPT
iptables -A INPUT -o ppp0 -p tcp --syn --sport 22 -m state --state NEW -j
LOG --log-level info --log-prefix "---SSH from ppp0---"
# accetto le richieste di ping provenienti da 127.0.0.1
iptables -t filter -A INPUT -s 127.0.0.1 -p icmp -j ACCEPT
iptables -t filter -A INPUT -p icmp --icmp-type 0 -j ACCEPT
# nego tutte le altre richieste di ping
iptables -t filter -A INPUT -p icmp --icmp-type echo-request -j DROP
# port scanner strani
iptables -A FORWARD -p tcp --tcp-flags SYN,ACK,FIN,RST RST -m limit --limit
1/s -j ACCEPT
# attivo registrazione connessioni
iptables -t filter -A INPUT -p tcp --syn -j LOG --log-prefix "FW: CONNESIONE" \
  --log-level info
# sezione mascheramento
iptables -t nat -A POSTROUTING -o ppp0 -j MASQUERADE
# fine dello script di configurazione firewall riabilito l'inoltro pacchetti
echo 1 > /proc/sys/net/ipv4/ip_forward

Questa la base sulla quale poi è stato pian piano modificato e completato.

Moduli e Kernel ...

Partendo dall'inizio dello script...

Innanzitutto sono stati aggiunti i moduli del connection-tracking, essenziali per sfruttare al meglio IPTABLES, i moduli per la registrazione avanzata dei log, per il Masquerade, e per l'utilizzo del multiport:

modprobe ip_conntrack
modprobe ip_conntrack_ftp
modprobe ipt_LOG
modprobe ipt_MASQUERADE
modprobe ipt_multiport

Dopodiché è stato rimosso il parametro "ip_forward", necessario solamente nel caso in cui l'host venga utilizzato come router. Conseguentemente a quello appena detto è stato quindi disabilitato anche il traffico sulla catena "FORWARD". Il passo successivo è stato includere nello script alcuni parametri del Kernel non strettamente necessari per il funzionamento del Firewall, ma comunque importanti per salvaguardare tutto il traffico:

blocco i ping verso la mia macchina
echo '1' > /proc/sys/net/ipv4/icmp_echo_ignore_all
echo '1' > /proc/sys/net/ipv4/icmp_echo_ignore_broadcasts
# attivo protezione contro attacchi Spoofing
echo '1' > /proc/sys/net/ipv4/icmp_ignore_bogus_error_responses
echo '1' > /proc/sys/net/ipv4/tcp_syncookies
echo '1' > /proc/sys/net/ipv4/conf/all/rp_filter
# logga in /var/log/messages i pacchetti malformati e scartati automaticamente
echo '1' > /proc/sys/net/ipv4/conf/all/log_martians
echo '0' > /proc/sys/net/ipv4/conf/all/accept_source_route
echo '0' > /proc/sys/net/ipv4/conf/all/accept_redirects

Default Policy e Regole personali:

Passiamo alla politica di default. Qui è stato droppato in maniera decisa tutto!!! Trattandosi di un PC casalingo che non deve offrire servizi di nessun genere, è stato deciso di giocarsi tutto sulle connesioni in uscita. Quindi sono solo io a collegarmi all'esterno. Detto questo, verrà utilizzata prevalentemente la catena di "OUTPUT" per definire le connessioni richieste da me verso l'esterno, mentre quella di "INPUT" avrà il mero compito di salvaguardare quei servizi che non possono essere disabilitati (ved. X Server) e quindi risulterebbero essere pericolosamente scoperti.
Terminata la sezione Default Policy passiamo a quella riguardante le regole personali: inanzitutto è stata aggiunta una regola che permette di accettare tutte le connessioni dipendenti da quelle iniziate da me, per evitare che i pacchetti debbano correre attraverso il Firewall in cerca di una regola adeguata e comunque perchè si può reputare sicura la fonte che le ha inizializzate :).

# accetto tutte le connessioni correlate alla mia
iptables -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT

La successiva modifica chiama in causa tutte le regole del Firewall a partire da questo punto.
Infatti da questo momento tutte le regole non specificherano più la porta sorgente con il parametro "--sport" ma quella di destinazione con il parametro "--dport". E' più indicato specificare che sono io che mi collego ad un servizio su una porta nota, e quindi allo stesso tempo permetto al traffico di far ritorno verso di me. In questo modo se non sono io ad aprire connessione, nessuno può collegarsi.

Continuando nel percorso delle catene ecco quali sono state le ulteriori variazioni:

# abilito servizio DNS per protocolli UDP
iptables -t filter -A OUTPUT -p udp --dport 53 -j ACCEPT

Due correzioni importanti da segnalare! Come prima cosa, la regola è stata spostata dal centro del Firewall, e posizionata subito dopo quella dello "state" delle connessioni. Motivo: il traffico dns rappresenta la maggioranza di traffico che effettuo, quindi è opportuno configurarlo subito all'inizio.
Seconda modifica: è stata eliminata una regola superflua. Infatti nella bozza iniziale veniva abilitato il servizio DNS anche su protocollo TCP, il che di fatto è inutile visto che sul mio PC non gira assolutamente un server DNS

# abilito la navigazione web e il traffico https
iptables -t filter -A OUTPUT -p tcp -m multiport --dports 80,443 -j ACCEPT

è stato sfruttato l'attributo "multiport", che mi ha permesso di accorciare di una regola il Firewall avendo aggiunto nella stessa regola due porte e non solo una, con conseguente probabilità di aver velocizzato il Firewall, anche se agli effetti pratici non si nota.

# abilito connessioni SSH con attivazione Log
iptables -t filter -A OUTPUT -p tcp --syn --dport 22 -m state --state NEW -j LOG \
  --log-level info --log-prefix "---SSH from ppp0---"
iptables -t filter -A OUTPUT -p tcp --dport 22 -j ACCEPT

La regola qui sopra permette di effettuare connessioni SSH e di registrare tutto mediante i LOG file. La parte modificata è proprio quella riguardante questi ultimi, che vanno specificati prima della regola sul pacchetto, pena il non funzionamento della parte LOG.

# disabilito pacchetti ICMP di tipo echo-request
iptables -t filter -A INPUT -p icmp ! --icmp-type 8 -j ACCEPT

Visto che ritengo pericoloso che il mio PC risponda alle richieste di echo-reply ho preferito disabilitarli, permettendo così a tutti gli altri pacchetti icmp di passare.

blocco tutti i pacchetti destinati al server X11 e al Xfont Server
iptables -t filter -A INPUT -i ppp0 -p tcp --dport 6000:6010 -j DROP
iptables -t filter -A INPUT -i ppp0 -p udp --dport 6000:6010 -j DROP
iptables -t filter -A INPUT -i ppp0 -p tcp --dport 7000:7010 -j DROP
iptables -t filter -A INPUT -i ppp0 -p udp --dport 7000:7010 -j DROP

Questa regole non erano presenti nel firewall iniziale, sono state aggiunte successivamente. Considerato il fatto che il PC viene utilizzato prevalentemente con il server X attivo, ho ritenuto opportuno aggiungere queste regole di modo da proteggerlo dietro al firewall. A seguito infatti di un port-scanning ho rilevato che la porta 6000 era aperta.
Piccola nota di percorso: a dir la verita questa ultima sezione riguardante il server X avrei potuto anche ometterla. Infatti la politica di default del Firewall è quella di droppare tutto tranne quello che viene esplicitamente accettato da me. Visto e considerato che nel firewall originale una regola sul server X non era stata indicata, i pacchetti diretti verso quella porta sarebbero stati comunque scartati. Ad ogni modo ho preferito aggiungere la regola per maggiore sicurezza e comunque considerato il fatto che il firewall è abbastanza contenuto.

# aggiungo questa regola in caso di problemi nella politica di DEFAULT
iptables -A INPUT -j DROP

Per terminare è stata aggiunta questa regola conclusiva, che può tornare utile in caso di problemi del firewall; se avessi impostato la politica di default in Accept allora questa regola avrebbe droppato tutto quello che non trova una corrispondenza nel Firewall.

Script completo e Conclusioni

Sicuramente il firewall è migliorabile; qualsiasi persona con competenze e capacità legate alla network-security avrebbe trovato il modo di renderlo più leggero e affidabile; comunque in generale dopo tutte le prove effettuate si è dimostrato valido sotto svariati punti di vista.

Un ringraziamento ancora a Tommy per la generosa disponibilità data.
Beppe
Qui sotto lo script completo dopo tutte le modifiche.>

#!/bin/sh
iptables="/sbin/iptables"
modprobe ipt_LOG
modprobe ip_conntrack
modprobe ip_conntrack_ftp
modprobe ipt_MASQUERADE
modprobe ipt_multiport
# blocco i ping verso la mia macchina
echo '1' > /proc/sys/net/ipv4/icmp_echo_ignore_all
echo '1' > /proc/sys/net/ipv4/icmp_echo_ignore_broadcasts
# attivo protezione contro attacchi Spoofing
echo '1' > /proc/sys/net/ipv4/icmp_ignore_bogus_error_responses
echo '1' > /proc/sys/net/ipv4/tcp_syncookies
echo '1' > /proc/sys/net/ipv4/conf/all/rp_filter
# logga in /var/log/messages i pacchetti malformati e scartati automaticamente
echo '1' > /proc/sys/net/ipv4/conf/all/log_martians
echo '0' > /proc/sys/net/ipv4/conf/all/accept_source_route
echo '0' > /proc/sys/net/ipv4/conf/all/accept_redirects
# configurazione politica di default per la tabella filter
iptables -t filter -P INPUT DROP
iptables -t filter -P OUTPUT DROP
iptables -t filter -P FORWARD DROP
# configurazione politica di default per la tabella nat
iptables -t nat -P PREROUTING ACCEPT
iptables -t nat -P POSTROUTING ACCEPT
iptables -t nat -P OUTPUT ACCEPT
# configurazione politica di default per la tabella mangle
iptables -t mangle -P PREROUTING ACCEPT
iptables -t mangle -P OUTPUT ACCEPT
# scarta subito pacchetti malformati
iptables -A INPUT -m unclean -j DROP
# consento traffico su loopback
iptables -A INPUT -i lo -j ACCEPT
# regole personali
# accetto tutte le connessioni correlate alla mia
iptables -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
# abilito servizio DNS per protocolli UDP
iptables -t filter -A OUTPUT -p udp --dport 53 -j ACCEPT
# abilito la navigazione web e il traffico https
iptables -t filter -A OUTPUT -p tcp -m multiport --dports 80,443 -j ACCEPT
# abilito connessioni SMPT e POP3
iptables -t filter -A OUTPUT -p tcp --dport 25 -j ACCEPT
iptables -t filter -A OUTPUT -p tcp --dport 110 -j ACCEPT
# abilito connessioni SSH (SecureShell) con attivazione Log
iptables -t filter -A OUTPUT -p tcp --syn --dport 22 -m state --state NEW -j LOG \
  --log-level info --log-prefix "---SSH from ppp0---"
iptables -t filter -A OUTPUT -p tcp --dport 22 -j ACCEPT
# blocco tutti i pacchetti destinati al server X11 e al Xfont Server
iptables -t filter -A INPUT -i ppp0 -p tcp --dport 6000:6010 -j DROP
iptables -t filter -A INPUT -i ppp0 -p udp --dport 6000:6010 -j DROP
iptables -t filter -A INPUT -i ppp0 -p tcp --dport 7000:7010 -j DROP
iptables -t filter -A INPUT -i ppp0 -p udp --dport 7000:7010 -j DROP
# disabilito pacchetti ICMP di tipo echo-request
iptables -t filter -A INPUT -p icmp ! --icmp-type 8 -j ACCEPT
# aggiungo questa regola in caso di problemi nella politica di DEFAULT
iptables -A INPUT -j DROP
# mascheramento
iptables -t nat -A POSTROUTING -o ppp0 -j MASQUERADE
# riabilita l'inoltro dei pacchetti alla fine delle operazioni di settaggio
# del firewall



L'autore

Giuseppe Lucente alias Beppe è un utente casalingo con tanta passione per tutto quello che ruota attorno al mondo dell'informatica.
È fuggito appena in tempo nel 1999 da un regime dittatoriale governato da sistemi CloseSource per (e)migrare verso un regime più democratico: Linux, che gli ha concesso di ampliare le proprie capacità.
Amante degli animali, ha deciso di intraprendere una dura lotta per la salvaguardia dei pinguini :)



<- SL: GNU/Linux e autoloader - Archivio Generale - Copertina - SL: Sicurezza ->