Un sistema destinato ad essere perennemente attivo e connesso ad Internet deve essere configurato al meglio per prevenire ogni possibile problema di sicurezza (accessi indesiderati, attacchi DoS, etc). In tale ottica, particolare attenzione va rivolta alla configurazione di rete, avendo cura di assicurarsi che solo i servizi strettamente necessari siano accessibili dall'esterno. Ad esempio, un server web dovrebbe essere raggiungibile dall'esterno solo sulle porte 80 (HTTP) e 443 (HTTPS). Ogni tentativo di accesso agli altri servizi in esecuzione sulla macchina (ad esempio, SSH, FTP, etc) dovrebbe essere negato. Ovviamente l'individuazione dei servizi e la determinazione delle relative politiche di accesso varia di caso in caso.
Il componente software che determina se un determinato flusso di rete può avvenire o meno è detto firewall (ovvero il "muro di fuoco" a protezione del sistema). Il firewall monitora il traffico di rete basandosi su regole precedentemente impostate, ed in base ad esse interviene se necessario, bloccando le connessioni che non rispettano la configurazione prevista. Esso può girare su una macchina dedicata, a protezione di più sistemi ad esso connessi (firewall di rete), oppure essere parte integrante del sistema stesso (firewall di sistema).
In generale, a meno di non avere particolari esigenze in termini di latenza di rete o di tempo di processore, è buona norma attivare il firewall di sistema presente sul server, indipendentemente dalla presenza o meno di altri firewall di rete.
Iptables
Il kernel Linux dispone di un firewall integrato, implementato grazie al framework Netfilter attraverso una serie di moduli detti "tables" (ip_tables, ip6_tables, arp_tables, ecc). Il comportamento di questi moduli è controllato infatti dalle corrispondenti tabelle di configurazione, ognuna costituita da una o più "catene" di regole (chain). Essenzialmente, una catena è una lista di regole alle quali viene sottoposto il pacchetto in esame. Ogni regola è a sua volta costituita da uno o più match, che determinano se il pacchetto in oggetto debba essere o meno affetto dalla regola, e da un target, che nel caso di match della regola determina l'azione da intraprendere.
Esistono 5 chain predefinite:
PREROUTING
INPUT
FORWARD
OUTPUT
POSTROUTING
Come si evince dai nomi, esse contengono le regole da elaborare in base alla provenienza del pacchetto in esame. Ad esempio, la chain INPUT
è utilizzata per i pacchetti in ingresso.
Per gestire le regole contenute all'interno di ogni catena, esistono delle utility da riga di comando apposite. Ad esempio, la configurazione delle regole per il protocollo IPv4 avviene grazie all'utility iptables, mentre per il protocollo IPv6 esiste l'omologa ip6tables.
Per visualizzare l'elenco delle regole attualmente in uso, possiamo digitare:
# iptables -nVL
Il comando mostrerà l'elenco delle catene attive, e per ognuna di esse le relative regole.
Analogamente, le opzioni da riga di comando di iptables consentono l'aggiunta, la rimozione o la modifica delle regole di una particolare catena. Ad esempio, per impedire qualunque tentativo di connessione in ingresso proveniente dall'indirizzo IP 10.10.10.10, basterà digitare:
# iptables -A INPUT -s 10.10.10.10 -j DROP
Le opzioni da riga di comando usate nell'esempio sono:
-A
: usata per aggiungere una regola alla catena specificata (INPUT
in questo caso);-s
: che specifica che il criterio di match della regola è l'indirizzo della sorgente;-j
: usata per indicare il target (DROP
in questo caso; come si intuisce, il targetDROP
è usato per scartare il pacchetto);
Persistenza
Le modifiche alla configurazione effettuate con iptables non sono permanenti. Al riavvio della macchina, il firewall userà nuovamente le regole di default. Per memorizzare la configurazione in modo permanente è sufficiente installare il pacchetto iptables-persistent, con il comando:
# apt-get install iptables-persistent
Dopo l'installazione, per memorizzare i cambiamenti effettuati con il comando iptables è sufficiente digitare:
# iptables-persistent save
UFW
UFW (Uncomplicated FireWall, firewall semplice) è lo strumento di configurazione del firewall di default in ambiente Ubuntu. UFW è stato sviluppato proprio in casa Canonical per semplificare le operazioni più comuni di configurazione delle tabelle del firewall di Linux. Come illustrato sopra infatti, la sintassi del comando iptables è piuttosto articolata e richiede una conoscenza dettagliata del funzionamento del firewall per poter agire sulla configurazione dello stesso in modo efficace. Inoltre, la configurazione di default di UFW è più restrittiva di quella di iptables. In particolare, per default UFW impedisce qualunque connessione in ingresso. Il processo di configurazione si riduce quindi alla specifica delle sole connessioni che vogliamo accettare (ad esempio, per un server web, quelle sulle porte 80/tcp e 443/tcp).
Attivazione
UFW è preinstallato per default, ma non attivato. Per attivarlo, è sufficiente digitare il comando:
# ufw enable
Un messaggio confermerà l'avvenuta attivazione del firewall.
Stato
Digitando il comando:
# ufw status
UFW mostrerà lo stato del firewall (attivo o non attivo) e l'elenco delle regole attualmente in uso.
Aggiunta di regole
L'aggiunta di regole avviene con i comandi ufw allow
ed ufw deny
. In riferimento all'esempio riportato sopra, per negare ogni tentativo di connessione dall'indirizzo IP 10.10.10.10, basterà digitare:
# ufw deny from 10.10.10.10
Come si evince, la sintassi del comando ufw è più leggibile ed immediata di quella del comando iptables.
Apertura di una porta
Per accettare le connessioni verso una specifica porta TCP, dobbiamo usare il comando allow. Ad esempio, per accettare le connessioni sulla porta 80 TCP, digitare:
# ufw allow tcp/80
UFW confermerà l'avvenuta creazione delle regole corrispondenti. Per default, UFW creerà due regole, una per il protocollo IPv4 ed una per il protocollo IPv6. Se si desidera impostare la regola per il solo protocollo IPv4, è necessario specificare il range di indirizzi ammissibili, con il comando:
# ufw allow proto tcp to 0.0.0.0/0 port 80
Chiusura di una porta
Analogamente, è possibile negare ogni tentativo di connessione ad una specifica porta con il comando deny. Ad esempio, il comando:
# ufw deny tcp/22
bloccherà ogni tentativo di connessione alla porta 22.
Interfacce
In assenza di ulteriori parametri, le regole impostate con i comandi mostrati sopra avranno effetto su tutti i pacchetti in ingresso, indipendentemente dall'interfaccia di rete dalla quale sono stati ricevuti. In generale può rendersi necessario definire regole diverse per gli stessi protocolli in base all'interfaccia di provenienza. Ad esempio, si consideri un server con due interfacce di rete, una connessa alla rete esterna ed un'altra invece connessa direttamente ad una console di amministrazione. In uno scenario del genere si dovrebbe configurare il firewall per negare ogni accesso alla porta 22 (ssh) proveniente dalla rete esterna ma non dalla console di amministrazione.
Supponendo che l'interfaccia connessa alla rete interna sia eth1, è possibile consentire l'accessso via SSH su quell'interfaccia con il comando:
# ufw allow in on eth1 to any port 22 proto tcp
Persistenza
A differenza del comando iptables, le modifiche effettuate con il comando ufw sono persistenti e non è quindi necessario dare altri comandi per memorizzarle in via definitiva.