Impostare un firewall con uno script iptables: differenze tra le versioni
(2 versioni intermedie di uno stesso utente non sono mostrate) | |||
Riga 417: | Riga 417: | ||
Quindi salviamo l'attuale configurazione di ipset: | Quindi salviamo l'attuale configurazione di ipset: | ||
<pre> | <pre> | ||
# ipset save > /etc/ipset-blacklist/ip-blacklist.restore | |||
</pre> | </pre> | ||
Modifichiamo il file di configurazione adattandolo alle nostre necessità: | Modifichiamo il file di configurazione adattandolo alle nostre necessità: | ||
Riga 439: | Riga 440: | ||
pre-up ipset restore -! < /etc/ipset-blacklist/ip-blacklist.restore | pre-up ipset restore -! < /etc/ipset-blacklist/ip-blacklist.restore | ||
</pre> | </pre> | ||
alla sezione della scheda di rete principale nel file <tt>/etc/network/interfaces</tt>. | alla sezione della scheda di rete principale nel file <tt>/etc/network/interfaces</tt>, stando attenti a inserirla '''''prima''''' della direttiva <tt>pre up</tt> impostata in precedenza per l'avvio dello script di iptables. | ||
<br/> | <br/> |
Versione attuale delle 13:26, 22 feb 2018
Versioni Compatibili Tutte le versioni supportate di Debian |
Introduzione
Questa guida non vuole essere il solito howto dove si spiega che in iptables
ci sono le catene, le policy di default, quali sono e come funzionano, ma vuole essere un promemoria per ricordare velocemente come configurare un firewall per linux con le seguenti caratteristiche:
- policy di default: drop di tutti i pacchetti
- permettere solo ai servizi che ci interessano di essere accessibili dall’esterno
- permettere a certi servizi di essere accessibili solo dalla LAN
Lo script
Creiamo quindi un nuovo file:
# nano /etc/iptables-firewall.sh
e diamogli questo contenuto, che sarà analizzato nel paragrafo successivo:
#!/bin/sh ########################### # Imposto alcune variabili ########################### # Il path di iptables IPT="/sbin/iptables" # Interfaccia di rete esterna IFACE=bond0 ######################## # Un messaggio di avvio ######################## echo -n " Loading iptables rules..." ##################################### # Pulisco la configurazione corrente ##################################### # Cancellazione delle regole presenti nelle chains $IPT -F $IPT -F -t nat # Eliminazione delle chains non standard vuote $IPT -X # Inizializzazione dei contatori (utile per il debugging) $IPT -Z ################################################### # Blocco tutto il traffico tranne quello in uscita. # NOTA: per ragioni di sicurezza sarebbe opportuno # bloccare anche il traffico in uscita e stabilire # poi delle regole selettive ################################################### $IPT -P INPUT DROP $IPT -P FORWARD DROP $IPT -P OUTPUT ACCEPT ############################## # Abilito il traffico locale ############################## $IPT -A INPUT -i lo -j ACCEPT $IPT -A OUTPUT -o lo -j ACCEPT ##################################################### # Imposto alcune regole per i pacchetti ICMP di ping ##################################################### $IPT -A INPUT -p icmp --icmp-type echo-reply -m state --state ESTABLISHED,RELATED -j ACCEPT $IPT -A INPUT -p icmp --icmp-type echo-request -m limit --limit 5/s -m state --state NEW -j ACCEPT $IPT -A INPUT -p icmp --icmp-type destination-unreachable -m state --state NEW -j ACCEPT $IPT -A INPUT -p icmp --icmp-type time-exceeded -m state --state NEW -j ACCEPT $IPT -A INPUT -p icmp --icmp-type timestamp-request -m state --state NEW -j ACCEPT $IPT -A INPUT -p icmp --icmp-type timestamp-reply -m state --state ESTABLISHED,RELATED -j ACCEPT $IPT -A INPUT -p icmp -m icmp --icmp-type 8 -j ACCEPT $IPT -A OUTPUT -p icmp -m icmp --icmp-type 8 -j ACCEPT ############################################### # Mi difendo dallo spoofing ############################################### $IPT -A INPUT -s 10.0.0.0/8 -j DROP $IPT -A INPUT -s 169.254.0.0/16 -j DROP $IPT -A INPUT -s 172.16.0.0/12 -j DROP $IPT -A INPUT -s 127.0.0.0/8 -j DROP $IPT -A INPUT -s 192.168.0.0/24 -j DROP $IPT -A INPUT -s 192.168.1.0/24 -j DROP $IPT -A INPUT -s 192.168.10.0/24 -j DROP $IPT -A INPUT -s 224.0.0.0/4 -j DROP $IPT -A INPUT -d 224.0.0.0/4 -j DROP $IPT -A INPUT -s 240.0.0.0/5 -j DROP $IPT -A INPUT -d 240.0.0.0/5 -j DROP $IPT -A INPUT -s 0.0.0.0/8 -j DROP $IPT -A INPUT -d 0.0.0.0/8 -j DROP $IPT -A INPUT -d 239.255.255.0/24 -j DROP $IPT -A INPUT -d 255.255.255.255 -j DROP ######################################## # Mi proteggo da attacchi SMURF ######################################## $IPT -A INPUT -p icmp -m icmp --icmp-type address-mask-request -j DROP $IPT -A INPUT -p icmp -m icmp --icmp-type timestamp-request -j DROP $IPT -A INPUT -p icmp -m icmp -m limit --limit 1/second -j ACCEPT $IPT -A INPUT -p tcp -m tcp --tcp-flags RST RST -m limit --limit 2/second --limit-burst 2 -j ACCEPT ##################################### # Elimino pacchetti non validi ##################################### $IPT -A INPUT -m state --state INVALID -j DROP $IPT -A FORWARD -m state --state INVALID -j DROP $IPT -A OUTPUT -m state --state INVALID -j DROP ############################################## # Impedisco i port scan e loggo i tentativi # Gli IP sono bloccati per 24 ore ############################################## $IPT -A INPUT -m recent --name portscan --rcheck --seconds 86400 -j DROP $IPT -A FORWARD -m recent --name portscan --rcheck --seconds 86400 -j DROP $IPT -A INPUT -p tcp -m tcp --dport 139 -m recent --name portscan --set -j LOG --log-prefix "portscan:" $IPT -A INPUT -p tcp -m tcp --dport 139 -m recent --name portscan --set -j DROP ############################################### # Blocco le nuove connessioni senza SYN e # mi proteggo dagli attacchi Denial of Service ############################################### $IPT -N syn-flood $IPT -A INPUT -i $IFACE -p tcp --syn -j syn-flood $IPT -A syn-flood -m limit --limit 1/s --limit-burst 4 -j RETURN $IPT -A syn-flood -j DROP $IPT -A INPUT -p tcp ! --syn -m state --state NEW -j DROP ######################################################### # Consento il traffico delle connessioni gia' stabilite ######################################################### $IPT -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT ######################################################### # Regole sulle porte. Da modificare secondo le esigenze # Per ogni regola nel commento viene indicato: # 1) il numero della porta # 2) il nome del servizio # 3) il protocollo # 4) il livello di accesso # - pubblico = accesso permesso a tutti # - LAN = accesso permesso solo ai client della LAN ######################################################### # 21 - ProFTPD - FTP - pubblico $IPT -A INPUT -p tcp --dport 21 -m state --state NEW -j ACCEPT # Abilito le porte dinamiche. Configurare correttamente la # direttiva PassivePorts in /etc/proftpd/proftpd.conf $IPT -A INPUT -m state --state NEW -m tcp -p tcp --dport 60000:65000 -j ACCEPT # 25 - Postfix - SMTP - pubblico $IPT -A INPUT -p tcp --dport 25 -m state --state NEW -j ACCEPT # 80/443 - Apache - HTTP - pubblico $IPT -A INPUT -p tcp --dport 80 -m state --state NEW -j ACCEPT $IPT -A INPUT -p tcp --dport 443 -m state --state NEW -j ACCEPT # 110 - Dovecot - POP3 - pubblico $IPT -A INPUT -p tcp --dport 110 -m state --state NEW -j ACCEPT # 111 - Ulogd - Syslog Server - LAN $IPT -A INPUT -p tcp --dport 111 -m state --state NEW -s 192.168.90.0/24 -j ACCEPT $IPT -A INPUT -p tcp --dport 111 -m state --state NEW -s 10.0.0.0/24 -j ACCEPT $IPT -A INPUT -p udp --dport 111 -m state --state NEW -s 192.168.90.0/24 -j ACCEPT $IPT -A INPUT -p udp --dport 111 -m state --state NEW -s 10.0.0.0/24 -j ACCEPT # 143 - Dovecot - IMAP - pubblico $IPT -A INPUT -p tcp --dport 143 -m state --state NEW -j ACCEPT # 667 - Darkstat - Statistiche - LAN $IPT -A INPUT -p tcp --dport 667 -m state --state NEW -s 192.168.90.0/24 -j ACCEPT $IPT -A INPUT -p tcp --dport 667 -m state --state NEW -s 10.0.0.0/24 -j ACCEPT # 993 - Dovecot - IMAPs - pubblico $IPT -A INPUT -p tcp --dport 993 -m state --state NEW -j ACCEPT # 995 - Dovecot - POP3s - pubblico $IPT -A INPUT -p tcp --dport 995 -m state --state NEW -j ACCEPT # 1050/1051 - Zabbix - Monitor - LAN $IPT -A INPUT -p tcp --dport 1050 -m state --state NEW -s 192.168.90.0/24 -j ACCEPT $IPT -A INPUT -p tcp --dport 1050 -m state --state NEW -s 10.0.0.0/24 -j ACCEPT $IPT -A INPUT -p tcp --dport 1051 -m state --state NEW -s 192.168.90.0/24 -j ACCEPT $IPT -A INPUT -p tcp --dport 1051 -m state --state NEW -s 10.0.0.0/24 -j ACCEPT # 1194 - OpenVPN - pubblico $IPT -A INPUT -p tcp --dport 1194 -m state --state NEW -j ACCEPT echo 1 > /proc/sys/net/ipv4/ip_forward # 2000 - Sieve - Spam filter - localhost # Non ha bisogno di configurazione # 2293 - OpenSSH - SSH - pubblico $IPT -A INPUT -p tcp --dport 2293 -m state --state NEW -j ACCEPT # 2605 - BitMeter - Monitor - LAN $IPT -A INPUT -p tcp --dport 2605 -m state --state NEW -s 192.168.90.0/24 -j ACCEPT $IPT -A INPUT -p tcp --dport 2605 -m state --state NEW -s 10.0.0.0/24 -j ACCEPT # 2812 - Monit - Monitor - LAN $IPT -A INPUT -p tcp --dport 2812 -m state --state NEW -s 10.0.0.0/24 -j ACCEPT # 3000 - ntop - Monitor - LAN $IPT -A INPUT -p tcp --dport 3000 -m state --state NEW -s 10.0.0.0/24 -j ACCEPT # 3306 - MySQL - localhost # Non ha bisogno di configurazione # 10000 Webmin - Monitor - LAN $IPT -A INPUT -p tcp --dport 10000 -m state --state NEW -s 192.168.90.0/24 -j ACCEPT $IPT -A INPUT -p tcp --dport 10000 -m state --state NEW -s 10.0.0.0/24 -j ACCEPT # 10024/10025 - Amavis - localhost # Non ha bisogno di configurazione # 8980 - OpenNMS - Server Monitor - LAN $IPT -A INPUT -p tcp --dport 8980 -m state --state NEW -s 10.0.0.0/24 -j ACCEPT $IPT -A INPUT -p udp --dport 8980 -m state --state NEW -s 10.0.0.0/24 -j ACCEPT # 9000 - 9200 - 9300 - 8514 - GrayLOG - LOG Monitor - LAN $IPT -A INPUT -p tcp --dport 9000 -m state --state NEW -s 10.0.0.0/24 -j ACCEPT $IPT -A INPUT -p tcp --dport 9200 -m state --state NEW -s 10.0.0.0/24 -j ACCEPT $IPT -A INPUT -p tcp --dport 9300 -m state --state NEW -s 10.0.0.0/24 -j ACCEPT $IPT -A INPUT -p tcp --dport 8514 -m state --state NEW -s 10.0.0.0/24 -j ACCEPT $IPT -A INPUT -p udp --dport 9000 -m state --state NEW -s 10.0.0.0/24 -j ACCEPT $IPT -A INPUT -p udp --dport 9200 -m state --state NEW -s 10.0.0.0/24 -j ACCEPT $IPT -A INPUT -p udp --dport 9300 -m state --state NEW -s 10.0.0.0/24 -j ACCEPT $IPT -A INPUT -p udp --dport 8514 -m state --state NEW -s 10.0.0.0/24 -j ACCEPT # 5353 mDNS - LAN $IPT -A INPUT -p udp -m udp --dport 5353 --sport 5353 -m state --state NEW -s 10.0.0.0/24 -j ACCEPT # 67-68 DHCP - LAN $IPT -A INPUT -p udp -m udp --dport 67 --sport 68 -m state --state NEW -s 10.0.0.0/24 -j ACCEPT # 4200 - Shell in a Box - LAN $IPT -A INPUT -p tcp --dport 4200 -m state --state NEW -s 10.0.0.0/24 -j ACCEPT $IPT -A INPUT -p udp --dport 4200 -m state --state NEW -s 10.0.0.0/24 -j ACCEPT # 173 - 138 - 139 - 445 - 389 - 901 - Samba - LAN $IPT -A INPUT -p tcp --dport 137 -m state --state NEW -s 10.0.0.0/24 -j ACCEPT $IPT -A INPUT -p udp --dport 137 -m state --state NEW -s 10.0.0.0/24 -j ACCEPT $IPT -A INPUT -p tcp --dport 138 -m state --state NEW -s 10.0.0.0/24 -j ACCEPT $IPT -A INPUT -p udp --dport 138 -m state --state NEW -s 10.0.0.0/24 -j ACCEPT $IPT -A INPUT -p tcp --dport 139 -m state --state NEW -s 10.0.0.0/24 -j ACCEPT $IPT -A INPUT -p udp --dport 139 -m state --state NEW -s 10.0.0.0/24 -j ACCEPT $IPT -A INPUT -p tcp --dport 445 -m state --state NEW -s 10.0.0.0/24 -j ACCEPT $IPT -A INPUT -p udp --dport 445 -m state --state NEW -s 10.0.0.0/24 -j ACCEPT $IPT -A INPUT -p tcp --dport 389 -m state --state NEW -s 10.0.0.0/24 -j ACCEPT $IPT -A INPUT -p udp --dport 389 -m state --state NEW -s 10.0.0.0/24 -j ACCEPT $IPT -A INPUT -p tcp --dport 901 -m state --state NEW -s 10.0.0.0/24 -j ACCEPT $IPT -A INPUT -p udp --dport 901 -m state --state NEW -s 10.0.0.0/24 -j ACCEPT ############################################################### # Regole di sicurezza # Block fragments and Xmas tree as well as SYN,FIN and SYN,RST ############################################################### $IPT -A INPUT -p ip -f -j DROP $IPT -A INPUT -p tcp --tcp-flags ALL ACK,RST,SYN,FIN -j DROP $IPT -A INPUT -p tcp --tcp-flags SYN,FIN SYN,FIN -j DROP $IPT -A INPUT -p tcp --tcp-flags SYN,RST SYN,RST -j DROP ############################### # Concludo lo script firewall ############################### # echo -n "Iptables successfully configured."
Descrizione delle regole precedenti
Dopo aver dichiarato alcune variabili passiamo alla pulizia delle chains e alla reinizializzazione dei contatori:
iptables -F #Cancellazione delle regole presenti nelle chains iptables -X #Eliminazione delle chains non standard vuote iptables -Z #Inizializzazione dei contatori (utile per il debugging)
Definiamo in seguito le policy di default per le 3 chains predefinite, settando tutto a DROP (in questo modo, tutto ciò che non è esplicitamente permesso è di fatto proibito!):
iptables -P INPUT DROP iptables -P FORWARD DROP iptables -P OUTPUT DROP
Le 2 policy built-in sono ACCEPT (che accetta tutti i pacchetti su una data chain) e DROP, che abbiamo già visto. Sono inoltre presenti 2 estensioni: LOG (relativa al modulo che si occupa del logging dell'attività del firewall) e REJECT (che ha fondamentalmente lo stesso effetto di DROP, ma risponde ai tentativi di connessione con un ICMP "port unreachable").
Infine, è possibile utilizzare altri due target speciali, RETURN e QUEUE, che però non approfondiremo.
Siamo finalmente giunti alle regole vere e proprie. Cominciamo accettando esplicitamente tutto il traffico, in uscita ed in entrata, sull'interfaccia di loopback. Si tratta di una scelta consigliata e assolutamente sicura, poiché il loopback non rappresenta un collegamento alla rete, ma viene utilizzato da alcune applicazioni per il loro corretto funzionamento:
iptables -A INPUT -i lo -j ACCEPT iptables -A OUTPUT -o lo -j ACCEPT
Come vediamo abbiamo specificato le due chains su cui agire (INPUT e OUTPUT), l'interfaccia relativa (lo) ed il target, ovvero la policy da seguire per i pacchetti che matchano la regola.
A questo punto vediamo all'opera una delle nuove funzionalità di iptables, il Rate Limiting, che ci permette di proteggerci dai SYN flood. Creando una nuova chain user-defined dove inviare TCP SYN, infatti, possiamo limitare il ratio di arrivo dei pacchetti ed evitare così attacchi di tipo Denial of Service (DoS), che mirano ad esaurire le risorse dei sistemi bersaglio:
iptables -N syn-flood iptables -A INPUT -i $IFACE -p tcp syn -j syn-flood iptables -A syn-flood -m limit limit 1/s limit-burst 4 -j RETURN iptables -A syn-flood -j DROP
Quello che abbiamo fatto è creare una nuova chain user-defined chiamata "syn-flood", attraverso l'opzione -N. A questo punto abbiamo comunicato al Packet Filter di inviare tutti i pacchetti TCP con flag SYN settato (-p tcp syn) a tale chain e di limitare il ratio di arrivo di tali pacchetti.
Ora utilizziamo la Stateful Inspection per assicurarci che le nuove connessioni TCP siano dei pacchetti SYN e per rifiutare di conseguenza tutte quelle che non lo sono (possibili FIN scan o pacchetti malformati):
iptables -A INPUT -i $IFACE -p tcp syn -m state state NEW -j DROP
Infine passiamo a impostare le regole sui servizi offerti dal nostro server:
- Accesso pubblico al servizio
iptables -A INPUT -p tcp --dport 21 -m state --state NEW -j ACCEPT
- Accesso al servizio solo dalla nostra LAN
iptables -A INPUT -p tcp --dport 2605 -m state --state NEW -s 192.168.90.0/24 -j ACCEPT
Avviare il firewall
Arrivati a questo punto non ci resta che proteggere il file e renderlo eseguibile:
# chmod 700 /etc/iptables-firewall.sh # chown root:root /etc/iptables-firewall.sh
Per avviare lo script direttamente al boot del nostro server sarà sufficiente modificare il file di configurazione delle impostazioni di rete:
# nano /etc/network/interfaces
aggiungendo una riga pre-up
alla configurazione dell'interfaccia di rete pubblica:
auto eth1 iface eth1 inet static address 192.168.0.111 netmask 255.255.255.0 gateway 192.168.0.1 dns-search somedomain.org dns-nameservers 195.238.2.21 195.238.2.22 broadcast 192.168.0.0 pre-up /etc/iptables-firewall.sh
Impostare il ban di IP ostili
Per impostare il blocco di un IP è sempre possibile agire manualmente, in questo modo:
# iptables -I INPUT -s 192.168.1.100 -j DROP
ma l'amministrazione e la gestione manuale dei ban agli indirizzi IP ostili non è praticabile.
A questo scopo ci può venire in aiuto uno strumento disponibile nei repository ufficiali di Debian:
# apt-get install ipset
Una volta installato, occorre creare la lista, che chiameremo blacklist:
# ipset create blacklist hash:net maxelem 1000000
Con il comando:
# ipset list
possiamo vedere l'elenco delle liste già create.
A questo punto è possibile aggiungere a mano il primo IP da bannare:
# ipset add blacklist 1.1.2.0/24 # ipset add blacklist 1.1.3.0/24
Controlliamo se i due IP sono stati aggiunti alla lista di ban:
# ipset list Name: blacklist Type: hash:net Revision: 6 Header: family inet hashsize 1024 maxelem 1000000 Size in memory: 472 References: 0 Number of entries: 2 Members: 1.1.3.0/24 1.1.2.0/24
Aggiungere a mano tutti gli IP da bannare è un'impresa titanica; meglio affidarsi a liste già costruite, come quelle utilizzate qui di seguito, disponibili sotto licenza GPL.
Per prima cosa installiamo un tool per convertire le liste di iBlockList nel formato accettato da Ipset.
# apt-get install python-pip curl
Quindi recuperiamo uno script che ci permetterà di mantenere aggiornata la nostra lista di IP ostili:
# wget -O /usr/local/sbin/update-blacklist.sh https://raw.githubusercontent.com/trick77/ipset-blacklist/master/update-blacklist.sh # chmod +x /usr/local/sbin/update-blacklist.sh # mkdir -p /etc/ipset-blacklist # wget -O /etc/ipset-blacklist/ipset-blacklist.conf https://raw.githubusercontent.com/trick77/ipset-blacklist/master/ipset-blacklist.conf
Quindi salviamo l'attuale configurazione di ipset:
# ipset save > /etc/ipset-blacklist/ip-blacklist.restore
Modifichiamo il file di configurazione adattandolo alle nostre necessità:
# nano /etc/ipset-blacklist/ipset-blacklist.conf
Impostiamo un cronjob che ogni domenica a mezzanotte aggiornerà le nostre liste:
crontab -e 0 0 * * 7 /usr/local/sbin/update-blacklist.sh /etc/ipset-blacklist/ipset-blacklist.conf
Aggiungiamo la nuova regola al nostro script iptables:
# nano /etc/iptables-firewall.sh # Imposto le regole ipset iptables -I INPUT -m set --match-set blacklist src -j DROP iptables -I FORWARD -m set --match-set blacklist src -j DROP
e facciamo in modo che ipset sia impostato correttamente dopo un riavvio, aggiungendo la direttiva:
pre-up ipset restore -! < /etc/ipset-blacklist/ip-blacklist.restore
alla sezione della scheda di rete principale nel file /etc/network/interfaces, stando attenti a inserirla prima della direttiva pre up impostata in precedenza per l'avvio dello script di iptables.
Sitografia
http://www.sitepoint.com/secure-server-iptables/
http://news.dediserve.com/2009/09/23/configuring-iptables-on-your-vps/
http://www.temporini.net/configurare-un-firewall-con-iptables
http://www.commedia.it/ccontavalli/docs-it/iptables/iptables4dummies/
Guida scritta da: Ferdybassi 16:02, 17 apr 2011 (CEST) | Debianized 20% |
Estesa da: | |
Verificata da: | |
Verificare ed estendere la guida | Cos'è una guida Debianized |