Le persone spesso pensano che un firewall fornisce la massima sicurezza, ma non è così. Nella maggior parte dei casi un firewall configurato male fornisce meno sicurezza che non averne uno installato. Un firewall inoltre è una parte di software e tale dovrebbe essere trattato, perchè può benissimo contenere bug.
Quindi è consigliato pensarci prima di installare un firewall. Se ne ha veramente bisogno? Se si pensa che è necessario, allora scrivere da una parte per cosa dovrebbe funzionare, quale tipo di firewall e chi se ne dovrebbe occupare. Ma prima si legga questa guida.
I firewall sono usati per due scopi:
Ci sono tre tipi di firewall:
Un firewall dovrebbe essere un sistema dedicato, che non esegue servizi (o
che esegue solo
Tutto il traffico di rete è mandato sotto forma di pacchetti. Una grande quantità di traffico è divisa in piccoli pacchetti per facilitare la gestione, e poi riassemblata quando arriva a destinazione. Nell'intestazione di ogni pacchetto ci sono informazioni su come e dove dovrebbe essere portato. E queste informazioni sono quelle che usa un filtraggio di pacchetti. Il filtraggio è basato su:
In altre parole, questo filtraggio è basato su tutti i dati con una intestazione del pacchetto e non sul loro contenuto.
Svantaggi:
Vantaggi:
Esempi di filtraggio di pacchetti su Linux:
Un circuito di livello gateway è un firewall che convalida le connessioni prima che sia accettato lo scambio dati. Non accetta o nega solo pacchetti basati sull'intestazione del pacchetto, ma determina se la connessione è valida secondo le regole di configurazione, prima che si apre una sessione di scambio di dati. Il filtraggio è basato su:
Tutto il traffico è convalidato e monitorato, e il traffico non desiderato può essere eliminato.
Svantaggi:
L'applicazione di livello gateway è un proxy per applicazioni, scambio di dati con sistemi remoti sulla parte dei client. E' tenuta non pubblica da un DMZ (De-Militarized Zone: la parte di una rete privata visibile con il firewall) o da un firewall che non permette connessioni da fuori. Il filtraggio è basato su:
Vantaggi:
Svantaggi:
I gateway di applicazione sono considerati la soluzione più sicura poichè non devono essere eseguiti come root e i loro host non sono raggiungibili da Internet.
Esempi di gateway di applicazione:
Per poter usare iptables, deve essere abilitato il kernel. Qui si sono
aggiunti iptables come moduli (il comando
Per testare il suo funzionamento, digitare
Iptables è il nuovo e migliorato filtro di pacchetti nel kernel 2.4.x. E' il successore di ipchains nel kernel 2.2.x. Uno dei maggiori miglioramenti è che iptables può effettuare un completo filtraggio di pacchetti. E grazie a questo, è possibile tenere traccia di ogni connessione TCP stabilita.
Una connessione TCP è una serie di pacchetti che contiene informazioni sull'indirizzo IP sorgente, l'indirizzo IP di destinazione, la porta sorgente, quella di destinazione, e una sequenza di numeri, così che il pacchetto può essere riassemblato senza perdere dati. TCP è un protocollo orientato alla connessione, in contrasto con UDP, che è senza connessione.
Esaminando l'intestazione del pacchetto TCP, un completo filtro di pacchetti può determinare se un pacchetto TCP ricevuto è parte di una connessione già stabilita o meno e decidere se accettare o no il pacchetto.
E' possibile ingannare un non completo filtro di pacchetti quando si accettano pacchetti che si dovrebbero eliminare, manipolando l'intestazione del pacchetto TCP. Può essere fatto con la manipolazione della flag SYN o di altre flag nell'intestazione TCP, per far sembrare un pacchetto pericoloso come parte della connessione stabilita (poichè il filtro di pacchetti non fa una traccia delle connessioni). Con un completo filtro di pacchetti è possibile ridurre questi pacchetti poichè non sono parte di una connessione già stabilita. Questo fermerà anche la possibilità di "stealth scans", un tipo di port scan con il quale si manda pacchetti con flag che sono più probabili di essere loggati da un firewall che da pacchetti ordinari SYN.
Iptables fornisce molte altre caratteristiche come NAT (Network Address Translation) e il rate limiting. Quest'ultimo è utile quando si cerca di prevenire attacchi DoS (Denial of Service) come SYN flood.
Una connessione TCP è stabilita in tre tempi (three-way handshake). Quando si stabilisce la connessione TCP il client manda un pacchetto al server con la flag SYN. Quando il server riceve il pacchetto SYN, risponde mandando un pacchetto SYN+ACK al client. Quando riceve SYN+ACK, il client risponde con un terzo pacchetto ACK che riconosce la connessione.
Un attacco SYN flood è effettuato con il mandare un pacchetto SYN e con una mancata risposta al pacchetto SYN+ACK. Il client può fare un pacchetto con un indirizzo IP sorgente falso perchè non ha bisogno di una replica. Il server aggiungerà una voce a una queue di connessioni metà aperte, quando riceve il pacchetto SYN e poi aspetta il pacchetto finale ACK prima di eliminare la voce dalla queue. La queue ha un numero limitato di slot e se tutti gli slot sono pieni, non si può aprire un'altra connessione. Se il pacchetto ACK non è ricevuto prima di un tempo specificato, la voce sarà eliminata dalla queue. Le impostazione del tempo specificato variano, ma sono di solito 30-60 secondi o più. Il client inizia l'attacco con molti pacchetti SYN con indirizzi IP di diversa sorgente, e li manda agli indirizzi IP da colpire e riempiono la queue delle connessioni metà aperte e non fanno stabilire a altri client una connessione con il server.
In questi casi diventa di aiuto il rate limit. E' possibile limitare una
parte di pacchetti SYN accettati con
Alcuni esempi pratici.
Quando iptables è caricato nel kernel, ha cinque sezioni in cui si possono
elencare le regole, e sono
Si possono mettere le regole direttamente nelle 5 chain principali o creare nuove chain e aggiungerle come regole di una esistente chain. Iptables supporta le seguenti opzioni.
| Opzione: | Descrizione: |
|---|---|
Iniziare con bloccare tutti i pacchetti ICMP nella propria macchina, per familiarizzare con iptables.
# iptables -A INPUT -p icmp -j DROP
Si specifica la chain nella quale dovrebbe essere aggiunta la regola, poi il
protocollo del pacchetto coincidente e l'obiettivo. Quest'ultimo può essere
il nome di una chain specificata dall'utente o uno degli obiettivi speciali
Dare un
# iptables -F
Si pone in rilievo il filtraggio di pacchetti completo in iptables. Se si vuole abilitare una ispezione completa dei pacchetti in arrivo su eth0, si digiti il comando:
# iptables -A INPUT -i eth0 -m state --state ESTABLISHED,RELATED -j ACCEPT
Nel comando sopra, si accettano pacchetti da una connessione già stabilita o
associata nella chain INPUT. E si potrebbero eliminare i pacchetti che non
sono nella tabella con
| Modulo | Descrizione | Opzioni estese |
|---|---|---|
Cercare di creare una chain definita dall'utente e applicarla a una chain esistente:
(Creare una nuova chain con una regola) # iptables -X mychain # iptables -N mychain # iptables -A mychain -i eth0 -m state --state ESTABLISHED,RELATED -j ACCEPT(Tutto il traffico in uscita è accettato. Quello in entrata no.) # iptables -P OUTPUT ACCEPT # iptables -P INPUT DROP(Aggiungerla alla chain INPUT) # iptables -A INPUT -j mychain
Applicando la regola alla chain input si ottiene: Tutti i pacchetti in uscita sono accettati e quelli in entrata no.
Si può trovare documentazione in
Si vede un esempio completo.
#!/sbin/runscript
IPTABLES=/sbin/iptables
IPTABLESSAVE=/sbin/iptables-save
IPTABLESRESTORE=/sbin/iptables-restore
FIREWALL=/etc/firewall.rules
DNS1=212.242.40.3
DNS2=212.242.40.51
#inside
IIP=10.0.0.2
IINTERFACE=eth0
LOCAL_NETWORK=10.0.0.0/24
#outside
OIP=217.157.156.144
OINTERFACE=eth1
opts="${opts} showstatus panic save restore showoptions rules"
depend() {
need net
}
rules() {
stop
ebegin "Setting internal rules"
einfo "Setting default rule to drop"
$IPTABLES -P FORWARD DROP
$IPTABLES -P INPUT DROP
$IPTABLES -P OUTPUT DROP
#default rule
einfo "Creating states chain"
$IPTABLES -N allowed-connection
$IPTABLES -F allowed-connection
$IPTABLES -A allowed-connection -m state --state ESTABLISHED,RELATED -j ACCEPT
$IPTABLES -A allowed-connection -i $IINTERFACE -m limit -j LOG --log-prefix \
"Bad packet from ${IINTERFACE}:"
$IPTABLES -A allowed-connection -j DROP
#ICMP traffic
einfo "Creating icmp chain"
$IPTABLES -N icmp_allowed
$IPTABLES -F icmp_allowed
$IPTABLES -A icmp_allowed -m state --state NEW -p icmp --icmp-type \
time-exceeded -j ACCEPT
$IPTABLES -A icmp_allowed -m state --state NEW -p icmp --icmp-type \
destination-unreachable -j ACCEPT
$IPTABLES -A icmp_allowed -p icmp -j LOG --log-prefix "Bad ICMP traffic:"
$IPTABLES -A icmp_allowed -p icmp -j DROP
#Incoming traffic
einfo "Creating incoming ssh traffic chain"
$IPTABLES -N allow-ssh-traffic-in
$IPTABLES -F allow-ssh-traffic-in
#Flood protection
$IPTABLES -A allow-ssh-traffic-in -m limit --limit 1/second -p tcp --tcp-flags \
ALL RST --dport ssh -j ACCEPT
$IPTABLES -A allow-ssh-traffic-in -m limit --limit 1/second -p tcp --tcp-flags \
ALL FIN --dport ssh -j ACCEPT
$IPTABLES -A allow-ssh-traffic-in -m limit --limit 1/second -p tcp --tcp-flags \
ALL SYN --dport ssh -j ACCEPT
$IPTABLES -A allow-ssh-traffic-in -m state --state RELATED,ESTABLISHED -p tcp --dport ssh -j ACCEPT
#outgoing traffic
einfo "Creating outgoing ssh traffic chain"
$IPTABLES -N allow-ssh-traffic-out
$IPTABLES -F allow-ssh-traffic-out
$IPTABLES -A allow-ssh-traffic-out -p tcp --dport ssh -j ACCEPT
einfo "Creating outgoing dns traffic chain"
$IPTABLES -N allow-dns-traffic-out
$IPTABLES -F allow-dns-traffic-out
$IPTABLES -A allow-dns-traffic-out -p udp -d $DNS1 --dport domain \
-j ACCEPT
$IPTABLES -A allow-dns-traffic-out -p udp -d $DNS2 --dport domain \
-j ACCEPT
einfo "Creating outgoing http/https traffic chain"
$IPTABLES -N allow-www-traffic-out
$IPTABLES -F allow-www-traffic-out
$IPTABLES -A allow-www-traffic-out -p tcp --dport www -j ACCEPT
$IPTABLES -A allow-www-traffic-out -p tcp --dport https -j ACCEPT
#Catch portscanners
einfo "Creating portscan detection chain"
$IPTABLES -N check-flags
$IPTABLES -F check-flags
$IPTABLES -A check-flags -p tcp --tcp-flags ALL FIN,URG,PSH -m limit \
--limit 5/minute -j LOG --log-level alert --log-prefix "NMAP-XMAS:"
$IPTABLES -A check-flags -p tcp --tcp-flags ALL FIN,URG,PSH -j DROP
$IPTABLES -A check-flags -p tcp --tcp-flags ALL ALL -m limit --limit \
5/minute -j LOG --log-level 1 --log-prefix "XMAS:"
$IPTABLES -A check-flags -p tcp --tcp-flags ALL ALL -j DROP
$IPTABLES -A check-flags -p tcp --tcp-flags ALL SYN,RST,ACK,FIN,URG \
-m limit --limit 5/minute -j LOG --log-level 1 --log-prefix "XMAS-PSH:"
$IPTABLES -A check-flags -p tcp --tcp-flags ALL SYN,RST,ACK,FIN,URG -j DROP
$IPTABLES -A check-flags -p tcp --tcp-flags ALL NONE -m limit \
--limit 5/minute -j LOG --log-level 1 --log-prefix "NULL_SCAN:"
$IPTABLES -A check-flags -p tcp --tcp-flags ALL NONE -j DROP
$IPTABLES -A check-flags -p tcp --tcp-flags SYN,RST SYN,RST -m limit \
--limit 5/minute -j LOG --log-level 5 --log-prefix "SYN/RST:"
$IPTABLES -A check-flags -p tcp --tcp-flags SYN,RST SYN,RST -j DROP
$IPTABLES -A check-flags -p tcp --tcp-flags SYN,FIN SYN,FIN -m limit \
--limit 5/minute -j LOG --log-level 5 --log-prefix "SYN/FIN:"
$IPTABLES -A check-flags -p tcp --tcp-flags SYN,FIN SYN,FIN -j DROP
# Apply and add invalid states to the chains
einfo "Applying chains to INPUT"
$IPTABLES -A INPUT -m state --state INVALID -j DROP
$IPTABLES -A INPUT -p icmp -j icmp_allowed
$IPTABLES -A INPUT -j check-flags
$IPTABLES -A INPUT -i lo -j ACCEPT
$IPTABLES -A INPUT -j allow-ssh-traffic-in
$IPTABLES -A INPUT -j allowed-connection
einfo "Applying chains to FORWARD"
$IPTABLES -A FORWARD -m state --state INVALID -j DROP
$IPTABLES -A FORWARD -p icmp -j icmp_allowed
$IPTABLES -A FORWARD -j check-flags
$IPTABLES -A FORWARD -o lo -j ACCEPT
$IPTABLES -A FORWARD -j allow-ssh-traffic-in
$IPTABLES -A FORWARD -j allow-www-traffic-out
$IPTABLES -A FORWARD -j allowed-connection
einfo "Applying chains to OUTPUT"
$IPTABLES -A OUTPUT -m state --state INVALID -j DROP
$IPTABLES -A OUTPUT -p icmp -j icmp_allowed
$IPTABLES -A OUTPUT -j check-flags
$IPTABLES -A OUTPUT -o lo -j ACCEPT
$IPTABLES -A OUTPUT -j allow-ssh-traffic-out
$IPTABLES -A OUTPUT -j allow-dns-traffic-out
$IPTABLES -A OUTPUT -j allow-www-traffic-out
$IPTABLES -A OUTPUT -j allowed-connection
#Allow client to route through via NAT (Network Address Translation)
$IPTABLES -t nat -A POSTROUTING -o $OINTERFACE -j MASQUERADE
eend $?
}
start() {
ebegin "Starting firewall"
if [ -e "${FIREWALL}" ]; then
restore
else
einfo "${FIREWALL} does not exists. Using default rules."
rules
fi
eend $?
}
stop() {
ebegin "Stopping firewall"
$IPTABLES -F
$IPTABLES -t nat -F
$IPTABLES -X
$IPTABLES -P FORWARD ACCEPT
$IPTABLES -P INPUT ACCEPT
$IPTABLES -P OUTPUT ACCEPT
eend $?
}
showstatus() {
ebegin "Status"
$IPTABLES -L -n -v --line-numbers
einfo "NAT status"
$IPTABLES -L -n -v --line-numbers -t nat
eend $?
}
panic() {
ebegin "Setting panic rules"
$IPTABLES -F
$IPTABLES -X
$IPTABLES -t nat -F
$IPTABLES -P FORWARD DROP
$IPTABLES -P INPUT DROP
$IPTABLES -P OUTPUT DROP
$IPTABLES -A INPUT -i lo -j ACCEPT
$IPTABLES -A OUTPUT -o lo -j ACCEPT
eend $?
}
save() {
ebegin "Saving Firewall rules"
$IPTABLESSAVE > $FIREWALL
eend $?
}
restore() {
ebegin "Restoring Firewall rules"
$IPTABLESRESTORE < $FIREWALL
eend $?
}
restart() {
svc_stop; svc_start
}
showoptions() {
echo "Usage: $0 {start|save|restore|panic|stop|restart|showstatus}"
echo "start) will restore setting if exists else force rules"
echo "stop) delete all rules and set all to accept"
echo "rules) force settings of new rules"
echo "save) will store settings in ${FIREWALL}"
echo "restore) will restore settings from ${FIREWALL}"
echo "showstatus) Shows the status"
}
Alcuni consigli sulla creazione di firewall:
Se si pensa che iptables è difficile da capire o richiede un lungo setup, si
può usare
Squid è un server proxy potente. Può filtrare il traffico basato sul tempo, espressioni regolari su path/URI, indirizzo IP sorgente e di destinazione, dominio, browser, user name autenticato, MIME type, e numero della porta (protocollo).
Nel seguente esempio si è aggiunto un filtro per i banner invece di uno
basato sui siti porno. Gentoo.org
Le indicazioni:
Quattro sono i
# Bind to a ip and port http_port 10.0.2.1:3128 # Standard configuration hierarchy_stoplist cgi-bin ? acl QUERY urlpath_regex cgi-bin \? no_cache deny QUERY # Add basic access control lists acl all src 0.0.0.0/0.0.0.0 acl manager proto cache_object acl localhost src 127.0.0.1/255.255.255.255 # Add who can access this proxy server acl localnet src 10.0.0.0/255.255.0.0 # And ports acl SSL_ports port 443 acl Safe_ports port 80 acl Safe_ports port 443 acl purge method PURGE # Add access control list based on regular # expressions within urls acl archives urlpath_regex "/etc/squid/files.acl" acl url_ads url_regex "/etc/squid/banner-ads.acl" # Add access control list based on time and day acl restricted_weekdays time MTWHF 8:00-17:00 acl restricted_weekends time A 8:00-13:00 acl CONNECT method CONNECT #allow manager access from localhost http_access allow manager localhost http_access deny manager # Only allow purge requests from localhost http_access allow purge localhost http_access deny purge # Deny requests to unknown ports http_access deny !Safe_ports # Deny CONNECT to other than SSL ports http_access deny CONNECT !SSL_ports # My own rules # Add a page do be displayed when # a banner is removed deny_info NOTE_ADS_FILTERED url_ads # Then deny them http_access deny url_ads # Deny all archives http_access deny archives # Restrict access to work hours http_access allow localnet restricted_weekdays http_access allow localnet restricted_weekends # Deny the rest http_access deny all
Mettere i tipi di file che non si vuole che siano scaricati dagli utenti, qui si sono aggiunti zip, viv, exe, mp3, rar, ace, avi, mov, mpg, mpeg, au, ra, arj, tar, gz e z.
\.[Zz][Ii][pP]$ \.[Vv][Ii][Vv].* \.[Ee][Xx][Ee]$ \.[Mm][Pp]3$ \.[Rr][Aa][Rr]$ \.[Aa][Cc][Ee]$ \.[Aa][Ss][Ff]$ \.[Aa][Vv][Ii]$ \.[Mm][Oo][Vv]$ \.[Mm][Pp][Gg]$ \.[Mm][Pp][Ee][Gg]$ \.[Aa][Uu]$ \.[Rr][Aa]$ \.[Aa][Rr][Jj]$ \.[Tt][Aa][Rr]$ \.[Gg][Zz]$ \.[Zz]$
Si aggiungono le espressioni regolari per identificare i banner.
/adv/.*\.gif$ /[Aa]ds/.*\.gif$ /[Aa]d[Pp]ix/ /[Aa]d[Ss]erver /[Aa][Dd]/.*\.[GgJj][IiPp][FfGg]$ /[Bb]annerads/ /adbanner.*\.[GgJj][IiPp][FfGg]$ /images/ad/ /reklame/ /RealMedia/ads/.* ^http://www\.submit-it.* ^http://www\.eads.* ^http://ads\. ^http://ad\. ^http://ads02\. ^http://adaver.*\. ^http://adforce\. adbot\.com /ads/.*\.gif.* _ad\..*cgi /Banners/ /SmartBanner/ /Ads/Media/Images/ ^http://static\.wired\.com/advertising/ ^http://*\.dejanews\.com/ads/ ^http://adfu\.blockstackers\.com/ ^http://ads2\.zdnet\.com/adverts ^http://www2\.burstnet\.com/gifs/ ^http://www.\.valueclick\.com/cgi-bin/cycle ^http://www\.altavista\.com/av/gifs/ie_horiz\.gif
E come ultima parte si vuole che sia mostrato questo file quando è rimosso un banner. E' un file metà HTML con una immagine gif 4x4 trasparente.
<HTML> <HEAD> <META HTTP-EQUIV="REFRESH" CONTENT="0; URL=http://localhost/images/4x4.gif"> <TITLE>ERROR: The requested URL could not be retrieved</TITLE> </HEAD> <BODY> <H1>Add filtered!</H1>
Come si può vedere, Squid ha molte possibilità e funziona bene come filtro e proxy. Possono essere usati proxy alternativi Squid per funzionare bene con una grande rete. La configurazione elencata va bene per una piccola rete di 1-20 utenti.
Usare il filtro di pacchetti (iptables) e il gateway di applicazione (Squid) è la migliore soluzione, anche se nessuno può accedere a Squid da fuori. Fare attenzione agli attacchi da dentro.
Si deve configurare il browser per usare il server proxy. Il gateway non permette il contatto con l'esterno agli utenti, a meno che si usi il proxy.
Si può usare iptables per mandare tutto il traffico outbound a un proxy Squid. Si aggiunge una regola forwarding/prerouting sul gateway:
# iptables -t nat -A PREROUTING -p tcp --dport 80 -j DNAT --to proxyhost:3128 # iptables -t nat -A PREROUTING -p tcp --dport 443 -j DNAT --to proxyhost:3128
Si è imparato che:
Se si è pronti, creare un firewall che corrisponda alle proprie esigenze.