Upgrade da Etch a Lenny e configurazione di iptables
di marcognu | 16/03/2009
Se anche tu, come me, ti trovi a gestire dei server Debian GNU/Linux, ti consiglio vivamente di passare da Etch a Lenny, in modo tale da lasciarti alle spalle il bug di OpenSSL 0.9.8.c, cioè quello per cui il generatore di numeri casuali non era poi così tanto casuale (DSA-1571-1).
Cosa è successo?
Nei giorni scorsi qualcuno ha cercato di forzare Apache per mettere al suo posto uno script che aprisse un socket sulla porta 80 verso il mondo esterno, per poi fare chissà cosa. Ovviamente questo script ha lasciato traccia nell’error_log di Apache, quindi è stato facile sgamarlo. In più il pirla ha usato un bell’IP pubblico, appartenente al pool di IP di un provider texano, per cui ho potuto agevolmente segnalare l’abuso allo stesso provider.
Il risultato di questo tentativo di hack del mio server è stato solo il down di Apache, dovuto al fatto che il web server riscontrava un conflitto sulla porta 80 e quindi non partiva.
Dopo questo episodio ho deciso quindi di fare una bella distro-upgrade in modo tale da levare per sempre i rischi di bug e altro, derivanti dai vecchi packages presenti nei repository di Etch. Putrtoppo infatti, nonostante gli aggiornamenti vari, l’OpenSSL era sempre alla versione 0.9.8c. Sì, sicuramente patchato, però il timore di vedersi il server bucato ti resta nel cervello…
Per procedere con l’upgrade della distro vi consiglio il seguente articolo, molto utile e preciso: cyberciti
Come leggerete in tale articolo, l’autore cita iptables. Altro mio consiglio spassionato: non fate come me, che pur conoscendo bene tale software – peraltro strafico perché semplicemente fa quello che deve fare – non lo avevo ancora configurato.
Iptables vi permette di filtrare tutto il traffico attorno al vostro server; se passate a Lenny, probabilmente lo troverete già installato e attivo, ma senza alcuna regola impostata. Non fatevi intimorire dalla sua sintassi, perché di fatto è molto intuitiva.
Dato che avevo a disposizione un file di regole che scrissi per Fedora, prima di fare cazzate ho chiesto al buon vecchio Google se sapeva darmi qualche indicazione specifica per Lenny (le distro qualche differenza tra di loro la devono pur implementare, se no a cosa serve averne n-mila a disposizione? ;-)
Sappiate che la cosa fondamentale da fare con iptables è non chiudersi mai fuori dal server stesso, se no per ripigliarlo o vi rivolgete al vostro houser, che interverrà con un reset della macchina, magari pigiando il tastino posto sullo chassîs del server stesso, o, peggio, staccandogli la corrente, oppure vi rivolgete a qualche divinità la quale però non vi darà retta perché fino ad un attimo prima l’avrete nominata più e più volte accostandola ad aggettivi che richiamano il mondo animale.
Questo è uno script shell che ho adattato alle mie esigenze:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 | #!/bin/sh # ... # Script per la configurazione di iptables # Rev. 1.0.4 - 20090326 check () { if [[ ! -x "\$1" ]] then echo "\$1 not found or is not executable" exit 1 fi } IPTABLES="/sbin/iptables" check "$IPTABLES" #IPTABLES=iptables_debug rule_counter=1 iptables_debug () { echo "doing ( $((rule_counter++)) ): \"/sbin/iptables $*\"" /sbin/iptables $* } INTERFACE=$1 if [[ "$INTERFACE" == "" ]] then echo "Usage: $0 <network>" exit 1 fi echo -n "Attempting to bring up firewall on $INTERFACE: " # Cancella ogni regola precedente: $IPTABLES -F $IPTABLES -t nat -F $IPTABLES -t mangle -F $IPTABLES -X # Regole di default: $IPTABLES -P INPUT DROP $IPTABLES -P FORWARD DROP $IPTABLES -P OUTPUT DROP # Catene di regole: # ICMP: iptables -N icmp-chain $IPTABLES -A icmp-chain -i $INTERFACE -p icmp --icmp-type echo-reply -m state --state ESTABLISHED,RELATED -j ACCEPT $IPTABLES -A icmp-chain -i $INTERFACE -p icmp --icmp-type echo-request -m limit --limit 5/s -m state --state NEW -j ACCEPT $IPTABLES -A icmp-chain -i $INTERFACE -p icmp --icmp-type destination-unreachable -m state --state NEW -j ACCEPT $IPTABLES -A icmp-chain -i $INTERFACE -p icmp --icmp-type time-exceeded -m state --state NEW -j ACCEPT $IPTABLES -A icmp-chain -i $INTERFACE -p icmp --icmp-type timestamp-request -m state --state NEW -j ACCEPT $IPTABLES -A icmp-chain -i $INTERFACE -p icmp --icmp-type timestamp-reply -m state --state ESTABLISHED,RELATED -j ACCEPT # ogni altra cosa respinta: iptables -A icmp-chain -j DROP # SERVIZI: $IPTABLES -N services # regole specifiche: # ssh: $IPTABLES -A services -p tcp -i $INTERFACE --dport 22 --sport 1024:65535 -m state --state NEW -j ACCEPT # www: $IPTABLES -A services -p tcp -i $INTERFACE --dport 80 --sport 1024:65535 -m state --state NEW -j ACCEPT $IPTABLES -A services -p tcp -i $INTERFACE --dport 443 --sport 1024:65535 -m state --state NEW -j ACCEPT # ftp: $IPTABLES -A services -p tcp -i $INTERFACE --dport 21 --sport 1024:65535 -m state --state NEW -j ACCEPT $IPTABLES -A services -p tcp -i $INTERFACE --dport 35000:36000 -m state --state NEW -j ACCEPT # named: $IPTABLES -A services -p tcp -i $INTERFACE --dport 53 --sport 1024:65535 -m state --state NEW -j ACCEPT $IPTABLES -A services -p udp -i $INTERFACE --dport 53 --sport 1024:65535 -m state --state NEW -j ACCEPT $IPTABLES -A services -p tcp -i $INTERFACE --dport 953 --sport 1024:65535 -m state --state NEW -j ACCEPT # ntpd: $IPTABLES -A services -p tcp -i $INTERFACE --dport 123 --sport 1024:65535 -m state --state NEW -j ACCEPT # ogni altra cosa respinta: $IPTABLES -A services -j DROP # Blocca frammenti e "Xmas tree", SYN,FIN e SYN,RST: $IPTABLES -A INPUT -i $INTERFACE -p ip -f -j DROP $IPTABLES -A INPUT -i $INTERFACE -p tcp --tcp-flags ALL ACK,RST,SYN,FIN -j DROP $IPTABLES -A INPUT -i $INTERFACE -p tcp --tcp-flags SYN,FIN SYN,FIN -j DROP $IPTABLES -A INPUT -i $INTERFACE -p tcp --tcp-flags SYN,RST SYN,RST -j DROP # Tutto attivo su loopback: $IPTABLES -A INPUT -i lo -s 127.0.0.1 -j ACCEPT $IPTABLES -A OUTPUT -o lo -d 127.0.0.1 -j ACCEPT # BLACK LIST: $IPTABLES -A INPUT -i $INTERFACE -s 69.13.93.44 -j DROP $IPTABLES -A OUTPUT -d 69.13.93.44 -j DROP $IPTABLES -A INPUT -i $INTERFACE -s 205.134.160.58 -j DROP $IPTABLES -A OUTPUT -d 205.134.160.58 -j DROP $IPTABLES -A INPUT -i $INTERFACE -s 205.134.160.74 -j DROP $IPTABLES -A OUTPUT -d 205.134.160.74 -j DROP # connessioni gia' stabilite permesse: $IPTABLES -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT $IPTABLES -A OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT # Anti-spoofing: $IPTABLES -A INPUT -i $INTERFACE -s 200.200.200.200 -j DROP $IPTABLES -A INPUT -i $INTERFACE -s 192.168.0.0/24 -j DROP $IPTABLES -A INPUT -i $INTERFACE -s 127.0.0.0/8 -j DROP # Blocca pacchetti NEW senza SYN: $IPTABLES -A INPUT -p tcp ! --syn -m state --state NEW -j DROP # Connessioni in uscita: $IPTABLES -A OUTPUT -m state --state NEW -j ACCEPT # Attiva la catena ICMP: $IPTABLES -A INPUT -p icmp -j icmp-chain # Attiva la catena servizi: $IPTABLES -A INPUT -i $INTERFACE -m state --state NEW -j services echo "done." exit 0 |
Lo script svuota le regole di iptables già presenti in runtime e carica quelle in esso contenute. In questo modo, eseguendolo sarete al riparo dal rischio di fare un flush delle regole senza avere poi la possibilità di riaprirvi l’accesso in ssh: lo script infatti, tra le prime azioni che compie, imposta il firewall in modo tale che di default rifiuti TUTTE le connessioni in entrata, quindi se avete già eseguito almeno una volta questo codice e poi fate un flush da linea di comando, vi ritroverete chiusi fuori e senza chiavi! Occhio quindi a non fare MAI un “iptables -F” senza avere aperto un varco verso il server stesso, se no ritorniamo al punto houser o divinità. Sarò ridondante ma tenete sempre in mente che se iniziate a manipolare le regole con questo script, è meglio che continuiate a farlo con questo script!
Nota importante: nel mio caso sul server dove questa configurazione è attiva non gestisco i servizi di posta per terzi, quindi come potete vedere dal codice, il firewall permetterebbe la connessione al servizio smtp solo dall’interfaccia di loopback, quindi solo locali (ad esempio da applicazioni che devono inviare e-mail). Se avete bisogno di filtrare il traffico per questo servizio, aggiungete le dovute regole alla catena “services” in modo tale che i vostri utenti possano collegarsi correttamente ad esso. Questo vale per ogni servizio che dovete fornire all’esterno del vostro server.
Altre due cose utili da fare:
la prima è salvare il set di regole in runtime in modo tale da creare un file di configurazione per le regole di iptables, in questo modo:
# iptables-save > /etc/firewall.conf
la seconda è creare uno script di avvio in modo tale che il set di regole venga caricato da iptables ad ogni riavvio del server:
create ad esempio il file “/etc/network/if-up.d/iptables”, rendetelo eseguibile con un “chmod +x /etc/network/if-up.d/iptables” e scrivetegli questo contenuto:
#!/bin/sh
iptables-restore < /etc/firewall.conf
Ovviamente i set di regole possono essere personalizzati a seconda delle proprie esigenze e dei servizi che si vogliono o devono offrire, inserendo, come si evince dal codice, regole per bloccare ogni comunicazione con determinati IP remoti, creando quindi una sorta di black list.
Buon divertimento!
Tutti noi abbiamo in casa una workstation basata su processore DEC Alpha ;)