IPTables


Nelle ultime settimane ho passato il tempo a studiare vari
howTo molto ben curati sulla costruzione delle catene di regole
per il filtraggio dei pacchetti su linux.

Linux possiede iptables che è un paccehtto per filtrare
le richieste verso un dato indirizzo IP.
Poniamo dei paletti per cominciare:

Abbiamo un server collegato staticamente ad internet con un’IP
fisso.
Il nostro server ha una sola scheda di rete, offre i servizi di
POP3, SMTP, FTP e WWW.
Vogliamo fare in modo che il nostro server risponda a quei soli
servizi indicati.

A questo punto dobbiamo impostare un firewall locale per le richieste
che vengono effettuate verso la scheda di rete del nostro server.

IPTables organizza le proprie regole in 3 catene principali:

INPUT (tutte le richieste in entrata)
OUTPUT (tutte le richieste in uscita)
FORWARD (le richieste che dovrebbero essere inoltrate verso un’altra
scheda di rete)

E’ tuttavia è possibile creare delle catene proprie in modo
da poter tenere logicamente ordinato il proprio FW.

IPTables quando riceve una richieste la fa passare attraverso la
catena di input finchè non incontra un "match",
cioè una regola che soddisfa il pacchetto in ingresso (o
in uscita).
Supponiamo di impostare la catena di input nel seguente modo:

INPUT
Regola1 -ACCEPT
Regola2 -ACCEPT



RegolaN -REJECT
Regola finale -DROP

Il nostro pacchetto cercherà di passare attraverso la catena
partendo dall’alto, se soddisferà la regola 1 allora il pacchetto
viene accettato, altrimenti viene spedito alla regola 2 che lo processa
e decide se soddisfa le condizioni. Nel caso in cui soddisfi la
regola N allora il pacchetto verà rifiutato (ovviamente è
arbitrario, io ho impostato queste regole come esempio) se infine
non soddisfa nessuna regola l’ultima di esse è bene che sia
un DROP, cioè un rifiuto.

Ora però è meglio passare al pratico, io consiglio
sempre di utilizzare i comandi shell perchè si ha molto più
controllo della situazione anche se è molto piu facile sbagliare.
Ovviamente è possibile utilizzare tool come WebMin
ma io li trovo poco chiari e dispersivi.

Cominciamo dalle regole base per una buona sicurezza. Siamo pessimisti
e supponiamo sempre che il pacchetto in ingresso sulla nosra scheda
sia da "droppare":

iptables INPUT -P DROP
iptables OUTPUT -P DROP

In questo modo l’utlima regola, è un drop cioè
il pacchetto non ha soddisfatto nessuna delle regola indicate.

E’ consigliabile filtrare anche i pacchetti del protocollo
ICMP, essi sono molto importanti per il controllo della rete ed
in generale non dovrebbero essere bloccati, ma alcuni di essi come
il ping ad esempio potrebbero permettere ad un computer remoto di
effettuare un ping attack, utilizzando il vostro server come amplificatore.
I principali ICMP sono:

0: echo reply: ping
3: destination unreachable: traffico UDP/TCP
5: redirect: instradamento dei pacchetti
8: echo-request: ping
11: time-exceeded: traceroute

ad esempio per disabilitare il solo ping basta droppare
il traffico ICMP sulle porte 0 e 8

Ora possiamo passare a controllare se il pacchetto
è pericoloso oppure no. Ho trovato delle regole che identificano
una serie di pacchetti pericolosi che non dovrebbero entrare nel
nostro server:
Nuove sessioni non Sincronizzate, cioè quelle che non hanno
flag SYN/RST,ACK,SYN
Sessioni non valide, con flag INVALID
Port Scanning, sessioni con flag FIN,SYN,RST,PSH,ACK,URG/FIN,PSH,URG
Syn Flood, flag SYN/RST oppure SYN/FIN
NetBus, richieste sulle porte 12345:12346
SubSeven, richieste sulla porta asp

Dopo aver individuato i pacchetti pericolosi possiamo
passare ad accettare soltanto i servizi che ci interessano. Consiglio
di dare un’occhiata al file /etc/services che contiene tutte le
porte e la descrizione dei servizi associati, ad esempio per abilitare
le connessioni TCP per il servizio FTP basta abilitare la porta
21 e la porta 20 per i dati.

Per rendere più chiara la visualizzazione delle nostre catene
di filtraggio possiamo organizzarle in più catene, non usando
cioè quelle standard del sistema operativo.
Descrivo brevemente il comando iptables:

iptables -F [catena]: esegue un flush di tutte le
catene o della catena specificata
iptables -N catena: crea una nuova catena definita dall’utente
iptables -X [catena]: cancella tutte le catene definite dall’utente
o cancella la sola catena specificata
iptables -P [catena] DROP/ACCEPT/REJECT/DENY: imposta la regola
di default per la catena specificata
iptables -D catena num.regola: cancella la regola numero dalla catena
specificata
iptables -I catena posizione regola: inserisce la regola nella catena
alla posizione specificata spostando le rimanenti in basso
iptables -A catena regola: appende la regola alla catena specificata

Prima di tutto impostiamo le regole per i pacchetti
ICMP, creiamo una catena chiamata "icmp_in":

iptables -N icmp_in

Impostiamo le regole della catena:

iptables -A icmp_in -i eth0 -p icmp -m
icmp –icmp-type 3 -j ACCEPT
iptables -A icmp_in -i eth0 -p icmp -m icmp –icmp-type 5 -j ACCEPT

iptables -A icmp_in -i eth0 -p icmp -m icmp –icmp-type 11 -j ACCEPT

iptables -A icmp_in -p icmp -j LOG –log-prefix "ICMP drop:"

iptables -A icmp_in -p icmp -j DROP

il parametro -j indica cosa fare le pacchetto quando
soddisfa le condizioni della regola quindi se il pacchetto icmp
non è un ping allora lo accetta altrimenti passa alla penultima
regola che indica al server di scriver in syslog una traccia del
pacchetto con il prefisso "ICMP drop:", questo ci permette
di visualizzare eventuali ping effettuati verso il nostro server.

Impostiamo il nostro firewall in modo tale che tutti
i pacchetti in ingresso di tipo icmp attraversione la catena chiamata
icmp_in:

iptables -A INPUT -i eth0 -p icmp -j
icmp_in

Il parametro -i eth0 invece specifica l’interfaccia
su cui passa il pacchetto, sia in ingresso che in uscita, con -j
icmp_in indichiamo invece di far attraversare il pacchetto attraverso
la catena icmp_in precedentemente creata.

In ogni momento possiamo visualizzare tutta la configurazione
del nostro firewall con il comando:

iptables -L

Filtro dei pacchetti pericolosi nella catena "bad_tcp":

iptbles -N bad_tcp

iptables -A bad_tcp -p tcp -m tcp
! –tcp-flags SYN,RST,ACK SYN -m state –state NEW -j LOG –log-prefix
"Nuova non syn:"
iptables -A bad_tcp -p tcp -m tcp ! –tcp-flags SYN,RST,ACK SYN
-m state –state NEW -j DROP
iptables -A bad_tcp -p tcp -m state –state INVALID -j LOG –log-prefix
"Invalida:"
iptables -A bad_tcp -p tcp -m state –state INVALID -j DROP
iptables -A bad_tcp -p tcp -m tcp –tcp-flags FIN,SYN,RST,PSH,ACK,URG
FIN,PSH,URG -m limit –limit 5/min -j LOG –log-prefix "NMAP-XMAS:"

iptables -A bad_tcp -p tcp -m tcp –tcp-flags FIN,SYN,RST,PSH,ACK,URG
FIN,PSH,URG -j DROP
iptables -A bad_tcp -p tcp -m tcp –tcp-flags SYN,RST SYN,RST -m
limit –limit 5/min -j LOG –log-prefix "SYN/RST:"
iptables -A bad_tcp -p tcp -m tcp –tcp-flags SYN,RST SYN,RST -j
DROP
iptables -A bad_tcp -p tcp -m tcp –tcp-flags FIN,SYN FIN,SYN -m
limit –limit 5/min -j LOG –log-prefix "SYN/FIN:"
iptables -A bad_tcp -p tcp -m tcp –tcp-flags FIN,SYN FIN,SYN -j
DROP
iptables -A bad_tcp -p tcp -m tcp –dport 137:139 -m limit –limit
5/min -j LOG –log-prefix "NO SMB:"
iptables -A bad_tcp -p tcp -m tcp –sport 137:139 -m limit –limit
5/min -j LOG –log-prefix "NO SMB:"
iptables -A bad_tcp -p tcp -m tcp –dport 137:139 -j DROP
iptables -A bad_tcp -p tcp -m tcp –sport 137:139 -j DROP
iptables -A bad_tcp -p tcp -m tcp –dport 2049 -m limit –limit
5/min -j LOG –log-prefix "NO NFS:"
iptables -A bad_tcp -p tcp -m tcp –sport 2049 -m limit –limit
5/min -j LOG –log-prefix "NO NFS:"
iptables -A bad_tcp -p tcp -m tcp –dport 2049 -j DROP
iptables -A bad_tcp -p tcp -m tcp –sport 2049 -j DROP
iptables -A bad_tcp -p tcp -m tcp –dport 6000:6063 -m limit –limit
5/min -j LOG –log-prefix "NO X:"
iptables -A bad_tcp -p tcp -m tcp –sport 6000:6063 -m limit –limit
5/min -j LOG –log-prefix "NO X:"
iptables -A bad_tcp -p tcp -m tcp –dport 6000:6063 -j DROP
iptables -A bad_tcp -p tcp -m tcp –sport 6000:6063 -j DROP
iptables -A bad_tcp -p tcp -m tcp –dport 20034 -m limit –limit
5/min -j LOG –log-prefix "NO NetBus2:"
iptables -A bad_tcp -p tcp -m tcp –sport 20034 -m limit –limit
5/min -j LOG –log-prefix "NO NetBus2:"
iptables -A bad_tcp -p tcp -m tcp –dport 20034 -j DROP
iptables -A bad_tcp -p tcp -m tcp –sport 20034 -j DROP
iptables -A bad_tcp -p tcp -m tcp –dport 12345:12346 -m limit –limit
5/min -j LOG –log-prefix "NO NetBus:"
iptables -A bad_tcp -p tcp -m tcp –sport 12345:12346 -m limit –limit
5/min -j LOG –log-prefix "NO NetBus:"
iptables -A bad_tcp -p tcp -m tcp –dport 12345:12346 -j DROP
iptables -A bad_tcp -p tcp -m tcp –sport 12345:12346 -j DROP
iptables -A bad_tcp -p tcp -m tcp –dport 27374 -m limit –limit
5/min -j LOG –log-prefix "NO SubSeven:"
iptables -A bad_tcp -p tcp -m tcp –sport 27374 -m limit –limit
5/min -j LOG –log-prefix "NO SubSeven:"
iptables -A bad_tcp -p tcp -m tcp –dport 27374 -j DROP
iptables -A bad_tcp -p tcp -m tcp –sport 27374 -j DROP

Questa catena è molto importante per individuare
e loggare quei pacchetti che arrivano e potrebbero essere maligni.
Nella maggior parte di questa catena vengono controllati flag pacchetot
sopratutto quelli per i SYN.

Possiamo adesso Aggiungere alla catena INPUT il controllo
dei pacchetti TCP:

iptables -A INPUT -i eth0 -p tcp -j bad_tcp

Adesso impostiamo una catena chimata ok_tcp che permetterà
l’accesso ai servizi detti all’inizio, cioè FTP, POP3, SMTP,
WWW

iptables -N ok_tcp

iptables -A ok_tcp -d 151.39.245.14 -p
tcp -m tcp –dport 20 -j ACCEPT
iptables -A ok_tcp -d 151.39.245.14 -p tcp -m tcp –dport 21 -j
ACCEPT
iptables -A ok_tcp -d 151.39.245.14 -p tcp -m tcp –dport 25 -j
ACCEPT
iptables -A ok_tcp -d 151.39.245.14 -p tcp -m tcp –dport 80 -j
ACCEPT
iptables -A ok_tcp -d 151.39.245.14 -p tcp -m tcp –dport 110 -j
ACCEPT
iptables -A ok_tcp -s 151.39.245.14 -p tcp -m tcp –sport 20 -j
ACCEPT
iptables -A ok_tcp -s 151.39.245.14 -p tcp -m tcp –sport 21 -j
ACCEPT
iptables -A ok_tcp -s 151.39.245.14 -p tcp -m tcp –sport 25 -j
ACCEPT
iptables -A ok_tcp -s 151.39.245.14 -p tcp -m tcp –sport 80 -j
ACCEPT
iptables -A ok_tcp -s 151.39.245.14 -p tcp -m tcp –sport 110 -j
ACCEPT
iptables -A ok_tcp -p tcp -m tcp –tcp-flags SYN,RST,ACK SYN -j
ACCEPT
iptables -A ok_tcp -p tcp -m state –state RELATED,ESTABLISHED -j
ACCEPT
iptables -A ok_tcp -i eth0 -p tcp -j LOG –log-prefix "ok_tcp
drop:"
iptables -A ok_tcp -p tcp -j DROP

l’indirizzo ip specificato sarà quello della
nostra scheda di rete o indirizzo pubblico assegnatoci. il parametro
–dport indica la porta di destinazione, quindi l’istruzione contenente
–dport 80 -j accept abilita tutte le richieste fatte all”indirizzo
ip specificato con porta 80, il parametro –sport indica la porta
di partenza.
Ho specificato 2 regole che permettono alle nuove connessioni ed
alle connessioni ormai stabilite di passare indipendentemente dalla
porta a cui si riferiscono.
Come ultima regola ho impostato un log ed un drop in modo da poter
sempre visualizzare una connessione che magari non doveva essere
droppata od una connessione non valida.
Dobbiamo adesso creare le stesse regole per il protocollo UDP in
una catena che chiamaremo ok_udp

iptables -N ok_udp

iptables -A ok_udp -d 151.39.245.14 -p
udp -m udp –dport 20 -j ACCEPT
iptables -A ok_udp -d 151.39.245.14 -p udp -m udp –dport 21 -j
ACCEPT
iptables -A ok_udp -d 151.39.245.14 -p udp -m udp –dport 25 -j
ACCEPT
iptables -A ok_udp -d 151.39.245.14 -p udp -m udp –dport 80 -j
ACCEPT
iptables -A ok_udp -d 151.39.245.14 -p udp -m udp –dport 110 -j
ACCEPT
iptables -A ok_udp -d 151.39.245.14 -p udp -m udp –dport 53 -j
ACCEPT
iptables -A ok_udp -s 151.39.245.14 -p udp -m udp –sport 53 -j
ACCEPT
iptables -A ok_udp -s 151.39.245.14 -p udp -m udp –sport 20 -j
ACCEPT
iptables -A ok_udp -s 151.39.245.14 -p udp -m udp –sport 21 -j
ACCEPT
iptables -A ok_udp -s 151.39.245.14 -p udp -m udp –sport 25 -j
ACCEPT
iptables -A ok_udp -s 151.39.245.14 -p udp -m udp –sport 80 -j
ACCEPT
iptables -A ok_udp -s 151.39.245.14 -p udp -m udp –sport 110 -j
ACCEPT
iptables -A ok_udp -p udp -m udp –udp-flags SYN,RST,ACK SYN -j
ACCEPT
iptables -A ok_udp -p udp -m state –state RELATED,ESTABLISHED -j
ACCEPT
iptables -A ok_udp -i eth0 -p udp -j LOG –log-prefix "ok_udp
drop:"
iptables -A ok_udp -p udp -j DROP

Nella catena UDP dobbiamo ricordarci anche delle chiamate per la
risoluzione dei nomi dei domini sulla porta 53.
Ora possiamo collegare alla catena INPUT le due catene personalizzate
per TCP ed UDP per i rispettivi protocolli:

iptables -A INPUT -i eth0 -p tcp -j ok_tcp
iptables -A INPUT -i eth0 -p udp -j ok_udp

Giusto per sicurezza imposto una regola di log finale ed una regola
di drop come ultima risorsa:

iptables -A INPUT -i eth0 -j LOG –log-prefix "Default
drop:"
iptables -A INPUT -i eth0 -j DROP

E questo è quanto, il nostro firewall è completamente
funzionante.

IPTables ultima modifica: 2003-01-20T00:00:00+00:00 da Enrico

Related Posts

2 Comments.

  1. Ho come l’impressione che questa regola:
    iptables -A ok_tcp -p tcp -m tcp –tcp-flags SYN,RST,ACK SYN -j ACCEPT
    ti apre tutto in entrata su tcp…

  2. “ad esempio per disabilitare il solo ping basta droppare
    il traffico ICMP sulle porte 0 e 8”

    magari sbaglio io, ma forse hai confuso 0 e 8 con i codici degli icmp types. che corrispondono infatti a echo reply e echo request. che solitamente si usano per bloccare il ping.
    non credo siano porte.
    spero di non aver detto una stupidaggine.