Lavorare con iptables su Ubuntu [per pinguini in erba]

Obiettivo: configurare il firewall su Ubuntu adatto ad un webserver, compresi servizi FTP e di posta, capendo come funzionano le regole ed i criteri principali

Contenuti

  1. Visualizzare lo stato del firewall (iptables)
  2. Accettare tutte le connessioni e ripristinare il firewall alla configurazione base
  3. Modificare il criterio della catena
  4. Aggiungere una nuova catena personalizzata
  5. Cambiare ordine ai filtri (anelli) sulla catena
  6. Eliminare un filtro (anello) della catena
  7. Aggiungere intervalli di porte ad iptables
  8. Bloccare un indirizzo IP
  9. Firewall su OUTPUT
  10. Configurare il firewall standard per server web con Apache, Webmin, FTP, POP3, SMTP, IMAP e SSH

 

Abbiamo già visto la configurazione base di iptables su Ubuntu, ora propongo una serie di esempi per capire in modo più approfondito come funziona.

Suggerimento: per testare la connessione possiamo usare il webserver creato con Apache e provare via via a collegarci alla porta 80, ovvero all’indirizzo del server tramite browser. Nell’esempio dell’altra volta tale indirizzo era http://192.168.56.1

Iptables è un programma che serve a gestire Netfilter, che è il vero firewall della maggior parte dei più moderni sistemi Linux. Su Wikipedia ci sono maggiori dettagli di base, per ora ne estraggo la citazione fondamentale:

Per configurare netfilter attualmente si usa il programma iptables, che permette di definire le regole per i filtri di rete e il reindirizzamento NAT. Spesso con il termine iptables ci si riferisce all’intera infrastruttura, incluso netfilter.

Iptables si basa su 3 catene principali:

  • INPUT traffico in entrata, per esempio collegarsi da fuori verso il PC in SSH oppure interrogare il server web in HTTP
  • FORWARD traffico reindirizzato, si usa solo nel caso in cui il PC effettui operazioni di routing
  • OUTPUT connessioni in uscita, per esempio operazioni di ping

E 3 criteri fondamentali:

  • ACCEPT permette
  • DROP blocca come se non esistesse
  • REJECT blocca inviando un errore

Ci sono anche altri criteri, ma per ora focalizziamoci su questi che sono essenziali per i nostri scopi.

Prima di proseguire capiamo meglio come funzionano le catene (chain). Sul firewall possono essere configurate diverse catene, che verranno visitate nell’ordine in cui sono inserite.

Immaginiamo di avere del traffico in ingresso e due catene come di seguito:

Alle catene vengono aggiunti anelli successivi, allungandole sempre di più. Un pacchetto che entra cerca di passare da un anello dove gli sia consentito, altrimenti, se non trova passaggi liberi, viene scartato. Per riuscire ad attraversare “indenne” il firewall deve visitare tutte le catene successive (devono essere referenziate, ma questo lo vedremo dopo).

Il primo anello rappresenta il criterio generale della catena, ma anche questo lo capiremo meglio dopo.

Questa è una spiegazione vagamente semplicistica, ma per il momento è sufficiente.

NOTA: E’ molto importante ricordare che mentre si apportano le modifiche ad iptables queste non saranno permanente finché non si salvano definitivamente; questo significa che se aggiungiamo dei criteri e poi riavviamo il computer, al riavvio questi non saranno più presenti. Perché diventino permanenti bisogna salvarli e vedremo come dopo.

1. Visualizzare lo stato del firewall (iptables)

Per visualizzare la configurazione del firewall è sufficiente digitare:

Nel mio caso viene visualizzato qualcosa di simile (ho già effettuato delle configurazioni):

Notiamo che nella prima chain, quella di INPUT (le prime 3 sono predefinite), c’è un comando inutile che tenta di bloccare i pacchetti dpt:http (dpt = destination port, http = 80), ovvero quelli passanti dalla porta 80 utilizzata per le connessioni web HTTP. Poche righe prima è infatti definita una regola che li fa passare attraverso la catena con ACCEPT, quindi questo DROP è inutile.

2. Accettare tutte le connessioni e ripristinare il firewall alla configurazione base

Per fare il reset del firewall è sufficiente digitare:

La -F sta per flush. Questo reimposterà tutte le catene effettuando la cancellazione di tutti gli anelli, lasciando solamente quelli in cima. Questo significa che se la regola per INPUT è ACCEPT resterà ACCEPT, se fosse stata DROP resterà DROP, senza tutte le altre regole a seguire.

Per reimpostare il primo anello della catena è necessario utilizzare:

In questo caso modifichiamo la catena predefinita degli INPUT, impostandola affinché faccia passare tutte le connessioni che non sono state definite. Il primo anello della catena, nel disegno precedente, è il criterio della catena.

Digitando il seguente comando si aprirà l’intero firewall e si cancelleranno tutti i criteri aggiuntivi.

Per non rischiare che il flush chiuda la connessione SSH possiamo concatenare i comandi con &&.

3. Modificare il criterio della catena

Immaginiamo di prendere la configurazione del firewall nel primo grafico, ma di cambiare il criterio della prima catena da DROP ad ACCEPT. Il risultato produrrà qualcosa di simile:

Quando il criterio della catena è ACCEPT significa che ogni pacchetto che non sia proibito, oppure sia esplicitamente accettato, passa, ovvero è ACCEPT di default. Se un pacchetto è DROP, al primo DROP è DROP per tutta la catena.

Per modificare il criterio di una catena, come quella di INPUT per esempio, è sufficiente digitare:

In questo caso l’intera catena è su ACCEPT come la catena1 del disegno. Se su INPUT volessimo riprodurre le medesime regole della catena precedente sarebbe sufficiente digitare, in questo ordine:

Con -A aggiungiamo un filtro (un anello) ad INPUT (o una catena scelta), -p definisce il protocollo da filtrare, per noi TCP, –dport definisce la porta di destinazione, per esempio la porta 80, -j imposta il jump, ovvero se si passa o si precipita.

NB: i protocolli accettati sono tcp, udp, udplite, icmp, esp, ah, sctp oppure all per prenderli tutti

Per visualizzare la configurazione digitiamo:

Il risultato assomiglierà al seguente:

Inutile dire come il criterio ACCEPT presupporrebbe di dover bloccare tutti i pacchetti eccetto quelli desiderati, quindi si preferisce di solito il criterio DROP, per cui sono bloccati tutti i pacchetti eccetto quello desiderati.

Il criterio ACCEPT è invece molto utile in fase di configurazione.

Immaginiamo di voler attivare il firewall solamente sulle seguenti porte: 80, 443, 20, 21, 22 (rispettivamente HTTP, HTTPS, FTP, FTP, SSH). Digitiamo in sequenza:

Interrogando iptables il risultato sarà:

4. Aggiungere una nuova catena personalizzata

Oltre alle catene predefinite, per ora abbiamo visto INPUT, OUTPUT e FORWARD, possiamo aggiungere delle ulteriori catene personalizzate.

Creiamo anzitutto la nostra nuova catena che io chiamerò Cerberus (niente di speciale nel nome, giusto per dare un tono fantasy all’esempio)

Adesso aggiungiamo, alla catena delle regole, ma prima di tutto una confessione:

ATTENZIONE! Solamente le catene predefinite possono avere dei criteri come ACCEPT, DROP, REJECT ecc., le catene personalizzate non possono averli, ma vanno collegate a quelle predefinite

Quindi sulla nostra catena personalizzata Cerberus blocchiamo la porta 80.

Assicuriamoci che la catena INPUT sia sul criterio ACCEPT e senza altri filtri. In tal caso il nostro server è ancora accessibile sulla porta 80.

Adesso colleghiamo la catena Cerberus alla catena predefinita INPUT, inserendo un jump (un salto potremmo dire)

A questo punto il server non è più accessibile dalla porta 80.

Se interroghiamo iptables per vedere le configurazioni presenti, vedremo qualcosa come questo:

Faccio notare come alla chain Cerberus è segnato un riferimento (1 references)

Per rimuovere il riferimento, e quindi riattivare la porta 80, è sufficiente eseguire:

ATTENZIONE! Bisogna tenere conto dell’ordine della catena e dove viene collegata ogni nuova catena. Immaginiamo di eseguire i seguenti comandi:

In questo modo ripristiniamo tutta la catena INPUT, impostando il criterio su ACCEPT, quindi permettiamo l’uscita dei pacchetti sulla porta 80. In questo caso, la catena Cerberus non serve a nulla.

5. Cambiare ordine ai filtri (anelli) sulla catena

Benché sia possibile eliminare i singoli filtri, non è possibile ordinarli. Esiste però un trucco, ed il seguente:

Questo creerà un file iptables.txt nella posizione nella quale ci troviamo. Apriamo e modifichiamo il file:

Quello che ci verrà mostrato è il set di tutte le regole impostate nel firewall. Nel mio caso, dopo le ultime modifiche le regole saranno:

A questo punto modifico il file invertendo tra di loro la riga 8 e la 9, ottenendo il seguente file:

A questo punto salviamo il file ed importiamolo nel firewall digitando:

Adesso controllando di nuovo la configurazione del firewall vedremo:

Adesso possiamo verificare che la porta 80 sia bloccata.

ATTENZIONE! Ricordarsi di cancellare il file iptables.txt se non si trova in un posto sicuro.

6. Eliminare un filtro (anello) della catena

Per eliminare un singolo filtro della catena è sufficiente dichiararlo al “contrario”. Se per esempio per aggiungere il suddetto filtro sulla porta 80 abbiamo digitato:

Per rimuoverlo è sufficiente digitare:

Faccio notare che l’unico parametro che cambia è la -A che diventa -D, che starebbe per delete, ovvero cancella.

La rimozione può essere anche effettuata in base al numero di riga nella catena interessata. La prima riga equivale ad 1.

Se avessi la seguente configurazione:

E volessi cancellare il filtro alla riga 2, ovvero

Mi basterebbe digitare:

Infine un modo ancora più veloce è quello illustrato al punto 5 per ordinare le regole, semplicemente rimuovendole dal file di testo e reimportandolo.

7. Aggiungere intervalli di porte ad iptables

Per aggiungere un intervallo di porte, per esempio dalla 6000 alla 6010, è sufficiente digitare:

Se si interroga iptables all’intervallo scelto si potrebbe vedere qualcosa di simile:

Nella colonna finale notiamo dpts che sta per destination ports, x11 che è il nome della porta 6000, utilizzata da X Windows System. Se la porta non avesse avuto un nome sarebbe comparso il numero.

Se volessimo invece abilitare diverse porte contemporaneamente sarebbe sufficiente digitare:

In questo caso attiviamo le porte 20, 21, 22, 80, 443 e l’intervallo delle porte comprese tra la 6000 e la 6010.

8. Bloccare un indirizzo IP

Per bloccare un indirizzo IP è sufficiente digitare:

-s sta per source (sorgente), ovvero origine della connessione.

Se volessimo bloccare un indirizzo IP ad una determinata porta potremmo digitare:

Questo blocca la porta 80 solo per l’indirizzo 10.0.2.30.

Adesso proviamo a digitare:

Questo bloccherà tutte le connessioni sulla porta 80, eccetto quelle provenienti dall’indirizzo 10.0.2.2.

9. Firewall su OUTPUT

Potremmo dire, per semplificare l’idea, che mentre le regole di INPUT si applicano al modello client ⇒ server (noi siamo il server) quelle di OUTPUT si applicano server ⇒ client. Ovvero al momento in cui il nostro server cerca di uscire verso l’esterno.

Questo avviene praticamente in tutte le connessioni, per esempio quando ci colleghiamo in SSH noi dobbiamo poter parlare da fuori al server (client ⇒ server), ma il server deve anche poterci rispondere (server ⇒ client).

Se digitassimo:

Praticamente nulla uscirebbe dal server.

Per capire meglio questa cosa proviamo a fare la seguente prova. Anzitutto assicuriamoci che l’OUTPUT non abbia filtri e sia su ACCEPT.

Proviamo a scaricare un file sul nostro server (per esempio il file zip di installazione di WordPress). Digitiamo:

Questo scaricherà nella cartella dove ci troviamo un file chiamato latest.tar.gz.

In questo momento non ci interessa tanto il file quanto il fatto che possa scaricarlo. Adesso proviamo a digitare i seguenti due comandi:

Questo aggiungerà due regole, la prima, che abbiamo già visto, per mantenere aperte le connessioni stabilite, la seconda per bloccare tutte le altre connessioni dall’interno. Questo significa che se un client interroga il server, quindi stabilisce una connessione del tipo client ⇒ server (come quando accediamo con putty al server), allora anche la relativa connessione server ⇒ client necessaria sarà permessa. Altrimenti sarà impossibile collegarsi da dentro al server verso l’esterno.

Se adesso tentiamo il comando precedente:

Incontriamo il seguente errore:

Questa connessione dovrebbe avvenire sulla porta 443 (HTTPS) quindi possiamo provare ad aprirla digitando:

Ma anche così facendo il download si blocca sulla risoluzione del dominio. Questo avviene perché il server deve potersi connettere anche in TCP e UDP al DNS sulla porta 53. Quindi è necessario abilitare anche tale filtro digitando:

A questo punto il download può avvenire.

Inutile dire che mantenere questo genere di blocco è di scarso interesse quando siamo noi i soli a gestire il server.

10. Configurare il firewall standard per server web con Apache, Webmin, FTP, POP3, SMTP, IMAP e SSH

Fatti tutti questi esperimenti scriviamo la configurazione per il nostro firewall standard, aprendo le porte per i suddetti servizi:

Il risultato dovrebbe apparire come quello seguente:

Per maggiori dettagli sull’associazione tra protocolli e fare riferimento a questa pagina di Wikipedia.

Le uniche porte non predefinite sono quelle per l’FTP passivo che ho messo, giusto per prova, dalla 6000 alla 6010. In realtà converrebbe associare un range più ampio, in base anche al numero di connessioni che si intende ricevere.

Per salvare il tutto installiamo iptables-persistent (se non lo abbiamo già fatto):

Ed infine digitiamo:

Vi ricordate che netfilter è il vero firewall di Linux e iptables “solo” un programma di gestione? Questo comando salva tutti i dati che abbiamo configurato.

Rispondi

This site uses Akismet to reduce spam. Learn how your comment data is processed.