Esempio Iptables: Server pubblico

Analizziamo la configurazione di iptables per un server pubblico, che deve rendere accessibili dei servizi, con diversi livello di accesso, e che ha un firewall locale.
In questo caso si agisce sulle catene di INPUT e di OUTPUT della tabella FILTER.

Configurazione essenziale
Vediamo un esempio essenziale di una configurazione per un server web pubblico, che deve rendere accessibili a tutto il mondo le porte 80 e 443 e deve poter essere gestito da alcuni IP privilegiati.
La configurazione prevede:
- DROP di default su tutte le catene
- Si lascia aperto il traffico in uscita dal proprio host (OUTPUT) dopo aver sanitificato i pacchetti in uscita (--state)
- Si permette in INPUT tutto il traffico di ritorno relativo a connessioni già esistenti
- Si permette il traffico sulla interfaccia di loopback
- Si permette accesso, da tutta Internet, alle porte 80 e 443
- Si permette l'accesso via SSH (porta 22/TCP) da una arbitraria rete di amministrazione (es: 213.25.10.0/24)
- Si permette l'accesso FTP (porta 21/TCP + gestione del canale dati) da un arbitrario host di un webmaster (es: 143.20.12.7)
*filter
:INPUT DROP [0:0]
:FORWARD DROP [0:0]
:OUTPUT DROP [0:0]
-A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
-A INPUT -i lo -j ACCEPT
-A INPUT -p tcp --dport 80 -j ACCEPT
-A INPUT -p tcp --dport 443 -j ACCEPT
-A INPUT -p tcp --dport 22 -s 213.25.10.0/24 -j ACCEPT
-A INPUT -p tcp --dport 21 -s 143.20.12.7 -j ACCEPT
-A OUTPUT -m state --state NEW,RELATED,ESTABLISHED -j ACCEPT
-A OUTPUT -o lo -j ACCEPT
COMMIT

Notare che per gestire correttamente il protocollo FTP è opportuno assicurarsi che venga caricato il modulo del kernel ip_conntrack_ftp. Se non viene fatto automaticamente dalla propria distribuzione, caricarlo, facendo eseguire durante la fase di boot (per esempio nel file /etc/rcd.d/rc.local) il seguente comando:
modprobe ip_conntrack_ftp

Configurazione più elaborata
Un esempio più complesso di un simile sistema può prevedere:
- Default DROP su tutte le catene
- Si permette in INPUT tutto il traffico di ritorno relativo a connessioni già esistenti
- Si permette il traffico sulla interfaccia di loopback (si interviene sia in INPUT che in OUTPUT)
- Si permette in uscita solo il traffico di risposta al traffico in entrata permesso
- Si permette l'aggiornamento del sistema (in questo esempio via http all'indirizzo arbitrario 213.215.144.242)
- Si permette l'invio della posta tramite un unico smtp relay (in questo esempio con IP 213.15.44.22)  
- Si loggano tutti i pacchetti di tipo unicast (escludendo quindi broadcast e multicast) con una syslog facility che ci permetta il logging su file separato
*filter
:INPUT DROP [0:0]
:FORWARD DROP [0:0]
:OUTPUT DROP [0:0]
-A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
-A INPUT -i lo -j ACCEPT
-A INPUT -p tcp --dport 80 -j ACCEPT
-A INPUT -p tcp --dport 443 -j ACCEPT
-A INPUT -p tcp --dport 22 -s 213.25.10.0/24 -j ACCEPT
-A INPUT -p tcp --dport 21 -s 143.20.12.7 -j ACCEPT
-A INPUT -m pkttype --pkt-type unicast -j LOG --log-prefix "INPUT DROP: " --log-level 7
-A FORWARD -m pkttype --pkt-type unicast  -j LOG --log-prefix "FORWARD DROP: " --log-level 7
-A OUTPUT -o lo -j ACCEPT
-A OUTPUT -p tcp --sport 80 -j ACCEPT
-A OUTPUT -p tcp --sport 443 -j ACCEPT
-A OUTPUT -p tcp --sport 22 -d 213.25.10.0/24 -j ACCEPT
-A OUTPUT -p tcp --sport 21 -d 143.20.12.7 -j ACCEPT
-A OUTPUT -p tcp --dport 80 -d 213.215.144.242 -j ACCEPT
-A OUTPUT -p tcp --dport 25 -d 213.15.44.42 -j ACCEPT
-A OUTPUT -m pkttype --pkt-type unicast -j LOG --log-prefix "OUTPUT DROP: " --log-level 7
COMMIT

Per visualizzare il log su file separato è necessario configurare Syslog. Editare /etc/syslog.conf (o analogo) e aggiungere una riga tipo:
kern.debug   /var/log/firewall.log.

Esempi di configurazioni particolari
Vediamo alcuni esempi che usano funzioni di iptables meno comuni e non sempre incluse nel kernel di una distribuzione.

- Aprire diverse porte con multiport
Se il nostro server deve esporre più porte può essere comodo il match multiport, che permette di definire più porte TCP o UDP in una singola regola.
Ad esempio per un server di posta completo di webmail, pop3, imap e corrispettivi SSL si può permette pubblico accesso con:
iptables -I INPUT -m multiport -p tcp --dport 25,80,110,143,443,993,995 -j ACCEPT

- Limitare rischi con tool di analisi log con owner
Spesso sul sistema vengono installati strumenti di analisi dei log, di qualsiasi tipo. Questi possono essere semplici programmi singoli o applicazioni più complesse, possono venire schedulati o eseguiti in background. Qualsiasi sia la loro natura, sono programmi che ricevono un input con il log da analizzare, che spesso contiene informazioni su attività generate dall'esterno. Log di server web, di firewall, di posta, per esempio, contengono dati che possono entro certi limiti essere manipolati direttamente da un potenziale intrusore, facendo richieste via HTTP anomale, inviando pacchetti invalidi ecc.
Spesso si sorvola sui potenziali rischi associati al parsing di log, soprattutto se questo viene fatto da programmi semplici e non particolarmente prudenti nel gestire i loro input e se magari vengono pure eseguiti con privilegi di root.
Si possono limitare gli effetti di potenziali vulnerabilità di questi strumenti anche via iptables, impedendo all'utente con cui sono eseguiti sul sistema di comunicare via rete.
Primariamente è opportuno che simili programmi vengano eseguiti con permessi non privilegiati, per cui se non già previsto , è opportuno fare in modo che tutti i log e dati che devono leggere e scrivere siano accessibili dall'utente con cui il programma gira.
Poi, si può usare il metodo di match "owner" con cui le iptables possono gestire il traffico a seconda dell'utente che lo ha generato (per logica questo match si applica solo alla catena di OUTPUT).
Ad esempio se il nostro programma di analisi dei log si chiama fwanalog e viene eseguito con utente logs, con UID 150, possiamo impedire che questo programma comunichi all'esterno (escludendo query DNS che potrebbe fare per reverse DNS lookup) con un comando tipo:
iptables -I OUTPUT -p udp --dport ! 53 -m owner --uid-owner 150 -j DROP
oppure, nei kernel dove è supportata questa estensione:
iptables -I OUTPUT -p udp --dport ! 53 -m owner --cmd-owner fwanalog -j DROP

Privacy Policy