1 2 3 | iptables -A INPUT -j DROP iptables -A OUTPUT -j DROP iptables -A FORWARD -j DROP |
Fatto, vi siete chiusi fuori dal server e anche molti software ora non stanno più funzionando.
Voi ( e i cattivi) non potete più entrare perchè iptables è un firewall (porta tagliafuoco) e quindi sta scartando (-j DROP) tutte le richieste che arrivano al server e i software non funzionano più perchè iptables elimina anche i messaggi che passano per l’interfaccia di loopback (lo) che viene usata dai programmi per comunicare tra loro.
Iptables divide le sue regole in 3 tabelle (tables), ognuna dedicata ad un utilizzo diverso:
- nat
- mangle
- filter
Ogni tabella ha delle chains (elenchi di regole) predefinite.
Per un utilizzo minimo ci basta la tabella mangle e 3 delle sue chains:
- INPUT: dedicata hai pacchetti destinati all’host locale
- OUTPUT: per i pacchetti uscenti
- FORWARD: pacchetti destinati ad altri host
.
Naturalmente per mettere in produzione un firewall è meglio (molto meglio, essenziale) capire come funziona iptables e come i pacchetti attraversano tabelle e chains, non mi dilungo, leggetelo qui o in un qualunque altro sito dell’elenco che propone google.
Per farla breve, comunque, un pacchetto entra in una chain e si scorre l’elenco di regole contenute dalla prima all’ultima,applicandole immediatamente.
Di conseguenza un pacchetto che incontra un DROP viene scartato ed esce dalla chain.
Prima cosa da imparare: l’ordine delle regole conta.
Nel cattivo esempio di cui sopra non serve a niente aggiungere altre regole, siamo fuori e ci rimarremo.
Cancelliamo quindi le regole inserite sopra.
Abbiamo 3 sintassi possibili:
- Le regole non sono ancora persistenti, vanno esplicitamente salvate, quindi riavviare la macchina.
Questo ci manda a ramengo l’uptime, ma noi perfortuna non ne siamo schiavi. - Eliminarle tutte insieme
1
iptables -F - Cancelliamo una regola alla volta:
1 2
iptables -D {regola} iptables -D [CHAIN] [numero di riga(partendo da 1)]
iptables -D si può usare inserendo il numero di riga in cui appare la regola oppure riscrivendo la regola con la sintassi usata per aggiungerla (-A oppure -I)
Verifichiamo di esserci liberati delle regole chiedendone la lista (-L):
- una elenco semplice
1
iptables -L - più informazioni
1
iptables -L -v
- con numeri di linea (così magari usiamo con più tranquillità l’opzione -D)
1
iptables -L --line-numbers
A questo punto possiamo prendere il tablet (non un iPad per favore) su cui abbiamo segnato i servizi offerti e le porte che usano per iniziare ad appendere le regole.
Per semplicità userò negli esempi solo le chain INPUT e OUTPUT.
La nostra priorità è di consentire tutto il traffico sull’interfaccia di loopback (lo), quindi:
1 2 | iptables -A INPUT -i lo -j ACCEPT iptables -A OUTPUT -i lo -j ACCEPT |
spiegazione:
iptables, appendi (-A) alla chain INPUT la regola che tutti i pacchetti che passano per l’interfaccia (-i lo) sono accettati (-j ACCEPT)
Al primo posto dei servizi permessi c’è sicuramente ssh quindi vogliamo che siano possibili connessioni entranti e uscenti sulla porta 22 (default).
1 | iptables -A INPUT --dport 22 -j ACCEPT |
Questa regola dice ad iptables di accettare le connessioni entranti dirette alla porta 22.
Questa regola base può (e deve) essere migliorata con ulteriori vincoli:
- accettare solo uno specifico protocollo, nel caso specifico tcp
1
-p tcp - verificare lo stato della connessione. Nel caso di connessioni entranti dobbiamo accettare sia comunicazioni nuove che già attive (NEW ed ESTABLISHED)
1
-m state --state NEW,ESTABLISHED
attenzione, non di devono essere spazi intorno alla virgola.
- potremmo poi voler accettare solo le connessioni dirette ad un solo IP
1
-d [indirizzo ip]
- oppure consentire l’accesso solo ad uno specifico IP/rete
1
-s [indirizzo ip]/[netmask]
per lasciare libera la connessione si può non specificare nulla oppure usare
1
-s 0/0
- eventualmente si può anche specificare da che porta deve partire la connessione affinchè sia accettata
1
--sport [numero di porta]
per consentire un intervallo
1 2 3
--sport [porta partenza]:[porta base] es. --sport 1024:65535
Una regola ragionevolmente restrittiva da cui partire diventa quindi:
1 | iptables -A INPUT -p tcp --dport 22 -m state --state NEW,ESTABLISHED -j ACCEPT |
Siccome dopo diremo al firewall di scartare tutti i pacchetti entranti e uscenti che non siano altrimenti regolati dobbiamo anche dire ad iptables cosa fare delle risposte che richiede il client ssh:
1 | iptables -A OUTPUT -p tcp -m state --state ESTABLISHED -j ACCEPT |
La sintassi è identica, cambia solo la chain a cui appenderlo e non sono specificate le porte della connessione.
A questo punto non rimane che reiterare la logica applicata per ssh per ogni servizio a cui vogliamo consentire l’accesso.
Finito l’elenco dei servizi blocchiamo tutto di nuovo:
1 2 3 | iptables -A INPUT -j DROP iptables -A OUTPUT -j DROP iptables -A FORWARD -j DROP |
A questo punto un port scanner tipo nmap vi segnalerà solo la porta ssh disponibile e l’output di iptables -L dovrebbe essere:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | Chain INPUT (policy ACCEPT) target prot opt source destination ACCEPT all -- anywhere anywhere ACCEPT tcp -- anywhere anywhere tcp dpt:ssh state NEW,ESTABLISHED DROP all -- anywhere anywhere Chain FORWARD (policy ACCEPT) target prot opt source destination DROP all -- anywhere anywhere Chain OUTPUT (policy ACCEPT) target prot opt source destination ACCEPT all -- anywhere anywhere ACCEPT tcp -- anywhere anywhere tcp spt:ssh dpts:login:65535 state ESTABLISHED DROP all -- anywhere anywhere |
Il parametro -A appende una regola in fondo alla chain selezionata, volendo inserire una regola in una posizione specifica si usa:
1 | iptables -I INPUT 3 {regola} |
Che ci consente di appendere {regola} alla terza posizione della chain (sempre partendo da 1).
Lavorando con i firewall è purtroppo molto facile fare errori che poi richiedono di loggarsi in locale sulla macchina per essere riparati.
Siccome più spesso che no il server è a qualche chilometro dalla tastiera su cui stiamo lavorando la seconda semplice precauzione da prendere è di spegnere il firewall ogni 5 minuti
1 2 3 4 | crontab -e */5 * * * * /sbin/service iptables stop (centos) */5 * * * * /etc/init.d/iptables stop (debian-like) */5 * * * * /sbin/iptables -F (per tutte le stagioni) |
Ovviamente la prima precauzione da prendere è provare la configurazione sul server di test.
Riassunto dei comandi
- visualizzare le regole
1
iptables -L -v --line-number
- eliminare tutte le regole
1
iptables -F - eliminare una regola
1 2
iptables -D [chain] [numero regola] iptables -D [chain] {sintassi regola}
- appendere una] regola in fondo alla chain
1 2 3
iptables -A [chain] {sintassi regola} es. iptables -A INPUT -p tcp --dport 22 -m state --state NEW,ESTABLISHED -j ACCEPT (per ssh)
- appendere una regola in posizione specifica
1
iptables -I [chain] [numero riga] {sintassi regola}
Iptables ha molti più parametri di così.
Per un firewall sicuro ci vuole molto più studio di questo semplice tutorial, si possono creare nuove chains e modificare i pacchetti prima del routing e dopo il routing; genericamente si può gestire ogni aspetto dei flussi entranti e uscenti.
0 Responses
Stay in touch with the conversation, subscribe to the RSS feed for comments on this post.