Script di base per configurare il firewall Netfilter
Da Linux@P2P Forum Italia.
Indice |
Netfilter
Linux ha integrato a livello di kernel un potente firewall, chiamato Netfilter.
La configurazione di Netfilter può essere effettuata attraverso l'utilizzo di interfacce grafiche come GuardDog e FireStarter. L'utilizzo di queste interfacce, se da un lato facilitano la gestione del firewall, possono renderne difficoltosa e poco precisa la messa a punto. Per questo motivo, spesso, è preferibile impostare le regole manualmente attraverso il comando iptables.
Il comando iptables generalmente viene utilizzato all'interno di uno script, che, attraverso il ripetuto lancio del comando imposta tutta la catena delle regole.
Per maggiori informazioni sul comando iptables si rimanda alla pagina della documentazione di Netfilter, dove è possibile reperire molto materiale anche il italiano.
Nota: attualmente nelle versioni ufficiali del Kernel Linux, Netfilter è in grado di effettuare il filtraggio a livello ISO/OSI 3 e 4, quindi il firewall può riconoscere il traffico in base all'indirizzo/porta di partenza/destinazione e lo stato della connessione, ma non è in grado di identificare il protocollo utilizzato. Queste capacità sono in genere più che sufficienti per garantire un elevato livello di protezione, ma nel caso si abbia la necessità di effettuare il filtraggio dei protocolli, è possibile utilizzare l'estensione L7-filter.
Dove utilizzare gli script
Questi script non eseguono alcun controllo sull'eventuale impostazione attuale del firewall, ma procedono eliminando tutte le catene e impostando le proprie. Per il loro utilizzo è opportuno disinstallare GuardDog, Firestarter, shorewall, Webmin Firewall ed ogni altra interfaccia eventualmente installata, per evitare possibili conflitti. Questo tuttavia non impedisce di utilizzare questi schemi di regole in uno script più complesso.
Gli script possono essere messi nella directory /sbin, in quanto il loro utilizzo è riservato all'utente root, ed è consigliabile impostarne i permessi a 700.
Lo script che attiva il firewall dovrebbe essere lanciato prima dell'attivazione dell'interfaccia di rete, o, comunque, durante l'avvio del sistema. Se si utilizza un sistema Debian o derivato (come Ubuntu), ad esempio, può essere utilizzata la direttiva pre-up in /etc/network/interfaces, ad esempio:
auto lo
iface lo inet loopback
pre-up /sbin/fwup.sh
Disattivare il firewall
Questo script cancella tutte le regole impostate in netfilter, permette tutte le connessioni in ingresso ed in uscita dalla macchina, impedendo comunque l'attraversamento del traffico verso altre macchine.
#!/bin/bash ## RESET DELLE REGOLE ## iptables -F iptables -t mangle -F iptables -t nat -F iptables -X iptables -t mangle -X iptables -t nat -X ## TABELLA FILTER ## # Definizione criterio generale iptables -P INPUT ACCEPT iptables -P FORWARD DROP iptables -P OUTPUT ACCEPT
Attivare il firewall
A seconda delle esigenze, si dovrà configurare di conseguenza la politica di filtraggio dei pacchetti, in modo da garantire il massimo della sicurezza compatibilmente con la necessità di permettere il corretto funzionamento dei servizi.
Negli esempi riportati si considererà il caso in cui la connessione ad Internet avvenga attraverso un modem (interfaccia ppp0), poiché con un router la presenza di un NAT costituisce già un'ottima difesa e, spesso, rende superflua la presenza di un firewall sul PC collegato.
Impostazione base
L'obiettivo di queste regole è quello di bloccare tutti i tentativi di connessione dall'esterno, permettendo in ingresso il solo traffico di risposta.
#!/bin/bash # Per prima cosa ripuliamo la configurazione eventualmente # presente ## RESET DELLE REGOLE ## iptables -F iptables -t mangle -F iptables -t nat -F iptables -X iptables -t mangle -X iptables -t nat -X ## TABELLA FILTER ## # Le regole di default imporranno di scartare tutti i pacchetti # a meno che non venga specificato diversamente. In questo modo # eviteremo di lasciare inavvertitamente qualcosa aperto # Definizione criterio generale iptables -P INPUT DROP # scarta tutti i pacchetti in ingresso iptables -P FORWARD DROP # scarta tutti i pacchetti in attraversamento iptables -P OUTPUT ACCEPT # accetta tutto il traffico che vuole uscire # Per maggiore sicurezza, diciamo a Netfilter di scartare tutto il traffico # non valido, come ad esempio quello che non appartiene a nessuna # connessione conosciuta # Frammenti e pacchetti non validi iptables -A INPUT -f -j DROP iptables -A INPUT -m state --state INVALID -j DROP iptables -A OUTPUT -f -j DROP iptables -A OUTPUT -m state --state INVALID -j DROP # Netfilter disciplina tutto il traffico, anche quello che passa per # l'interfaccia di loopback, che non deve essere bloccato # Traffico di loopback iptables -A INPUT -i lo -j ACCEPT iptables -A OUTPUT -o lo -j ACCEPT # Per poter utilizzare una connessione ad Internet, comunque, è necessario # permettere l'ingresso dei pacchetti appartenenti o correlati ad una # connessione aperta dalla nostra macchina, che, altrimenti, verrebbe # bloccato in vitrù della configurazione di default ## TABELLA FILTER - INGRESSO ## # Accetta pacchetti di connessioni esistenti iptables -A INPUT -i ppp0 -m state --state ESTABLISHED,RELATED -j ACCEPT
Questa configurazione consente la completa invisibilità da Internet, in quanto la nostra macchina non risponderà a nessun tentativo di contatto, ping, port scan... perché tutto il traffico in ingresso non aspettato verrà scartato dal Kernel.
Apertura delle porte
Nel caso in cui volessi usare un qualsiasi programma P2P (aMule, MLdonkey, Azureus...), questo non potrebbe funzionare correttamente con le regole impostate nello script precedente, in quanto ogni tentativo di connessione da parte di un altro nodo cadrebbe nel vuoto (tipica causa del famigerato id basso in eMule).
Dovremo quindi impostare altre regole per permettere il passaggio del traffico destinato al client P2P, attraverso l'individuazione delle porte utilizzate.
Nel nostro esempio supponiamo di dover lasciare entrare tutto il traffico destinato al nostro client P2P (o a qualsiasi altro servizio che dobbiamo rendere visibile), in ascolto sulle porte TCP 4662 e 4668, e UDP 18745. Le porte effettivamente utilizzate possono essere diverse, per conoscere quelle aperte dal client può essere utile il comando:
# netstat -pnl|grep nome_eseguibile-client
Nel caso in cui il client consenta il controllo remoto, occorre fare attenzione a non aprire le porte utilizzate per il controllo stesso, a meno che non si sappia quello che si sta facendo.
Aggiungiamo quindi al nostro script le tre righe:
#!/bin/bash ## RESET DELLE REGOLE ## iptables -F iptables -t mangle -F iptables -t nat -F iptables -X iptables -t mangle -X iptables -t nat -X ## TABELLA FILTER ## # Definizione criterio generale iptables -P INPUT DROP iptables -P FORWARD DROP iptables -P OUTPUT ACCEPT # Frammenti e pacchetti non validi iptables -A INPUT -f -j DROP iptables -A INPUT -m state --state INVALID -j DROP iptables -A OUTPUT -f -j DROP iptables -A OUTPUT -m state --state INVALID -j DROP # Traffico di loopback iptables -A INPUT -i lo -j ACCEPT iptables -A OUTPUT -o lo -j ACCEPT ## TABELLA FILTER - INGRESSO ## # Accetta pacchetti di connessioni esistenti iptables -A INPUT -i ppp0 -m state --state ESTABLISHED,RELATED -j ACCEPT # Accettiamo il traffico in ingresso nelle porte del client # Accetta connessioni per client P2P iptables -A INPUT -i ppp0 -p tcp --dport 4662 -j ACCEPT iptables -A INPUT -i ppp0 -p tcp --dport 4668 -j ACCEPT iptables -A INPUT -i ppp0 -p udp --dport 18745 -j ACCEPT
Condivisione della connessione
Supponiamo ora di avere 2 PC, pippo e pluto: pippo è connesso ad Internet con un modem (ppp0) e vuole condividere la connessione con il computer pluto, connesso all'interfaccia eth0 di pippo con un normale cavo ethernet. Non ha importanza quale sia il sistema operativo di pluto.
Supponiamo anche che pippo ospiti un client P2P che, quindi, dovra accettare un certo tipo di traffico.
L'interfaccia eth0 di pippo dovrà essere configurata con un IP statico (ad es. 192.168.0.10 e netmask 255.255.255.0), perché dovrà fungere da gateway per pluto. Se non si dispone di un servizio DHCP opportunamente configurato, anche l'interfaccia pluto dovrà essere configurata staticamente (nel nostro caso con indirizzo 192.168.0.20/255.255.255.0), avendo l'accortezza di impostare come default gateway 192.168.0.10.
Per permettere a pluto di uscire su Internet con l'indirizzo pubblico dell'interfaccia ppp0 di pippo, dovremo:
- abilitare il passaggio dei pacchetti IP da un'interfaccia all'altra;
- caricare eventuali moduli necessari per il corretto tracciamento delle connessioni che richiedono attenzioni particolari (come l'FTP e il SIP).
- indicare a Netfilter come effettuare il NAT;
#!/bin/bash ## IMPOSTAZIONE DEL KERNEL ## # Abilito il forwarding dei pacchetti echo 1 > /proc/sys/net/ipv4/ip_forward # Carico moduli per tracciamento FTP e SIP modprobe ip_nat_ftp modprobe ip_conntrack_ftp modprobe ip_nat_sip modprobe ip_conntrack_sip ## RESET DELLE REGOLE ## iptables -F iptables -t mangle -F iptables -t nat -F iptables -X iptables -t mangle -X iptables -t nat -X ## INIZIALIZZAZIONE ## # Definizione criterio generale iptables -P INPUT DROP iptables -P FORWARD DROP iptables -P OUTPUT ACCEPT # Frammenti e pacchetti non validi iptables -A INPUT -f -j DROP iptables -A INPUT -m state --state INVALID -j DROP iptables -A OUTPUT -f -j DROP iptables -A OUTPUT -m state --state INVALID -j DROP # Traffico di loopback iptables -A INPUT -i lo -j ACCEPT iptables -A INPUT -i ! lo -s 127.0.0.0/8 -j DROP iptables -A OUTPUT -o lo -j ACCEPT # Definizione zone # L'utilizzo di più catene per identificare le zone rende più # ordinata la gestione del firewall, riducendo il rischio di errori. # La prima zona riguarda il traffico della LAN tra pippo e pluto, # ed è composta dalle due catene IN_LAN e OUT_LAN, a seconda # della direzione del traffico. Non interessa l'accesso ad Internet da parte # di pluto, ma, ad esempio, il servizio di condivisione file e stampanti. iptables -N IN_LAN # traffico in ingresso a pippo dalla LAN (pluto) iptables -A INPUT -i eth0 -j IN_LAN iptables -N OUT_LAN # traffico in uscita da pippo verso la LAN (pluto) iptables -A OUTPUT -o eth0-j OUT_LAN # Le catene IN_WAN e OUT_WAN regolano il traffico tra pippo e Internet. iptables -N IN_WAN iptables -A INPUT -i ppp0 -j IN_WAN iptables -N OUT_WAN iptables -A OUTPUT -o ppp0 -j OUT_WAN # Le catene LAN_WAN e WAN_LAN ruguardano l'accesso ad Internet da parte dei # nodi della LAN (pluto) e che attraversano pippo. iptables -N LAN_WAN iptables -A FORWARD -i eth0 -o ppp0 -j LAN_WAN iptables -N WAN_LAN iptables -A FORWARD -i ppp0 -o eth0 -j WAN_LAN ## TABELLA FILTER - INGRESSO ## # Accetta connessioni per client P2P iptables -A IN_WAN -p tcp --dport 4662 -j ACCEPT iptables -A IN_WAN -p tcp --dport 4668 -j ACCEPT iptables -A IN_WAN -p udp --dport 18745 -j ACCEPT # Accetta pacchetti di connessioni esistenti iptables -A IN_LAN -m state --state ESTABLISHED,RELATED -j ACCEPT ## TRAFFICO NATTATO E SOTTORETI ## # Accettiamo tutto il traffico LAN proveniente da pluto. # Servizi sottoreti iptables -A IN_LAN -j ACCEPT # Effettuiamo il NAT del traffico in uscita con il mascheramento iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE # Diciamo a Netfilter di permettere l'uscita del traffico dalla LAN # e l'ingresso del traffico relativo a connessioni aperte dall'interno. # Filtri iptables -A LAN_WAN -j ACCEPT iptables -A WAN_LAN -m state --state ESTABLISHED,RELATED -j ACCEPT