Firewall, netfilter, iptables Masetti Marco (marcomas@libero.it) v0.1, 01 Luglio 2000 Questo documento descrive come impostare un firewall usando Linux e in particolare il nuovo kernel 2.4 ______________________________________________________________________ Indice Generale 1. Introduzione 2. Liberatoria 3. Firewall 3.1 Introduzione 3.2 Norme generali di sicurezza 4. Netfilter 4.1 Descrizione 4.2 Differenze rispetto alle versioni 2.0 e 2.2 del kernel 4.3 Kernel 4.4 Descrizione 5. iptables 5.1 Introduzione 5.2 Differenze rispetto alle versioni 2.0 e 2.2 del kernel 5.2.1 Tabelle 5.2.2 Criteri per il filtraggio 5.2.3 Obiettivi 5.2.4 Varie 5.3 Compilare e installare iptables 5.4 Aggiornare iptables 5.5 Documentazione, mailing list 6. Filtraggio 6.1 Operazioni sulle catene 6.2 Operazioni sulle regole 6.3 Operazioni di selezione 6.4 Estensioni 7. NAT 7.1 Descrizione 7.2 Operazioni 7.2.1 SNAT (Source NAT) 7.2.2 MASQUERADE 7.2.3 DNAT (Destination NAT) 7.3 Protocollo speciali (ftp, quake, irc) 8. Connection tracking 8.1 Descrizione 8.2 Opzioni 8.3 Esempi 8.3.1 Esempio 1 8.3.2 Esempio 2 8.3.3 Esempio 3 8.3.4 Esempio 4 9. LOG 9.1 Descrizione 9.2 Opzioni 9.3 Utilizzo 9.4 Formato della registrazione 10. LIMIT 10.1 Descrizione 10.2 Opzioni 10.3 Esempi 11. Multiport 11.1 Descrizione 11.2 Opzioni 11.3 Esempi 12. Unclean 12.1 Descrizione 12.2 Opzioni 13. Owner 13.1 Descrizione 13.2 Opzioni 13.3 Esempi 14. Mac 14.1 Descrizione 14.2 Opzioni 14.3 Esempi 15. MARK 15.1 Descrizione 15.2 Opzioni 15.3 Esempi 16. TOS (Type Of Service) 16.1 Descrizione 16.2 Opzioni 16.3 Bit 16.4 Esempi 16.5 ipchains vs. iptables 17. MIRROR 17.1 Descrizione 17.2 Opzioni 18. REJECT 18.1 Descrizione 18.2 Opzioni 18.3 Esempi 19. TCP/IP 19.1 Connessione "Three-way handshake" 19.2 Porte 19.3 Esempio 19.4 Problemi 19.4.1 IP spoofing 19.4.2 Blind spoofing 19.4.3 Port scanning 20. FRAMMENTI 20.1 Descrizione 20.2 Ping della morte, Teardrop, ... 21. ICMP 21.1 Descrizione 21.2 Tipi ICMP 22. Masquerading, port forwarding 22.1 Masquerading 22.2 Port-forwarding, load-balancing, proxy trasparente 23. FTP 23.1 Descrizione 23.2 Esempi 24. DoS (Denial of Service) 24.1 Introduzione 24.2 TCP SYN Flooding 24.3 Smurfing 24.4 UDP Port DoS 24.5 LOG 25. Nessus e nmap 25.1 Introduzione 25.2 nmap 25.2.1 Dove si trova ? 25.2.2 Installazione 25.2.3 Esecuzione 25.2.4 Documentazione 25.3 Nessus 25.3.1 Dove si trova ? 25.3.2 nessus-libraries 25.3.3 nessus-core 25.3.4 nessus-plugins 25.3.5 Documentazione 26. Risorse 27. Marchi registrati 28. Appendice 28.1 Intestazione IP (Internet Protocol) 28.2 Intestazione TCP (Transmission Control Protocol) 28.3 Intestazione UDP (User Datagram Protocol) 28.4 Intestazione ICMP (Internet Control Message Protocol) 28.5 Servizi ______________________________________________________________________ 1. Introduzione Durante il mio tirocinio presso un internet service provider ho avuto l'occasione di approfondire la conoscenza di Linux, sistema operativo che si sta ritagliando uno spazio sempre maggiore nel panorama informatico. In particolare ho avuto la possibilità di utilizzare le versioni in sviluppo del nuovo kernel 2.4 (2.3) e di conoscere più da vicino il progetto Netfilter, il quale ha come obiettivo la realizzazione di una nuova infrastruttura adatta per la realizzazione di firewall evoluti con possibilità di NAT (Network Address Translation), manipolamento dei pacchetti, ... Durante lo studio ho raccolto e ricercato varia documentazione, informazioni, notizie utili che mi sono poi servite per realizzare questo documento per utilizzo personale. Quando ho poi deciso di realizzare la mia homepage ho pensato di metterlo a disposizione di chi ne avesse bisogno, con la speranza che possa essere in qualche modo di aiuto. Chi dovesse poi trovare imprecisioni, errori (clamorosi?) o avesse voglia di inviarmi dei commenti è naturalmente invitato a scrivermi. 2. Liberatoria L'autore non si assume alcuna responsabilità, esplicita o implicita, riguardante questo documento. Il documento deve essere visto come un'introduzione alle modalità di funzionamento del firewall in ambiente Linux. Non sono, e non pretendo di esserlo, un esperto sulla sicurezza. 3. Firewall 3.1. Introduzione Un firewall in genere è composto da uno o più computer che si pongono tra le reti private e quelle esterne (es. internet) con il preciso scopo di controllare ciò che transita da una rete verso l'altra. In particolare sono utilizzati per stabilire a quali servizi (www, ftp, mail,...) presenti nella rete internet è possibile accedere dalla rete locale, e quali possonono essere resi disponibili alle reti esterne. La necessità di questi controlli è dovuta al fatto che i sistemi operativi (Windows, Mac, Linux, ...), i protocolli utilizzati per lo scambio dei dati tra le reti (TCP/IP), i programmi hanno una serie di limiti, errori di programmazione che possono esporre la propria rete a diversi attacchi. Questi attacchi possono permettere ad una persona con le giuste informazioni e con particolari programmi (exploit) di individuare eventuali vulnerabilità e di accedere e modificare una macchina. L'intruso potrebbe quindi apportare delle modifiche che gli consentano di accedere in qualsiasi momento senza essere scoperto (backdoor), oppure di sfruttarla per sottrarre informazioni (progetti confidenziali, password, ...), per coinvolgerla in attacchi DoS (Denial of Service), DDoS (Distribuited Denial of Service) ... Le soluzioni adottate per proteggere le reti, viste anche le diversità dei sistemi, sono varie. L'ICSA, ente che certifica l'affidabilità di un prodotto firewall, ha individuato tre tipologie di firewall: · packet filtering · application gateway · packet inspection packet filtering Questa probabilmente è la soluzione più semplice e consiste nel controllare ogni pacchetto che transita da una rete all'altra. I pacchetti contengono una serie di informazioni (indirizzo sorgente, indirizzo destinazione, porta sorgente, porta destinazione ...) che possono essere utilizzate per stabilire se il pacchetto può essere accettato e quindi lasciato proseguire oppure no e quindi rifiutato. Questo tipo di firewall non provvede a richiedere e a controllare login e password, quindi ad identificare l'utente che richiede una connessione, l'unico dato disponibile è l'indirizzo sorgente contenuto nell'intestazione del pacchetto. application gateway In questo caso un'applicazione detta proxy si occupa di analizzare, autorizzare e inoltrare i pacchetti che transitano. L'autenticazione deve avvenire in modo sicuro e protetto, basato in genere su account e password cifrate. Sono molto diffuse e considerate ottimali le soluzioni che impiegano come firewall una macchina proxy che effettua anche il filtraggio dei pacchetti (packet filtering). packet inspection In questo caso oltre al filtraggio, comunque essenziale, si aggiungono ulteriori controlli che riguardano anche le altre informazioni sempre contenute nei pacchetti. Per valutare l'affidabilità della propria piattaforma (computer, sistema operativo, protocollo di rete) è possibile consultare il sito del CERT <http://www.cert.org/advisories/index.html> (Computer Emergency Response Team) e per ottenere varie informazioni il sito dell'ICSA <http://www.icsa.net>. 3.2. Norme generali di sicurezza Ottenere un sistema sicuro e protetto da un qualsiasi attacco è molto difficile, sono molte infatti le variabili che entrano in gioco, è comunque possibile adottare vari accorgimenti per cercare di proteggere al meglio la propria rete. In genere il punto di partenza per limitare queste vulnerabilità è quello di essere minimalisti, ossia configurare la propria macchina/firewall in modo che abbia lo stretto indispensabile, e di seguire i seguenti accorgimenti: Aggiornare e compilare il kernel abilitando le voci sulla sicurezza I kernel minori della versione 2.2.16 sono vulnerabili al TCP root exploit, le versioni minori alla 2.2.11 hanno un bug riguardante IPCHAINS e la frammentazione, aggiornare alle ultime versioni stabili del kernel risolve questi e altri problemi. Quando si compila il kernel è raccomandabile selezionare, se possibile, le voci IP: syn cookies, IP: always defragment. Permettono di risolvere alcuni problemi noti riguardanti la sicurezza. Installare i programmi strettamente necessari I programmi in genere sono molto complessi e quindi è inevitabile che ci possano essere degli errori di programmazione (BUG). Questi errori possono essere usati per accedere alle macchine quindi è indispensabile installare possibilmente solo i programmi strettamente necessari e in ogni caso consultare spesso il sito della propria distribuzione Linux per aggiornarli alle ultime versioni, soprattutto se sono stati riscontrati problemi riguardanti la sicurezza. Nota: aggiornare in casi di bachi noti è importante, se l'aggiornamento riguarda solo aggiunta di nuove funzionalità allora è meglio fare attenzione, in quanto potrebbero contenere a loro volta nuovi bug. Abilitare solo quei servizi (telnet, ftp, finger ...) di cui si ha realmente bisogno Linux permette di offrire tutta una serie di servizi agli utenti: ftp, mail, web. Per ottenere un elenco dei servizi attivi nella propria Linux box è possibile utilizzare il seguente comando: # netstat --inet -a -p Active Internet connections (servers and established) Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name tcp 0 0 *:ftp *:* LISTEN 324/inetd tcp 0 0 *:telnet *:* LISTEN 324/inetd ... Se sulla propria macchina ad esempio risulta attivo un server ftp e non si ha intenzione di permettere agli utenti di accedervi per effettuare upload/download di file allora è meglio disabilitare il servizio. A questo scopo basta modificare con un editor di testo il file /etc/inetd.conf e aggiungere un '#' all'inizio della riga: ftp stream tcp nowait root /usr/sbin/tcpd in.ftpd -l -a Quindi riavviare il processo inetd per rendere attiva la modifica. Nota: questa modifica non preclude la possibilità di effettuare ftp da questa macchina verso altre, ma solo l'inverso, ossia l'accesso di altre macchine alla propria. Utilizzare password cifrate (shadow, MD5) e scelte con criterio E' indispensabile scegliere password che non siano facilmente decifrabili, ossia brevi, appartenenti al dizionario o di uso comune. E' inoltre molto importante cambiarle con una certa frequenza. Rimuovere hardware non necessario Questo è un caso "paranoico" ma spesso anche hardware e driver non necessari possono essere sfruttati per degli attacchi. Controllare quali programmi possono essere pericolosi Con il comando: # find / -type f -perm +6000 -exec ls -l {} \; ... -rwsr-xr-x 1 root root 35892 Dec 8 1999 /usr/bin/chage -rwsr-xr-x 1 root root 37960 Dec 8 1999 /usr/bin/gpasswd -rwxr-sr-x 1 root tty 8580 Dec 21 1999 /usr/bin/write -rwsr-xr-x 1 root root 22904 Oct 25 1999 /usr/bin/crontab ... si ottiene una lista dei programmi che hanno particolare privilegi (root). Questi programmi potrebbero contenere dei bug che un intruso potrebbe sfruttare per acquisirne i privilegi e quindi arrecare danni al sistema. Se questi programmi sono indispensabili aggiornali con frequenza, in particolare se sono stati scoperti bachi riguardanti la sicurezza, o se inutili è possibile in molti casi anche eliminarli. Controllare il file /var/log/messages e verificare eventuali stranezze Se si utilizza il filtraggio dei pacchetti (con ipchains o iptables) è possibile impostare delle regole per "registrare" eventuali pacchetti anomali. Controllando queste informazioni è possibile stabilire se ci sono state intrusioni o tentativi di accesso. Usare software che verifichi l'integrità dei file (Tripwire) Se qualcuno riesce ad accedere ad una macchina potrebbe essere in grado di sostituire un programma o daemon con un "troiano" ossia un file che svolge le stesse funzioni ma che in più permette ad esempio di prelevare dei dati (es. password) dalla macchina della vittima e di inviarli all'intruso. Tripwire è un noto programma che controlla e verifica l'integrità dei file. Se la propria distribuzione utilizza i pacchetti rpm è possibile verificarne l'integrità utilizzando: rpm --verify -a > /tmp/rpm- verify.txt. Se in rpm-verify.txt in una o più linee compare un 5 allora il file associato è stato modificato. In questi casi è meglio controllare se queste modifiche sono proprie, altrimenti qualcuno potrebbe essere penetrato nel sistema. Nota: è sempre meglio fare attenzione ai programmi che si installano in particolare se prelevati da siti internet, floppy, zip di dubbia provenienza. Utilizzare ssh (secure shell) Servizi come ad esempio telnet sono insicuri in quanto la trasmissione dei dati avviene in "chiaro", compresi username e password. Quindi qualcuno, utilizzando uno "sniffer", potrebbe essere in grado di leggerle e utilizzarle a proprio vantaggio. ssh provvede a risolvere il problema cifrando le connessioni garantendo così maggior sicurezza. Consultare i siti dedicati alla sicurezza e alla scoperta di errori o buchi per la sicurezza Esistono diversi siti che si occupano di segnalare tempestivamente problemi, bachi presenti nei programmi o nei sistemi operativi e le relative precauzioni o soluzioni per risolverli. Tra i più noti packetstorm <http://www.packetstorm.securify.com>, securityfocus <http://www.securityfocus.com>. 4. Netfilter 4.1. Descrizione Netfilter è un'infrastruttura presente nel kernel, realizzata nel 1998 da Rusty Russell e Michael Neuling, che consente di scrivere dei moduli appositi per gestire il filtraggio, il manipolamento dei pacchetti, il NAT (Network Address Translation) e di caricarli quando necessario con il comando insmod o modprobe. E' possibile compilarli e integrarli nel kernel, creare nuovi moduli, aggiungere nuove funzionalità a quelle esistenti e perfino utilizzare i tool ipfwadm e ipchains, utilizzati rispettivamente con le versioni 2.0 e 2.2 del kernel, presenti anch'essi come moduli per garantire compatibilità con il passato. Naturalmente ipfwadm e ipchains non saranno supportati ancora a lungo, a partire dal 2004 il tool ufficiale sarà iptables, già disponibile, ma ancora in fase di sviluppo. 4.2. Differenze rispetto alle versioni 2.0 e 2.2 del kernel Le prime novità riguardano la gestione del passaggio dei pacchetti attraverso il sistema di filtraggio. Nei kernel 2.0 e 2.2 il pacchetto in arrivo è sottoposto innanzi tutto alle regole della catena INPUT (prima del routing) quindi successivamente, se destinato alla rete locale, alla catena forward e poi output, se destinato invece al firewall è inviato ai processi locali. I pacchetti in uscita dal firewall invece sono sottoposti alla sola catena output. __ +-------+ +-------+ +---------+ +---------+ __ |__| --->| input | ---> |Routing| ---> | forward | ---> | output | ---> |__| +-------+ +-------+ +---------+ +---------+^ | ^ | | V | +------ processi locali ------+ L'impostazione classica del firewall prevede quindi di inserire le regole di filtraggio nella catena input e di usare eventualmente la catena forward per il mascheramento. Nel prossimo kernel 2.4, a differenza della versione 2.2, quando un pacchetto arriva dalla rete viene innanzi tutto sottoposto al codice di routing e quindi se destinato o proveniente dalla rete locale e diretto all'esterno, è sottoposto esclusivamente alle regole della catena FORWARD. Alla catena INPUT sono destinati tutti i pacchetti diretti esclusivamente al firewall. Mentre i pacchetti che sono sottoposti alle regole della catena OUTPUT sono solo quelli generati esclusivamente dal firewall e in uscita. __ +-------+ +---------+ __ |__| ---> |Routing| ---> | FORWARD | -->.-----> |__| +-------+ +---------+ ^ | | | | V | +-------+ +--------+ | INPUT | | OUTPUT | +-------+ +--------+ | ^ V | +---- processi locali ----+ Questa modifica permette di avere maggior efficienza, ogni pacchetto è sottoposto alle regole di una SOLA catena (INPUT o FORWARD o OUTPUT), e semplicità di utilizzo. E' possibile utilizzare la catena INPUT per filtrare i pacchetti diretti al firewall, la catena OUTPUT per filtrare i pacchetti creati dal firewall e in uscita, la catena FORWARD per filtrare i pacchetti che transitano attraverso il firewall diretti o provenienti dalla rete locale. 4.3. Kernel Per poter utilizzare correttamente Netfilter e iptables è necessario compilare il kernel selezionando le seguenti voci: Networking options ---> ... [*] Network packet filtering (replaces ipchains) [CONFIG_NETFILTER] [ ] Network packet filtering debugging [CONFIG_NETFILTER_DEBUG] ... IP: Netfilter Configuration ---> <M> Connection tracking (required for masq/NAT) [CONFIG_IP_NF_CONNTRACK] <M> FTP protocol support [CONFIG_IP_NF_FTP] <M> Userspace queueing via NETLINK (EXPERIMENTAL) (NEW) [CONFIG_IP_NF_QUEUE] <M> Iptables support (required for filtering/masq/NAT) [CONFIG_IP_NF_IPTABLES] <M> limit match support [CONFIG_IP_NF_MATCH_LIMIT] <M> MAC address match support [CONFIG_IP_NF_MATCH_MAC] <M> netfilter MARK match support [CONFIG_IP_NF_MATCH_MARK] <M> Multiple port match support [CONFIG_IP_NF_MATCH_MULTIPORT] <M> TOS match support [CONFIG_IP_NF_MATCH_TOS] <M> Connection state match support [CONFIG_IP_NF_MATCH_STATE] <M> Packet filtering [CONFIG_IP_NF_FILTER] <M> REJECT target support [CONFIG_IP_NF_TARGET_REJECT] <M> MIRROR target support (EXPERIMENTAL) [CONFIG_IP_NF_TARGET_MIRROR] <M> Full NAT [CONFIG_IP_NF_NAT] <M> MASQUERADE target support [CONFIG_IP_NF_TARGET_MASQUERADE] <M> REDIRECT target support [CONFIG_IP_NF_TARGET_REDIRECT] <M> Packet mangling [CONFIG_IP_NF_MANGLE] <M> TOS target support [CONFIG_IP_NF_TARGET_TOS] <M> MARK target support [CONFIG_IP_NF_TARGET_MARK] <M> LOG target support [CONFIG_IP_NF_TARGET_LOG] Le voci relative a "IP: Netfilter Configuration" sono state tutte impostate come moduli (M), ma possono essere selezionate anche in modo da essere incluse direttamente nel kernel (*), o non essere proprio selezionate (sconsigliato). E' inoltre possibile includere solo una parte nel kernel e il resto compilarli come moduli, appena necessari potranno essere caricati con i comandi modprobe o insmod. 4.4. Descrizione Networking options ---> [*] Network packet filtering (replaces ipchains) Selezionare questa voce se si desidera che la Linux box possa operare come firewall, e quindi filtrare, mascherare, manipolare i pacchetti usando l'infrastruttura netfilter e il nuovo programma iptables, sostituto di ipchains nel kernel 2.4. Networking options ---> [ ] Network packet filtering debugging Selezionare questa voce nel caso si debba effettuare il debug del codice di netfilter e si vogliano maggiori informazioni. IP: Netfilter Configuration ---> Menu principale per la selezione dei moduli. Connection tracking (required for masq/NAT) Il connection tracking tiene traccia delle connessioni stabilite in modo da riconoscere quali pacchetti ne fanno parte e quali no. Richiesto per il mascheramento (masquerading) e altre forme di NAT (Network Address Translation). Può essere utilizzato anche per supportare il filtraggio dei pacchetti. FTP protocol support Selezionare questa voce se la macchina effettua il masquerading o altra forma di NAT, e se si intende usare FTP. FTP causa alcuni problemi con il connection tracking quindi è necessario includere questo modulo per risolverli. Userspace queueing via NETLINK (EXPERIMENTAL) (NEW) Netfilter è in grado di accodare e passare i pacchetti allo userspace. Il dispositivo netlink può poi essere utilizzato per accedere a questi dati. Iptables support (required for filtering/masq/NAT) Selezionare questa voce per filtrare i pacchetti e/o per effettuare il NAT, utilizzando il nuovo tool iptables. limit match support Selezionare questa voce per poter limitare il numero di confronti. Utile se usato in combinazione con il modulo LOG per limitare la registrazione dei messaggi e per aggirare alcuni attacchi DoS (Denial of Service). MAC address match support Selezionare questa voce se si vogliono confrontare i pacchetti in base all'indirizzo ethernet associato. netfilter MARK match support Selezionare questa voce se si vogliono confrontare i pacchetti in base al valore 'nfmark'. Questo valore può essere impostato attraverso il target MARK (vedere iptables). Multiple port match support Selezionare questa voce se si vogliono confrontare i pacchetti TCP o UDP in base ad una serie di porte sorgenti o destinazione. Nota che normalmente una regola può confrontare solo un singolo intervallo di porte. TOS match support Selezionare questa voce se si vogliono confrontare i pacchetti in base ai campi TOS (Type Of Service) dei pacchetti IP. Connection state match support Selezionare questa voce se si vogliono confrontare i pacchetti in base all'appartenenza o meno ad una connessione tracciata (pacchetti precedenti). Se si decide di includere questo modulo nel kernel tutte le connessioni saranno automaticamente tracciate. Unclean match support (EXPERIMENTAL) Selezionare questa voce se si vogliono confrontare i pacchetti in base ad una serie di campi delle intestazioni IP, TCP, UDP, ICMP, utile per verificare la validità dei pacchetti. Owner match support (EXPERIMENTAL) Selezionare questa voce se si vogliono confrontare i pacchetti generati localmente in base a chi li ha creati: utente, gruppo, processo, sessione. Packet filtering Definisce una tabella 'filter', in cui è possibile inserire le regole per il filtraggio dei pacchetti. REJECT target support Selezionare questa voce se si vuole utilizzare il target REJECT, che permette di inviare un pacchetto ICMP error in risposta. MIRROR target support (EXPERIMENTAL) Selezionare questa voce se si vuole permettere ad una regola di rispedire indietro un pacchetto ricevuto. Full NAT Selezionare questa voce se si vuole implementare il masquerading, il port forwarding o altre forme di NAT (Network Address Translation). Queste forme di NAT si possono impostare utilizzando iptables e l'opzione '-t nat'. MASQUERADE target support Selezionare questa voce se si desidera utilizzare questa forma specializzata di mascheramento, implementata specificatamente per supportare i collegamenti PPP dialup. REDIRECT target support Selezionare questa voce se si desidera utilizzare il proxy trasparente, un'altra forma di NAT. Packet mangling Selezionare questa voce se si vogliono manipolare i pacchetti, ossia modificare i campi delle intestazioni. TOS target support Selezionare questa voce se si vogliono creare delle regole nella tabella 'mangle' che possano alterare i bit TOS (Type Of Service) dei pacchetti. MARK target support Selezionare questa voce per aggiungere un target 'MARK' che permetta di creare nella tabella 'mangle' delle regole che siano in grado di alterare il campo nfmark associato ai pacchetti. Utile per cambiare l'instradamento (routing) dei pacchetti. Utilizzato in particolare per lo shaping, controllo del traffico. LOG target support Selezionare questa voce per aggiungere un target 'LOG' che permetta di creare delle regole che registrino le intestazioni dei pacchetti. Se si decide di includere queste voci come moduli, e quindi di non includerle direttamente nel kernel, allora nella directory /lib/modules/2.x.xx/ipv4/ dovrebbero essere presenti tutti i seguenti moduli o quasi dato che alcuni sono ancora sperimentali: ip_conntrack.o ip_conntrack_ftp.o ip_nat_ftp.o ip_queue.o ip_tables.o ipt_LOG.o ipt_MARK.o ipt_MASQUERADE.o ipt_MIRROR.o ipt_REDIRECT.o ipt_REJECT.o ipt_TOS.o ipt_limit.o ipt_mac.o ipt_mark.o ipt_multiport.o ipt_owner.o ipt_state.o ipt_tos.o ipt_unclean.o iptable_filter.o iptable_mangle.o iptable_nat.o 5. iptables 5.1. Introduzione La seconda novità riguarda il tool designato per impostare le regole di filtraggio che è ora iptables. Questo programma sostituisce ipchains, che comunque sarà ancora supportato, e si integra e adegua alle novità introdotte con l'infrastruttura Netfilter (tabelle, moduli, ...). 5.2. Differenze rispetto alle versioni 2.0 e 2.2 del kernel La caratteristica principale introdotta è la modularità, in passato con ipchains si impostavano tutte le regole riguardanti non solo il filtraggio ma anche il mascheramento, i bit TOS (Type of Service), il log dei pacchetti rendendo difficile lo sviluppo e l'impostazioni delle regole. Ora invece è possibile caricare solo i moduli che si intendono utilizzare e in qualsiasi momento. Si potranno inoltre aggiungerne di nuovi sviluppati ad esempio per svolgere compiti precisi, ciò amplia le possibilità e facilita l'introduzione di nuove caratteristiche ed opzioni. 5.2.1. Tabelle Con Netfilter, per migliorare e facilitare le impostazioni delle regole, sono state introdotte le seguenti tre tabelle che si possono gestire e impostare correttamente solo con iptables: · filter · nat · mangle filter Tabella contenente inizialmente le tre catene preesistenti INPUT, FORWARD e OUTPUT. Tutte le regole riguardanti il filtraggio dovranno essere inserite in questa tabella. nat Tutte le regole riguardanti masquerading, redirezione, port forwarding, proxy trasparente che ora sono raggruppate sotto il termine NAT (Network Address Translation) dovranno essere inserite all'interno di questa tabella che contiene le seguenti catene PREROUTING, POSTROUTING e OUTPUT. mangle In quest'ultima tabella invece si dovranno inserire le regole riguardanti il "manipolamento" dei pacchetti (bit TOS, marcamento dei pacchetti, ...). Le catene disponibili sono: PREROUTING e OUTPUT. Queste tabelle possono essere richiamate con l'opzione '-t' (es. '-t nat'). Non è necessario specificare la tabella filter con '-t filter' in quanto è quella di default. 5.2.2. Criteri per il filtraggio I criteri per il filtraggio sono aumentati rispetto ad ipchains e si può ora filtrare in base a: · interfaccia · indirizzo sorgente e destinazione · numero di porta · indirizzo MAC · protocollo IP · flag dei pacchetti · opzioni tcp interfaccia E' possibile filtrare i pacchetti in base all'interfaccia di ingresso (-i) e di uscita (-o). Rispetto ad ipchains ora l'opzione '-i' serve per specificare esclusivamente l'interfaccia di ingresso, per quella di uscita è necessario utilizzare l'opzione '-o'. indirizzo sorgente e destinazione Come in ipchains è possibile filtrare i pacchetti in base all'indirizzo sorgente e/o quello di destinazione. numero di porta Anche in questo caso nulla di nuovo rispetto ad ipchains tranne per il fatto che ora è necessario indicare la porta (numero o nome) specificando esplicitamente l'opzione --sport o --dport. indirizzo MAC E' possibile filtrare anche in base all'indirizzo fisico di un'interfaccia ethernet. protocollo IP E' possibile indicare nelle proprie regole il tipo di protocollo: TCP, UDP, ICMP. flag dei pacchetti I pacchetti che transitano hanno dei flag (SYN, RST, FIN, ...) che possono essere utilizzate nelle regole di filtraggio. Particolarmente interessante è il flag SYN utilizzato per richiedere una connessione. opzioni tcp E' possibile filtrare i pacchetti tcp anche in base alle opzioni presenti. 5.2.3. Obiettivi Per quanto riguarda gli obiettivi (target) ora sono disponibili: · ACCEPT · DROP · REJECT · QUEUE · RETURN · MIRROR · LOG · SNAT, DNAT, MASQUERADE ACCEPT E' utilizzata in una regola per accettare i pacchetti che la soddisfano, può essere usata inoltre anche come tattica (policy) di una catena. DROP Sostituisce DENY presente in ipchains e come scopo ha sempre quello di scartare il pacchetto che soddisfa la regola. Anche questo obiettivo può essere utilizzato come tattica. REJECT Stessa funzione di DROP con la differenza che viene inviato un pacchetto di errore ('port unreachable') all'altra macchina. QUEUE Utilizzato per accodare i pacchetti per elaborazioni userspace. RETURN Se la catena in cui si trova la regola con l'obiettivo RETURN è stata definita dall'utente allora la RETURN causa il ritorno alla catena precedente, altrimenti se la catena è predefinita (INPUT, OUTPUT, ...) viene eseguita la tattica. MIRROR Questo obiettivo è utilizzato per rispedire un pacchetto alla macchina che lo ha inviato. LOG Questo obiettivo permette di registrare i pacchetti che soddisfano la regola, consente inoltre di specificare diverse opzioni per migliorare la gestione e la leggibilità. Sostituisce e completa l'opzione '-l' utilizzata con ipchains. SNAT, DNAT, MASQUERADE Questi obiettivi sostituiscono e completano l'obiettivo MASQ presente in ipchains. Vedi capitolo sul NAT (Network Address Translation). Per indicare questi obiettivi come per ipchains è necessario utilizzare il comando '-j' (es. -j ACCEPT). 5.2.4. Varie Le operazioni classiche sono rimaste invariate rispetto ad ipchains, ci sono comunque le seguenti differenze: · I nomi delle catene create con -N devono essere in minuscolo per distinguerle da quelle predefinite (INPUT, FORWARD, OUTPUT), da scrivere sempre in maiuscolo. Es. iptables -N logdrop. · Non esiste più la policy DENY è stata sostituita con DROP. · La lunghezza dei nomi delle catene ora può essere di max. 30 caratteri, con ipchains il limite massimo è di 8 caratteri. · L'opzione -i serve a specificare esclusivamente l'interfaccia di input, -o l'interfaccia di output. · Le porte UDP e TCP devono essere specificate utilizzando --sport (--source-port) o --dport (--destination-port) a seconda dei casi. · Il flag -y ora deve essere indicato usando --syn e deve seguire '-p tcp'. · L'opzione -C per i test non è stata ancora implementata. · Il target MASQ e le opzioni '--masquerade' e '--set' non esistono più, vedere NAT. · Per impostare il port forwarding, il proxy trasparente è necessario utilizzare la tabella NAT e l'obiettivo DNAT. · Per impostare i bit TOS (Type Of Service) vedere tabella mangle e TOS. · Non è più possibile specificare -l per loggare i messaggi, esiste un modulo separato (LOG) che si occupa ora della registrazione. · L'opzione '-b' ('--bidirectional') non è più disponibile. 5.3. Compilare e installare iptables iptables è disponibile in formato bz2 al seguente indirizzo http://netfilter.kernelnotes.org <http://netfilter.kernelnotes.org>. Sono disponibili anche i formati rpm e deb, ma è necessario visitare il sito della propria distribuzione Linux. Una volta completato il download è necessario assicurarsi di avere nella directory /usr/src/linux/ gli include del kernel e poi impartire i seguenti comandi: # bzip2 -d iptables-1.1.0.tar.bz2 # tar -xvf iptables-1.1.0.tar # cd iptables-1.1.0 # make # make install Se si ottengono dei messaggi di errore o se si vuole solo cambiare la directory in cui saranno collocati i comandi leggere il file di testo INSTALL. Se iptables sembra non funzionare correttamente controllare di aver eseguito il comando 'make install' e di aver caricato con insmod o modprobe tutti i moduli necessari (iptable_filter.o, ...). 5.4. Aggiornare iptables iptables è ancora in fase di sviluppo, quindi periodicamente sono rilasciate delle patch che risolvono alcuni errori riguardanti iptables stesso, gli altri moduli e la documentazione. L'ultima versione disponibile di iptables al momento è la 1.1.0, la documentazione invece è alla versione 1.0.1. Per aggiornare è sufficiente eseguire le seguenti operazioni: 1. Accedere al server CVS di SAMBA come utente 'anonymous': cvs -d :pserver:cvs@cvs.samba.org:/cvsroot login 2. Quando è richiesta la password digitare 'cvs' 3. Verificare il codice utilizzato: cvs -d :pserver:cvs@cvs.samba.org:/cvsroot co netfilter 4. Per effettuare l'aggiornamento vero e proprio utilizzare il seguente comando: cvs update -d -P Si possono consultare le patch, la documentazione aggiornata, una lista TODO delle cose ancora da implementare, utilizzando anche il web, è sufficiente visitare l'indirizzo cvs.samba.org/cgi- bin/cvsweb/netfilter/ <http://cvs.samba.org/cgi- bin/cvsweb/netfilter/>. 5.5. Documentazione, mailing list E' possibile consultare le complete manpage con il comando: # man iptables Sono comunque disponibili le "Rusty's Unreliable Guides", quattro documenti completi che introducono ai concetti di rete, al filtraggio dei pacchetti, al mascheramento e alla realizzazione dei moduli di estensione. · Networking Concepts HOWTO · Linux 2.4 Packet filtering HOWTO · Linux 2.4 NAT HOWTO · Linux netfilter hacking HOWTO I suddetti documenti si trovano in vari formati (SGML, TXT, PS) al seguente indirizzo: http://netfilter.kernelnotes.org <http://netfilter.kernelnotes.org>. Sempre a questo indirizzo si trovano due link alle mailing list ufficiali di netfilter. 6. Filtraggio Il filtraggio sotto Linux 2.4 si basa come nelle versioni precedenti sui concetti di catene (chain), obiettivi (target), tattiche (policy). Inizialmente sono disponibili tre catene predefinite: INPUT, FORWARD, OUTPUT (tabella filter). INPUT Tutti i pacchetti destinati esclusivamente alla macchina firewall saranno sottoposti alle regole contenute nella catena INPUT. +--+ |PC|--+ ==> +---+ <===== +--+ |_____| |_______ INTERNET +--+ | +---+ |PC|--+ +--+ LAN FIREWALL FORWARD Tutti i pacchetti destinati non alla macchina firewall ma ad una delle macchine della rete locale o provenienti dalla rete locale e diretti verso l'esterno (non al firewall) saranno sottoposti alle regole della catena FORWARD. +--+ |PC|--+ <== +---+ <===== +--+ |_____| |_______ INTERNET +--+ | +---+ |PC|--+ ==> =====> +--+ LAN FIREWALL OUTPUT Tutti i pacchetti generati dalla macchina firewall e in uscita saranno sottoposti alle regole della catena OUTPUT. +--+ |PC|--+ <== +---+ ===> +--+ |_____| |_______ INTERNET +--+ | +---+ |PC|--+ +--+ LAN FIREWALL Ciascuna catena consiste di una tattica (policy), e di una o più regole che stabiliscono quali pacchetti sono accettati e quali no. Una regola si compone in genere di una serie di caratteristiche che servono ad individuare un pacchetto e da un obiettivo (target) che indica cosa fare del pacchetto se la regola è soddisfatta. L'obiettivo può corrispondere ad ACCEPT (pacchetto accettato), DROP (pacchetto scartato), REJECT (pacchetto rifiutato). Una catena si può rappresentare in questo modo (qui prendiamo ad esempio la catena INPUT): INPUT +--------------+ | | Regola 1 | | ---------------- | | Regola 2 | | ---------------- V | Regola 3 | ---------------- Tattica Tutti i pacchetti che arrivano dalla rete e destinati al firewall saranno sottoposti, in questo caso, a ciascuna regola contenuta nella catena INPUT in ordine. Se la Regola 1 non è soddisfatta si prosegue con la successiva, se una regola (es. Regola 2) è soddisfatta allora il pacchetto è accettato, scartato o rifiutato (questa informazione è contenuta nella regola). Se nessuna regola è soddisfatta allora si applica la tattica (policy), che non dice altro a sua volta se accettare, scartare o rifiutare. I pacchetti che viaggiano nella rete contengono un insieme di informazione molto utili come ad esempio indirizzo sorgente (indirizzo di chi ha inviato il pacchetto), indirizzo destinazione (indirizzo a cui il pacchetto è destinato), tipo di pacchetto (TCP, UDP, ICMP), porta sorgente e porta destinazione (FTP, TELNET, WWW, ...), ... Queste informazioni sono usate nelle regole per stabilire quali pacchetti sono da accettare e quali da scartare. Ad esempio se non si desidera che qualcuno dall'esterno possa effettuare un telnet su una macchina della LAN è necessario creare una regola nella tabella filter, catena FORWARD, che filtri, rifiuti i pacchetti destinati alla rete locale, aventi come porta destinazione la porta telnet. iptables -A FORWARD -p tcp -i eth0 -o eth1 --dport telnet -j DROP ^^^^^^^^^^ ^^^^^^ ^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^ ^^^^^^^ | | | | | | | | | +- se la regola è soddisfatta | | | | scarta (DROP) il pacchetto | | | +- porta dest. del pacchetto (telnet) | | +---- interfacce ingresso e uscita del pacchetto | + protocollo tcp + aggiungi regola alla catena FORWARD Con questa nuova versione come abbiamo visto il tool incaricato di impostare le regole di filtraggio nel kernel è iptables, anche se è ancora possibile usare ipfwadm e ipchains. Questo modulo si occupa di fornire le operazioni di base per la creazione, gestione delle catene e delle regole. 6.1. Operazioni sulle catene Segue un elenco delle operazioni che permettono di creare, modificare, cancellare le catene: · Crea una nuova catena (-N) ipchains: ipchains -N nuova (max. 8 caratteri) iptables: iptables -N nuova (max. 30 caratteri) · Cancella una catena vuota, senza regole (-X) ipchains: ipchains -X nuova iptables: iptables -X nuova · Cambia la tattica (policy) delle catene predefinite (-P) ipchains: ipchains -P input DENY iptables: iptables -P INPUT DROP · Mostra elenco delle regole di una catena (-L) ipchains: ipchains -L iptables: iptables -L · Svuota una catena di tutte le sue regole (-F) ipchains: ipchains -F output iptables: iptables -F OUTPUT · Azzera i contatori (pacchetti e byte) di tutte le regole di una catena (-Z) ipchains: ipchains -Z input iptables: iptables -Z INPUT NOTA 1: se non si specifica una catena con le opzioni '-L','-X','-F','-Z' si intenderanno tutte le catene. Esempio: # Rimuovi tutte le regole della catena INPUT iptables -F INPUT # Rimuovi tutte le regole presenti in TUTTE le catene iptables -F NOTA 2: l'opzione -L può essere utilizzata inoltre per visualizzare tutte le catene o una sola (se si desiderano anche i numeri di linea utilizzare l'opzione '--line-numbers'): # iptables -L Chain INPUT (policy ACCEPT) target prot opt source destination DROP tcp -- anywhere anywhere tcp dpt:telnet Chain FORWARD (policy ACCEPT) target prot opt source destination Chain OUTPUT (policy ACCEPT) target prot opt source destination # iptables -L INPUT Chain INPUT (policy ACCEPT) target prot opt source destination DROP tcp -- anywhere anywhere tcp dpt:telnet # iptables --line-numbers -L INPUT Chain INPUT (policy DROP) num target prot opt source destination 1 DROP tcp -- anywhere anywhere tcp dpt:telnet E' inoltre possibile visualizzare informazioni sul numero dei pacchetti sottoposti alle regole con l'opzione '-v' (o '--verbose') oppure ottenere contemporaneamente un elenco delle regole e l'azzeramento dei contatori: # iptables -v -L Chain INPUT (policy ACCEPT 0 packets, 0 bytes) pkts bytes target prot opt in out source destination 2 120 DROP tcp -- any any anywhere anywhere tcp dpt:telnet Chain FORWARD (policy ACCEPT 0 packets, 0 bytes) pkts bytes target prot opt in out source destination Chain OUTPUT (policy ACCEPT 0 packets, 0 bytes) pkts bytes target prot opt in out source destination # iptables -v -L -Z Chain INPUT (policy DROP 0 packets, 0 bytes) pkts bytes target prot opt in out source destination 2 120 DROP tcp -- any any anywhere anywhere tcp dpt:telnet Chain FORWARD (policy ACCEPT 0 packets, 0 bytes) pkts bytes target prot opt in out source destination Chain OUTPUT (policy ACCEPT 2 packets, 120 bytes) pkts bytes target prot opt in out source destination Zeroing chain `INPUT' Zeroing chain `FORWARD' Zeroing chain `OUTPUT' 6.2. Operazioni sulle regole Segue un elenco delle operazioni che permettono di inserire, cancellare, modificare le regole delle catene: · Appendi una nuova regola alla catena (-A) ipchains: ipchains -A input -p tcp --dport telnet -j REJECT iptables: iptables -A INPUT -p tcp --dport telnet -j REJECT · Inserisci una nuova regola alla catena (-I) # Inserisci una regola all'inizio della catena ipchains: ipchains -I input -p tcp --dport telnet -j REJECT iptables: iptables -I INPUT -p tcp --dport telnet -j REJECT · Sostituisci una regola presente in una determinata posizione (-R) # Sostituisci la seconda regola con la nuova ipchains: ipchains -R input 2 -p icmp --icmp-type ping -j DENY iptables: iptables -R INPUT 2 -p icmp --icmp-type ping -j DROP · Cancella una regola presente in una determinata posizione (-D) # Cancella la precedente regola (vedi -R) ipchains: ipchains -D input -p icmp --icmp-type ping -j DENY iptables: iptables -D INPUT -p icmp --icmp-type ping -j DROP # Cancella la terza regola della catena input ipchains: ipchains -D input 3 iptables: iptables -D INPUT 3 6.3. Operazioni di selezione Segue una lista delle opzioni che consentono di realizzare delle regole per filtrare i pacchetti: · interfaccia ('-i' e '-o' oppure '--in-interface' e '--out- interface') ipchains: ipchains -A forward -i eth0 -d $RETE_LOCALE -p icmp -j REJECT iptables: iptables -A FORWARD -i eth0 -o eth1 -p icmp -j REJECT NOTA: con ipchains si utilizzava l'opzione -i che in base all'obiettivo (input, output) indicava rispettivamente interfaccia di ingresso e interfaccia di uscita, per la catena forward indicava sempre e solo l'interfaccia di uscita. Si possono inoltre indicare tutte le interfacce di un certo tipo aggiungendo un '+' (es. ppp+). Per indicare tutte le interfacce NON uguali ad una certa interfaccia, ad esempio a ppp0, si può aggiungere un '!' prima del nome dell'interfaccia. '!' si legge "non uguale a " es.: iptables -A FORWARD -i ! ppp0 -j ACCEPT USO: -i, --in-interface [!] [name][+] -o, --out-interface [!] [name][+] · Indirizzo sorgente e/o destinazione ('-s' e '-o' oppure '--source' e '--destination') ipchains: ipchains -A input -s $RETE_LOCALE -d $RETE_ESTERNA -p icmp -j ACCEPT iptables: iptables -A INPUT -s $RETE_LOCALE -d $RETE_ESTERNA -p icmp -j ACCEPT USO: -s, --source [!] address[/mask] -d, --destination [!] address[/mask] · Protocollo tcp ('-p tcp' o '--protocol tcp') ipchains: ipchains -A input -p tcp -j ACCEPT iptables: iptables -A INPUT -p tcp -j ACCEPT NOTA: è possibile specificare inoltre le opzioni '--tcp-flags', '--tcp-option', e '--syn' oltre a '--sport' e '--dport'. USO: -p, --protocol [!] protocol · Porta sorgente e/o destinazione ('--sport' e '--dport' oppure '--source-port' e '--destination-port') ipchains: ipchains -A forward -p tcp -d 192.168.x.x telnet -j ACCEPT iptables: iptables -A FORWARD -p tcp -d 192.168.x.x --dport telnet -j ACCEPT NOTA: è possibile specificare anche un intervallo di porte (es. 21(ftp),22(ssh),23(telnet)). es. iptables -A INPUT -p tcp --dport ftp:telnet -j ACCEPT USO: --source-port [!] [port[:port]] --destination-port [!] [port[:port]] · flags tcp ('--tcp-flags') ipchains: non possibile iptables: iptables -A INPUT -p tcp --tcp-flags ALL SYN,ACK -j DROP NOTA: i flag sono SYN,ACK,FIN,RST,URG,PSH. La prima stringa è la maschera (flag che vuoi esaminare), la seconda indica quali dovrebbero risultare impostati. USO: --tcp-flags [!] mask comp · opzioni tcp ('--tcp-option') ipchains: non possibile iptables: iptables -A INPUT -p tcp --tcp-option 1 -j DROP USO: --tcp-option [!] number · Pacchetti richiesta connessione ('--syn') ipchains: ipchains -A input -p tcp -y -j DENY iptables: iptables -A INPUT -p tcp --syn -j DROP NOTA: '--syn' si può utilizzare solo con il protocollo tcp, ed è molto utile per impedire i tentativi di connessione verso il firewall o la propria rete locale. USO: [!] --syn · Protocollo udp ('-p udp' o '--protocol udp') ipchains: ipchains -A input -p udp -j ACCEPT iptables: iptables -A INPUT -p udp -j ACCEPT NOTA: è possibile specificare inoltre le opzioni '--sport', '--dport'. USO: -p, --protocol [!] protocol --source-port [!] [port[:port]] --destination-port [!] [port[:port]] · Protocollo icmp ('-p icmp' o '--protocol icmp') ipchains: ipchains -A input -p icmp -j ACCEPT iptables: iptables -A INPUT -p icmp -j ACCEPT NOTA: è possibile specificare inoltre l'opzione '--icmp-type' per indicare il tipo ICMP (es. '--icmp-type destination-unreachable', '--icmp-type 3', '--icmp-type 3/3'). Per una lista completa utilizzare 'iptables -p icmp -h'. USO: -p, --protocol [!] protocol --icmp-type [!] typename 6.4. Estensioni Oltre alle opzioni appena viste ci sono altre opzioni molto utili, disponibili come estensioni: · mac ('-m mac' o '--match mac') · limit ('-m limit' o '--match limit') · owner ('-m owner' o '--match owner') · state ('-m state' o '--match state') · multiport ('-m multiport' o '--match multiport') · unclean ('-m unclean' o '--match unclean') Vedere i capitoli corrispondenti per una completa descrizione. 7. NAT · insmod ipt_nat 7.1. Descrizione Questo modulo permette di sfruttare le nuove funzionalità introdotte sotto il termine NAT (Network Address Translation). Precedentemente con ipchains si utilizzava l'obiettivo '-j MASQ', ora questo non è più possibile in quanto è stato sostituito con i seguenti obiettivi: · MASQUERADE specifico per il caso di connessioni dialup (PPP). · SNAT (Source NAT) permette di alterare nei pacchetti l'indirizzo sorgente, il mascheramento è una forma specializzata di SNAT. Per quanto riguarda invece il port-forwarding è necessario utilizzare: · DNAT (Destination NAT) consente di alterare nei pacchetti l'indirizzo destinazione, ciò permette di implementare oltre al port-forwarding anche il proxy trasparente, il load-balancing, ... 7.2. Operazioni Prima di poter utilizzare una qualsiasi delle operazioni seguenti è necessario specificare l'opzione '-t nat', questa causa il caricamento del modulo ed è necessario ogni qual volta si vogliano effettuare operazioni di SNAT, DNAT, MASQUERADING. es. iptables -A PREROUTING -t nat ... La tabella nat contiene tre catene predefinite: · PREROUTING da utilizzare per il DNAT · POSTROUTING da utilizzare per il SNAT · OUTPUT da utilizzare per il DNAT sui pacchetti generati localmente. Queste catene sono disposte così: -----> PREROUTING --> Routing ------------------------------> POSTROUTING ----> DNAT | ^ SNAT | | | Routing | | | OUTPUT | DNAT | | +------ Processi locali ------+ Firewall Il filtraggio e il NAT sono distinti e in genere non è necessario preoccuparsi. DNAT è effettuato prima del routing e prima che i pacchetti siano filtrati. SNAT è effettuato dopo il routing e dopo che i pacchetti sono stati filtrati. 7.2.1. SNAT (Source NAT) SNAT permette di modificare il campo sorgente del pacchetto. Questo avviene in POSTROUTING ossia subito dopo la fase di routing, poco prima che il pacchetto sia inviato nella rete. Questa operazione è utilizzata principalmente per il mascheramento della connessione, e in particolare è specifica per indirizzi statici. In caso di indirizzi dinamici, connessioni dialup utilizzare MASQUERADE. Sono richieste le seguenti informazioni: tabella ('-t nat'), catena ('-A POSTROUTING'), obiettivo ('-j SNAT'), indirizzo sorgente che andrà a sostituire quello presente nel pacchetto ('--to' o '--to- source'). L'utilizzo dell'opzione '--to/--to-source' è il seguente: --to-source ipaddr[-ipaddr][:port-port] E' possibile anche specificare più di un indirizzo sorgente. Quindi se si desidera che ai pacchetti siano assegnati come indirizzo sorgente uno tra due o più indirizzi (es. 1.2.3.0 e 1.2.3.1) si può utilizzare: iptables -t nat -A POSTROUTING -o eth1 -j SNAT --to 1.2.3.0 --to 1.2.3.1 Si può inoltre specificare un'intervallo di indirizzi: iptables -t nat -A POSTROUTING -o eth1 -j SNAT --to 1.2.3.0-1.2.3.5 E anche una o un'intervallo di porte (è necessario specificare il protocollo tcp/udp): iptables -t nat -A POSTROUTING -p tcp --dport telnet -o eth1 -j SNAT --to 1.2.3.5:23 # -------------------------------------------------------------------------------- # Con il seguente comando indichiamo al kernel che a tutti i pacchetti in uscita # dall'interfaccia eth0 (-o eth0) deve sostituire l'indirizzo sorgente con quello # del firewall (es. 151.99.xxx.x). # -------------------------------------------------------------------------------- iptables -t nat -A POSTROUTING -o eth1 -j SNAT --to 151.99.xxx.x 7.2.2. MASQUERADE MASQUERADE è una forma di SNAT creata appositamente per gestire i collegamenti dialup (PPP). E' raccomandato utilizzare l'obiettivo MASQUERADE solo se l'indirizzo IP viene assegnato dinamicamente ad esempio da un provider. Se si possiede invece un indirizzo statico è necessario utilizzare l'obiettivo SNAT. Diversamente dal SNAT, se la linea dovesse interrompersi, i dati transitati e le connessioni saranno dimenticate, ciò è necessario per evitare problemi nel momento in cui ci si riconnetterà nuovamente al provider. NOTA: in questo caso il provider ci fornirà un nuovo indirizzo IP. Sono richieste le seguenti informazioni: tabella ('-t nat'), catena ('-A POSTROUTING'), interfaccia da cui usciranno i pacchetti ('-o ppp0'), obiettivo ('-j MASQUERADE'). Non è necessario specificare l'indirizzo sorgente, sarà utilizzato quello dell'interfaccia da cui usciranno i pacchetti. E' inoltre possibile specificare una o un'intervallo di porte (è necessario specificare anche il protocollo tcp/udp): --to-ports <port>[-<port>] Port (range) to map to. Segue un esempio di come mascherare tutti i pacchetti in uscita dall'interfaccia ppp0 con l'indirizzo assegnato ad esempio dal provider. # Carica il modulo NAT modprobe iptable_nat iptables -t nat -A POSTROUTING -o ppp0 -j MASQUERADE 7.2.3. DNAT (Destination NAT) DNAT permette di modificare il campo destinazione del pacchetto. Questo avviene in fase di PREROUTING ossia subito prima della fase di routing, appena il pacchetto arriva dalla rete. Sono richieste le seguenti informazioni: tabella ('-t nat'), catena (-A PREROUTING o -A OUTPUT), obiettivo ('-j DNAT'), interfaccia di provenienza ('-i eth0'), indirizzo che andrà a sostituire quello presente nel pacchetto ('--to'). L'utilizzo dell'opzione '--to/--to-destination' è il seguente: --to-destination ipaddr[-ipaddr][:port-port] Esempio: # -------------------------------------------------------------------------------- # Cambia l'indirizzo di destinazione in 192.168.0.6 # -------------------------------------------------------------------------------- iptables -t nat -A PREROUTING -i eth0 -j DNAT --to 192.168.0.6 E' possibile, come nel caso di SNAT, specificare più di un indirizzo destinazione. Se si desidera che ai pacchetti siano assegnati come indirizzo destinazione uno tra due o più indirizzi (es. 1.2.3.0 e 1.2.3.1) si può utilizzare: iptables -t nat -A PREROUTING -i eth0 -j DNAT --to 1.2.3.0 --to 1.2.3.1 Si può inoltre specificare un'intervallo di indirizzi e ottenere il cosiddetto load-balancing primitivo: # -------------------------------------------------------------------------------- # Tutti i pacchetti tcp destinati alla porta www e in ingresso dall'interfaccia eth0 # devono essere inviati verso le macchine 192.168.0.2 e 192.168.0.3. # -------------------------------------------------------------------------------- iptables -t nat -A PREROUTING -i eth0 -p tcp --dport www -j DNAT --to 192.168.0.2-192.168.0.3 +---+ |PC1|----+ +-- + | | Linux box +---+ | +---+<========= |MAC|----+-------|PC0|----O----- INTERNET +---+ | +---+\ | !! | \__________ eth0 +---+ | !! | +----+ |PC2|----+ !>>+-|WWW1| 192.168.0.2 +---+ !! | +----+ !! | +----+ !>>+-|WWW2| 192.168.0.3 +----+ LAN SERVERS Internet [rete locale] E anche una o un'intervallo di porte (è necessario specificare il protocollo tcp/udp): iptables -t nat -A PREROUTING -p tcp --dport www -i eth0 -j DNAT --to 192.168.0.5:8080 +---+ |PC1|----+ +-- + | | Linux box +---+ | +---+<========= |MAC|----+-------|PC0|----O----- INTERNET +---+ | +---+\ | !! | \__________ eth0 +---+ | !! | +---+ |PC2|----+ !>>+-|WWW| 192.168.0.5 porta 8080 +---+ | +---+ | +----+ +-|MAIL| +----+ LAN SERVERS Internet [rete locale] Esiste anche una forma specializzata di DNAT detta Redirezione che permette di redirigire il traffico verso una determinata porta del firewall stesso utilizzando l'obiettivo REDIRECT. E' più che altro una comodità, in quanto si può utilizzare allo stesso scopo anche il DNAT, ed è utile per implementare il proxy trasparente. Sono richieste le seguenti informazioni: tabella ('-t nat'), catena ('-A PREROUTING'), obiettivo ('-j REDIRECT'), interfaccia di provenienza ('-i eth0'), porta che andrà a sostituire quella presente nel pacchetto ('--to-port'). Esempio: # -------------------------------------------------------------------------------- # Invia i pacchetti diretti alla porta www verso il proxy squid che è in # ascolto sulla porta 3128 del firewall. # -------------------------------------------------------------------------------- iptables -t nat -A PREROUTING -i eth0 -p tcp --dport www -j REDIRECT --to-port 3128 +---+ pacchetto rediretto alla porta 3128 |PC1|----+ +-+ +---+ | | | | V | +---+ | +---+<========= |MAC|----+-------|PC0|----O----- INTERNET +---+ | +---+\ | \ +---+ | eth0 |PC2|----+ +---+ LAN Internet [rete locale] 7.3. Protocollo speciali (ftp, quake, irc) In alcuni casi il NAT potrebbe non funzionare correttamente, questo a causa di alcuni protocolli "particolari" (es. ftp, irc). Questo problema è presente anche con ipchains e la soluzione consiste nel realizzare dei moduli specifici per ciascuno di essi. Per ipchains esistono ip_masq_ftp, ip_masq_raudio, ip_masq_irc, ... Per iptables al momento sono disponibili moduli specifici per FTP (ip_conntrack_ftp.o e ip_nat_ftp.o) e da poco per IRC, mentre altri sono in fase di realizzazione. 8. Connection tracking · insmod ip_conntrack · Tipo: estensione (-m state) · Es.: iptables -A INPUT -p tcp -m state --state ESTABLISHED,RELATED -j ACCEPT 8.1. Descrizione Questo modulo è particolarmente interessante ed è una delle novità più importanti introdotte. Il suo ruolo è quello di tenere traccia delle connessioni stabilite e di indicare se un pacchetto appartiene o è relativo ad una di esse. Implementa quindi ciò che è comunemente definito "stateful firewall". Per connessioni si intendono impropriamente anche quelle UDP, ICMP che in realtà non prevedono un meccanismo di richiesta/conferma connessione ("three-way handshake"). Una volta caricato il modulo ip_conntrack.o appena viene stabilita una nuova connessione esso provvede a prendere nota delle informazioni più importanti (indirizzo sorgente, indirizzo destinazione, porta sorgente, porta destinazione ...) e a memorizzarle. E' in grado così per ogni pacchetto che giunge dalla rete o è generato dalla Linux box stessa di stabilire a quale delle seguenti categorie appartiene: · NEW · ESTABLISHED · RELATED · INVALID NEW Pacchetti che cercano di stabilire una nuova (NEW) connessione ESTABLISHED Pacchetti appartenenti ad una connessione esistente e nota. RELATED Pacchetti relativi ad una connessione esistente ma di cui non ne fanno parte, potrebbero essere pacchetti ICMP di errore o altro. INVALID Pacchetti non appartenenti a connessioni note, quindi in genere da rifiutare.. Quindi è possibile interrogare il "connection tracking" per conoscere che tipo di pacchetto è stato ricevuto (NEW,ESTABLISHED,RELATED,INVALID) e decidere l'azione da intraprendere (ACCEPT,DROP,...). A questo scopo è necessario specificare l'opzione 'm state --state' seguita da una o più degli stati appena descritti: NEW, ESTABLISHED, RELATED, INVALID. Esempio: # -------------------------------------------------------------------------------- # Interroghiamo il "connection tracking" e se il pacchetto appartiene ad una # connessione nota (ESTABLISHED) o è relativo (RELATED, es. ICMP error, ftp data, ...) # allora lo accettiamo (-j ACCEPT) # -------------------------------------------------------------------------------- iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT # -------------------------------------------------------------------------------- # Altrimenti lo scartiamo (-j DROP) # -------------------------------------------------------------------------------- iptables -A INPUT -j DROP Questo tipo di implementazione consente di rendere più semplice la realizzazione di un firewall e inoltre garantisce un maggior controllo sui pacchetti UDP e ICMP. UDP infatti diversamente da TCP è connection less (senza connessione) ciò comporta l'impossibilità ad esempio di utilizzare l'opzione '--syn' e quindi di averne un completo controllo. Naturalmente tenere traccia di tutte le connessioni, in particolare in caso di traffico notevole, può richiedere un maggior utilizzo di memoria e CPU, comunque in base a vari test condotti sembrano essere abbastanza contenuti. In caso si abbia a disposizione una banda larga e ci sia un traffico notevole da gestire la soluzione "classica", ossia che non utilizzi il connection tracking, garantisce in genere prestazioni migliori. Se non si intende utilizzare il "connection tracking" allora è necessario non compilare il modulo ip_conntrack.o nel kernel o caricarlo con insmod, questo per evitare che tenga traccia delle connessioni inutilmente. Il suo utilizzo è comunque obbligatorio se si intendono effettuare operazioni di NAT (masquerading, port forwarding ...) e può essere inoltre anche di aiuto per facilitare il filtraggio dei pacchetti. In alcuni casi si ritiene che questo meccanismo possa essere vulnerabile ad alcuni attacchi tra cui quelli DoS, è sempre possibile però utilizzare delle regole di filtraggio prima di quella contenente l'opzione '-m state --state ESTABLISHED,RELATED' per migliorare la protezione. Alcuni problemi noti e perfezionamenti sono già stati realizzati e sono in fase di testing. 8.2. Opzioni Non sono disponibili opzioni. 8.3. Esempi 8.3.1. Esempio 1 #!/bin/bash # Esempio 1 # Supponiamo che PC1 appartenga ad una rete locale e che vogliamo renderla # più sicura e protetta. # # +---+ . # |PC1|------+ # +---+ | # | # +---..... INTERNET # +---+ | # | |------+ # +---+ | # | # . # -------------------------------------------------------------------------------- # Carichiamo i moduli necessari se non compilati nel kernel (es. ip_conntrack) # -------------------------------------------------------------------------------- modprobe ip_conntrack modprobe ipt_REJECT # -------------------------------------------------------------------------------- # Svuotiamo le catene di tutte le regole # -------------------------------------------------------------------------------- iptables -F # -------------------------------------------------------------------------------- # OUTPUT # Accettiamo tutti i pacchetti riguardanti una connessione stabilita o relativa # -------------------------------------------------------------------------------- iptables -A OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT # -------------------------------------------------------------------------------- # I pacchetti di richiesta connessione o nuova connessione (NEW) accettati # sono solo quelli telnet,www, dns (tcp e udp) # Accettiamo inoltre anche i pacchetti in uscita dall'interfaccia lo # (localhost) # -------------------------------------------------------------------------------- iptables -A OUTPUT -o lo -j ACCEPT iptables -A OUTPUT -p tcp --dport telnet -m state --state NEW -j ACCEPT iptables -A OUTPUT -p tcp --dport domain -m state --state NEW -j ACCEPT iptables -A OUTPUT -p udp --dport domain -m state --state NEW -j ACCEPT iptables -A OUTPUT -p tcp --dport www -m state --state NEW -j ACCEPT # -------------------------------------------------------------------------------- # tutto il resto è rifiutato # -------------------------------------------------------------------------------- iptables -A OUTPUT -j REJECT # -------------------------------------------------------------------------------- # FORWARD # PC1 non è posto a protezione di una rete locale. # -------------------------------------------------------------------------------- iptables -A FORWARD -j DROP # -------------------------------------------------------------------------------- # INPUT - Accettiamo tutti i pacchetti che fanno parte di una connessione da # noi stabilita (ESTABLISHED) o che sono relativi (RELATED) come ad esempio # pacchetti ICMP di errore. # -------------------------------------------------------------------------------- iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT # -------------------------------------------------------------------------------- # il resto è scartato # -------------------------------------------------------------------------------- iptables -A INPUT -j DROP Il connection tracking rende tutto molto più semplice, con ipchains sarebbe necessario utilizzare invece questo script: #!/bin/bash # Esempio 1 # Supponiamo che PC1 appartenga ad una rete locale e che vogliamo renderla # più sicura e protetta. # # +---+ . # |PC1|------+ # +---+ | # | # +---..... INTERNET # +---+ | # | |------+ # +---+ | # | # . # -------------------------------------------------------------------------------- # Svuotiamo le catene di tutte le regole # -------------------------------------------------------------------------------- ipchains -F # -------------------------------------------------------------------------------- # OUTPUT - Accettiamo telnet, www, dns # Da questa macchina sarà consentito effettuare solo telnet e www # -------------------------------------------------------------------------------- ipchains -A output -i lo -j ACCEPT ipchains -A output -p tcp --dport telnet -j ACCEPT ipchains -A output -p tcp --dport domain -j ACCEPT ipchains -A output -p udp --dport domain -j ACCEPT ipchains -A output -p tcp --dport www -j ACCEPT # -------------------------------------------------------------------------------- # tutto il resto è vietato # -------------------------------------------------------------------------------- ipchains -A output -j REJECT # -------------------------------------------------------------------------------- # FORWARD # PC1 non è posto a protezione di una rete locale. # -------------------------------------------------------------------------------- ipchains -A forward -j REJECT # -------------------------------------------------------------------------------- # INPUT - Accettiamo tutti i pacchetti protocollo tcp che non siano di # richiesta connessione (pacchetti con flag SYN) e che non siano www, dns o # telnet. Modo classico. # -------------------------------------------------------------------------------- ipchains -A input -i lo -j ACCEPT ipchains -A input -p tcp ! -y --sport telnet -j ACCEPT ipchains -A input -p tcp ! -y --sport dns -j ACCEPT ipchains -A input -p udp --sport dns -j ACCEPT ipchains -A input -p tcp ! -y --sport www -j ACCEPT # -------------------------------------------------------------------------------- # tutto il resto è vietato # -------------------------------------------------------------------------------- ipchains -A input -j DENY 8.3.2. Esempio 2 #!/bin/bash # Esempio 2 # Supponiamo che PC1 sia ora un vero e proprio firewall posto a protezione # della rete locale. Accettiamo in questo caso tutte le richieste provenienti # dalla rete locale. # # +---+ . # | |------+ eth0 ppp0 # +---+ | | | # | \ +---+ / # +----|PC1|----..... INTERNET # +---+ | +---+ # | |------+ # +---+ | # | # . # -------------------------------------------------------------------------------- # Carichiamo i moduli necessari se non compilati nel kernel (es. ip_conntrack, ip_conntrack_ftp) # -------------------------------------------------------------------------------- modprobe ip_conntrack modprobe ip_conntrack_ftp # ... # -------------------------------------------------------------------------------- # Svuotiamo le catene di tutte le regole # -------------------------------------------------------------------------------- iptables -F # -------------------------------------------------------------------------------- # OUTPUT - In questo caso non è di grosso interesse # Possiamo comunque filtrare ciò che è generato dal FIREWALL e in uscita # -------------------------------------------------------------------------------- # -------------------------------------------------------------------------------- # FORWARD # PC1 ora è posto a protezione di una rete locale, quindi stabiliamo quali # pacchetti possono transitare e arrivare alla rete locale e quali # provenienti dalla rete locale uscire verso internet # -------------------------------------------------------------------------------- # -------------------------------------------------------------------------------- # Tutti i pacchetti appartenenti ad una connessione nota o relativi sono accettati # -------------------------------------------------------------------------------- iptables -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT # -------------------------------------------------------------------------------- # Qualsiasi nuova connessione (NEW) richiesta da una macchina della rete # locale verso internet, che quindi "entra" per l'interfaccia eth0, è accettata # -------------------------------------------------------------------------------- iptables -A FORWARD ! -i ppp0 -m state --state NEW -j ACCEPT # -------------------------------------------------------------------------------- # Tutto il resto è scartato # -------------------------------------------------------------------------------- iptables -A FORWARD -j DROP # -------------------------------------------------------------------------------- # INPUT # Qui stabiliamo quali pacchetti destinati esclusivamente al *firewall*, e # non alla rete locale, sono accettati. In questo esempio accettiamo solo i ping e # pacchetti provenienti dall'interfaccia lo. # -------------------------------------------------------------------------------- iptables -A INPUT -i lo -j ACCEPT iptables -A INPUT -p icmp --icmp-type ping -j ACCEPT # -------------------------------------------------------------------------------- # resto scartato # -------------------------------------------------------------------------------- iptables -A INPUT -j DROP 8.3.3. Esempio 3 #!/bin/bash # Esempio 3 # Supponiamo che PC1 sia ora un vero e proprio firewall posto a protezione # della rete locale. In questo caso restringiamo e accettiamo dalla rete locale # solo le richieste www, dns, telnet. Questo è solo un esempio e può essere # migliorato. # # +---+ . # | |------+ eth0 ppp0 # +---+ | | | # | \ +---+ / # +----|PC1|----..... INTERNET # +---+ | +---+ # | |------+ # +---+ | # | # . # -------------------------------------------------------------------------------- # Carichiamo i moduli necessari se non compilati nel kernel (es. ip_conntrack, ip_conntrack_ftp) # -------------------------------------------------------------------------------- modprobe ip_conntrack modprobe ip_conntrack_ftp # ... # -------------------------------------------------------------------------------- # Svuotiamo le catene di tutte le regole # -------------------------------------------------------------------------------- iptables -F # -------------------------------------------------------------------------------- # OUTPUT - In questo caso non è di grosso interesse # Possiamo comunque filtrare ciò che è generato dal FIREWALL e in uscita # -------------------------------------------------------------------------------- # -------------------------------------------------------------------------------- # FORWARD # Tutti i pacchetti che arrivano da internet (interfaccia di ingresso: ppp0) # appartenenti ad una connessione nota o relativi sono accettati # -------------------------------------------------------------------------------- iptables -A FORWARD -i ppp0 -m state --state ESTABLISHED,RELATED -j ACCEPT # -------------------------------------------------------------------------------- # Altrimenti se i pacchetti sono arrivati dall'interfaccia eth0 e quindi # dalla LAN e nuovi o di richiesta connessione (NEW) accettiamo solo # www, domain, telnet e ping. Accettiamo infine i pacchetti che appartengono # ad una connessione già stabilita (ESTABLISHED) o sono relativi. # -------------------------------------------------------------------------------- iptables -A FORWARD -i eth0 -p tcp --dport www -m state --state NEW -j ACCEPT iptables -A FORWARD -i eth0 -p tcp --dport domain -m state --state NEW -j ACCEPT iptables -A FORWARD -i eth0 -p udp --dport domain -m state --state NEW -j ACCEPT iptables -A FORWARD -i eth0 -p tcp --dport telnet -m state --state NEW -j ACCEPT iptables -A FORWARD -i eth0 -p icmp --icmp-type ping -m state --state NEW -j ACCEPT iptables -A FORWARD -i eth0 -m state --state ESTABLISHED,RELATED -j ACCEPT # -------------------------------------------------------------------------------- # Tutto il resto è scartato # -------------------------------------------------------------------------------- iptables -A FORWARD -j DROP # -------------------------------------------------------------------------------- # INPUT # Qui stabiliamo quali pacchetti destinati esclusivamente al *firewall*, e # non alla rete locale, sono accettati. In questo esempio accettiamo solo i ping # sia che provengano dalla rete locale che dalla rete internet (nota che qui non # si specificano -i e -o) oltre ai pacchetti provenienti dall'interfaccia lo. # -------------------------------------------------------------------------------- iptables -A INPUT -i lo -j ACCEPT iptables -A INPUT -p icmp --icmp-type ping -j ACCEPT # -------------------------------------------------------------------------------- # resto scartato # -------------------------------------------------------------------------------- iptables -A INPUT -j DROP # //////////////////////////////////////////////////////////////////////////////// # -------------------------------------------------------------------------------- # Impartendo il comando 'iptables -L -v' si ottiene il seguente risultato: # #Chain OUTPUT (policy ACCEPT) #target prot opt source destination #[root@localhost netfilter]# iptables -L -v #Chain INPUT (policy ACCEPT 0 packets, 0 bytes) # pkts bytes target prot opt in out source destination # 0 0 ACCEPT icmp -- any any anywhere anywhere icmp echo-request # 0 0 DROP all -- any any anywhere anywhere # #Chain FORWARD (policy ACCEPT 0 packets, 0 bytes) # pkts bytes target prot opt in out source destination # 0 0 ACCEPT all -- ppp0 any anywhere anywhere state RELATED,ESTABLISHED # 0 0 ACCEPT tcp -- eth0 any anywhere anywhere state NEW tcp dpt:www # 0 0 ACCEPT tcp -- eth0 any anywhere anywhere state NEW tcp dpt:domain # 0 0 ACCEPT udp -- eth0 any anywhere anywhere state NEW udp dpt:domain # 0 0 ACCEPT tcp -- eth0 any anywhere anywhere state NEW tcp dpt:telnet # 0 0 ACCEPT icmp -- eth0 any anywhere anywhere state NEW icmp echo-request # 0 0 ACCEPT all -- eth0 any anywhere anywhere state RELATED,ESTABLISHED # 0 0 DROP all -- any any anywhere anywhere # -------------------------------------------------------------------------------- # //////////////////////////////////////////////////////////////////////////////// 8.3.4. Esempio 4 In particolare nell'HOWTO Packet Filtering è presente il seguente esempio adatto per chi si connette al proprio ISP da casa via modem. insmod ip_contrack insmod ip_contrack_ftp iptables -N block iptables -A block -m state --state ESTABLISHED, RELATED -j ACCEPT iptables -A block -m state --state NEW -i ! ppp0 -j ACCEPT iptables -A block -j DROP iptables -A INPUT -j block iptables -A FORWARD -j block 9. LOG · Modulo: insmod ipt_LOG · Tipo: obiettivo (-j LOG) · Es.: iptables -A INPUT -p icmp -j LOG --log-level info --log- prefix "ICMP: " 9.1. Descrizione Questo modulo permette di gestire la registrazione dei pacchetti che transitano attraverso il firewall. Rispetto a ipchains che utilizza l'opzione '-l' ora si deve usare l'obiettivo '-j LOG'. Questa modifica ha consentito inoltre di introdurre due nuove opzioni che consentono di memorizzare i log in file diversi e di aggiungere una stringa di commento. 9.2. Opzioni Sono disponibili le seguenti opzioni: · --log-level · --log-prefix · --log-tcp-sequence · --log-tcp-options · --log-ip-options --log-level Questa opzione permette di specificare un nome di livello (debug, info, notice, warning, err, crit, alert, emerg) o il numero corrispondente (0-7). Configurando il file syslog.conf è possibile registrare le informazioni dei pacchetti in file differenti in base alle proprie esigenze, oppure direttamente sulla console. Ad esempio, con la Slackware, se si utilizza '--log-level info' o '--log-level notice' le informazioni dei pacchetti saranno memorizzate nel file /var/log/message, se si utilizza '--log-level debug' invece saranno registrate nel file /var/log/debug. Per ulteriori dettagli consultare il manuale di syslog.conf (man syslog.conf) e il file /etc/syslog.conf --log-prefix Questa opzione permette di specificare una stringa di max. 29 caratteri da inserire nel file di log (/var/log/messages) assieme al resto delle informazioni, usato per identificare rapidamente ciò che interessa. --log-tcp-sequence Registra i numeri di sequenza. Per default i numeri di sequenza (sequence number) non sono memorizzati (consigliato), se si desidera registrare queste informazioni (es. SEQ=3431266037) utilizzare '--log-tcp-sequence'. --log-tcp-options Registra le opzioni tcp, nel file si troverà una stringa simile alla seguente: OPT (020405B40000080A0004413D0000000001030300) --log-ip-options Registra le opzioni ip (flag). Per ottenere un elenco con relativa breve spiegazione utilizzare il comando: iptables -j LOG --help 9.3. Utilizzo Per registrare le intestazioni dei pacchetti è necessario specificare il tipo di pacchetto, l'obiettivo LOG ('-j LOG') ed opzionalmente anche il livello ('--log-level') e la stringa che deve essere associata ('--log-prefix'). Esempio: iptables -A INPUT -p tcp --dport telnet --syn -j LOG --log-level info \ --log-prefix "Firewall (telnet request) -->" In questo caso i pacchetti tcp destinati alla porta telnet del firewall sono registrati nel file associato a info (vedere syslog.conf - man syslog.conf), nel caso della Slackware è /var/log/messages, e "contrassegnati" con la stringa Firewall (telnet request) -->. In alcuni casi è necessario, oltre a registrare le informazioni di un pacchetto, anche scartarlo (o accettarlo): iptables -A INPUT -s 192.168.0.0/24 -j LOG iptables -A INPUT -s 192.168.0.0/24 -j DROP Questa soluzione in realtà non è utilizzata in quanto ripetitiva, è meglio creare delle catene specifiche ad esempio logdrop, logaccept e poi utilizzarle quando necessario. iptables -N logdrop iptables -A logdrop -j LOG --log-level info --log-prefix "FIREWALL logdrop: " iptables -A logdrop -j DROP iptables -N logaccept iptables -A logaccept -j LOG --log-level info --log-prefix "FIREWALL logaccept: " iptables -A logaccept -j ACCEPT iptables -A INPUT -s 192.168.0.0/24 -j logdrop Il meccanismo di LOG attuale non è ideale per tutti i casi, per questo motivo sono già state proposte nuovi soluzioni che dovrebbero sostituirlo e consentire un utilizzo più comodo. 9.4. Formato della registrazione Il formato della registrazione in base al comando precedentemente indicato è il seguente: Jun 5 17:35:49 localhost kernel: Firewall (telnet request) -->IN=lo OUT= MAC=00:00:00:00:00:00:00:00:00:00:00:00:08:00 SRC=127.0.0.1 DST=127.0.0.1 LEN=60 TOS=0x00 PREC=0x00 TTL=64 ID=0 DF PROTO=TCP SPT=1061 DPT=23 WINDOW=30816 RES=0x00 SYN URGP=0 Firewall (telnet request) --> = stringa inserita con l'opzione --log-prefix IN = interfaccia di ingresso OUT = interfaccia di uscita SRC = indirizzo IP sorgente del pacchetto DST = indirizzo IP destinazione del pacchetto LEN = dimensione del pacchetto (LENGTH) TOS = bit TOS (Type Of Service) PREC = Precedence TTL = Time to Live ID = Identification (necessario per stabilire a quale pacchetto appartiene un frammento) DF = Don't Fragment (bit che segnala di non frammentare il pacchetto) SPT = porta sorgente DPT = porta destinazione PROTO = protocollo (tcp/udp/icmp) WINDOW= window size (indica quanti byte possono essere spediti a partire dal byte confermato) RES = SYN...= flag impostati (URG/ACK/PSH/RST/SYN/FIN) URGP = urgent pointer (scostamento in byte utile per trovare i dati urgenti) Nel caso di pacchetti ICMP sono presenti oltre ad alcuni dei campi precedenti anche i seguenti: TYPE = tipo pacchetto ICMP CODE = codice pacchetto ICMP [..SRC=.. DST=..] = informazioni sul pacchetto che ha causato la risposta ICMP E' consigliato utilizzare LOG assieme a limit in quanto così è possibile stabilire dei limiti al numero di registrazioni, evitando casi di flood, ossia un numero esagerato di registrazioni che potrebbero causare l'esaurimento dello spazio su disco. # -------------------------------------------------------------------------------- # Registra i pacchetti (-j LOG) che transitano per la catena FORWARD (-A FORWARD) e # aggiungi la stringa "FORWARD: " (--log-prefix "FORWARD: ". # Utilizza inoltre i parametri di default di limit (3/h, burst di 5 pacchetti) per # limitare il numero di registrazioni. # -------------------------------------------------------------------------------- iptables -A FORWARD -m limit -j LOG --log-prefix "FORWARD: " # -------------------------------------------------------------------------------- # Come esempio precedente solo che si stabilisce un limite alle registrazioni pari a # 5 pacchetti ogni ora (burst rimane invariato, 5 pacchetti). # -------------------------------------------------------------------------------- iptables -A FORWARD -m limit --limit 5/h -j LOG --log-prefix "FORWARD: " L'esempio 1, riguardante il connection tracking, può essere modificato in questo modo: #!/bin/bash # Esempio 1 # Supponiamo che PC1 appartenga ad una rete locale e che vogliamo renderla # più sicura e protetta. # # +---+ . # |PC1|------+ # +---+ | # | # +---..... INTERNET # +---+ | # | |------+ # +---+ | # | # . # -------------------------------------------------------------------------------- # Carichiamo i moduli necessari se non compilati nel kernel (es. ip_conntrack) # -------------------------------------------------------------------------------- modprobe ip_conntrack modprobe ipt_REJECT # -------------------------------------------------------------------------------- # Svuotiamo le catene di tutte le regole # -------------------------------------------------------------------------------- iptables -F # -------------------------------------------------------------------------------- # OUTPUT # Accettiamo tutti i pacchetti riguardanti una connessione stabilita o relativa # -------------------------------------------------------------------------------- iptables -A OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT # -------------------------------------------------------------------------------- # I pacchetti di richiesta connessione o nuova connessione (NEW) accettati # sono solo quelli telnet,www, dns (tcp e udp). # Accettiamo anche i pacchetti in uscita dall'interfaccia lo (localhost). # -------------------------------------------------------------------------------- iptables -A OUTPUT -o lo -j ACCEPT iptables -A OUTPUT -p tcp --dport telnet -m state --state NEW -j ACCEPT iptables -A OUTPUT -p tcp --dport domain -m state --state NEW -j ACCEPT iptables -A OUTPUT -p udp --dport domain -m state --state NEW -j ACCEPT iptables -A OUTPUT -p tcp --dport www -m state --state NEW -j ACCEPT # -------------------------------------------------------------------------------- # tutto il resto è rifiutato # -------------------------------------------------------------------------------- iptables -A OUTPUT -j REJECT # -------------------------------------------------------------------------------- # FORWARD # PC1 non è posto a protezione di una rete locale. # -------------------------------------------------------------------------------- iptables -A FORWARD -j DROP # -------------------------------------------------------------------------------- # INPUT - Accettiamo tutti i pacchetti che fanno parte di una connessione da # noi stabilita (ESTABLISHED) o che sono relativi (RELATED) come ad esempio # pacchetti ICMP di errore. # -------------------------------------------------------------------------------- iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT # -------------------------------------------------------------------------------- # Registriamo i dati riguardanti i pacchetti che non sono appartenenti a connessioni note # o relativi. Nel file questi dati saranno evidenziati dalla stringa "FW ricevuto:" # Inoltre saranno registrati solo un numero limitato di pacchetti (-m limit). # Le opzioni di default di limit sono (--limit 3/hour --limit-burst 5). # -------------------------------------------------------------------------------- iptables -A INPUT -m limit -j LOG --log-level info --log-prefix "FW ricevuto: " # -------------------------------------------------------------------------------- # il resto è scartato # -------------------------------------------------------------------------------- iptables -A INPUT -j DROP 10. LIMIT · Modulo: insmod ipt_limit · Tipo: estensione (-m limit) · Es.: iptables -A INPUT -p tcp -m limit --limit 3/h -j LOG 10.1. Descrizione Questo modulo permette di restringere il numero di confronti e per sopprimere i messaggi di log. In ipchains non è implementata. Può essere utilizzato per limitare il numero di registrazioni dei log oppure per evitare alcuni Denial of Service (DoS), i port scanner sospetti, e i ping della morte (Ping of death). 10.2. Opzioni · --limit · --limit-burst --limit Questa opzione permette di specificare il numero confronti che devono essere effettuati in certo periodo di tempo. E' possibile specificare il numero di confronti da effettuare ogni secondo ('/second' o '/s'), oppure ogni minuto ('/minute' o '/m'), ogni ora ('/hour' o '/h'), ogni giorno ('/day' o '/d'). --limit-burst Questa opzione permette di specificare il burst, ossia il numero di pacchetti che devono essere confrontati la prima volta, e quanti ne devono essere recurati se ad ogni scadenza non sono pervenuti. Quindi se specifichiamo un limite di 1 pacchetto al minuto con burst di 5 la prima volta saranno confrontati 5 pacchetti, poi uno solo ogni minuto. Inoltre per ogni minuto che non si ricevono pacchetti allora ne sarà recuperato uno nel burst. I parametri di default sono --limit 3/hour --limit-burst 5 E' importante fare attenzione a questa enstensione in quanto si potrebbero causare involontariamente dei DoS, in genere è comunque raccomandato utilizzarla con l'obiettivo LOG. 10.3. Esempi # -------------------------------------------------------------------------------- # Appendiamo alla catena INPUT (-A INPUT) una regola che limiti (-m limit), usando # i parametri di default, le registrazioni. # -------------------------------------------------------------------------------- iptables -A INPUT -m limit -j LOG # -------------------------------------------------------------------------------- # Appendiamo alla catena FORWARD (-A FORWARD) una regola che limiti (-m limit), # le registrazioni accettando 1 pacchetto ogni ora (--limit 1/h), con burst # pari a 3 pacchetti (--limit-burst 3). # -------------------------------------------------------------------------------- iptables -A FORWARD -m limit --limit 1/h --limit-burst 3 -j LOG # -------------------------------------------------------------------------------- # Appendiamo una regola che accetti solo 1 pacchetto al secondo (burst di 5) # di tipo SYN (richiesta connessione tcp). # -------------------------------------------------------------------------------- iptables -A FORWARD -p tcp --syn -m limit --limit 1/s -j ACCEPT # -------------------------------------------------------------------------------- # Questo comando aggiunge una regola il cui scopo è di limitare il numero di pacchetti # RST da accettare (1 al secondo con burst di 5). # Utile nel caso qualcuno cerchi di effettuare un port-scanning. # -------------------------------------------------------------------------------- iptables -A INPUT -p tcp --tcp-flags SYN,ACK,FIN,RST RST -m limit --limit 1/s -j ACCEPT # -------------------------------------------------------------------------------- # Aggiungiamo una regola alla catena INPUT (-j INPUT) che accetti 1 pacchetto # icmp echo-request (ping) ogni secondo con burst di 5 pacchetti. # -------------------------------------------------------------------------------- iptables -A INPUT -p icmp --icmp-type echo-request -m limit --limit 1/s -j ACCEPT 11. Multiport · Modulo: insmod ipt_multiport.o · Tipo: estensione (-m multiport) · Es.: iptables -A INPUT -p tcp -m multiport --dports telnet,www,dns -j ACCEPT 11.1. Descrizione Questo modulo permette di specificare sulla stessa riga di comando una o più porte anche non consecutive (es. 21,80,8080), altrimenti, non utilizzandolo, è possibile indicare solo una porta o un intervallo di porte consecutive (es. 21:23 che specifica porte 21,22,23). NOTA: si può utilizzare solo con i protocolli tcp e udp. 11.2. Opzioni · --source-ports port(,port,port...) o --sports · --destination-ports port(,port,port...) o --dports · --ports port(,port,port...) --sports Permette di specificare più porte sorgenti --dports Permette di specificare più porte destinazione --ports Permette di specificare più porte, sorgenti e destinazione 11.3. Esempi #!/bin/bash # # Esempio 1 # PORTE_TCP=telnet,www,dns PORTE_UDP=dns # -------------------------------------------------------------------------------- # OUTPUT # -------------------------------------------------------------------------------- iptables -A OUTPUT -o lo -j ACCEPT iptables -A OUTPUT -m multiport -p tcp --dports $PORTE_TCP -j ACCEPT iptables -A OUTPUT -m multiport -p udp --dports $PORTE_UDP -j ACCEPT # -------------------------------------------------------------------------------- # accettiamo anche i pacchetti icmp necessari (vedi cap. ICMP) # -------------------------------------------------------------------------------- iptables -A OUTPUT -j icmp-accept iptables -A OUTPUT -j REJECT # -------------------------------------------------------------------------------- # FORWARD # -------------------------------------------------------------------------------- iptables -A FORWARD -j DROP # -------------------------------------------------------------------------------- # INPUT # -------------------------------------------------------------------------------- iptables -A INPUT -i lo -j ACCEPT iptables -A INPUT -p tcp ! --syn --sports $PORTE_TCP -j ACCEPT iptables -A INPUT -p udp --sports $PORTE_UDP -j ACCEPT iptables -A INPUT -j icmp-accept iptables -A INPUT -j DROP 12. Unclean · Modulo: insmod ipt_unclean · Tipo: estensione (-m unclean) · Es.: iptables -A INPUT -i eth0 -m unclean -j DROP 12.1. Descrizione Questo modulo permette di riconoscere una serie di pacchetti che per varie ragioni sono malformati o inusuali. Ecco un elenco dei pacchetti che il modulo è in grado di riconoscere: · Pacchetti troppo "corti" per avere un'intestazione ICMP/UDP/TCP completa. · Pacchetti TCP e UDP con porte sorgente e destinazione uguali a zero (illegale). · Pacchetti con combinazioni illegali di flag TCP · Pacchetti con opzioni TCP e IP di lunghezza zero (illegale) o eccessiva, o con opzioni presenti dopo l'opzione END-OF-OPTIONS · Frammenti con lunghezza o offset illegali (es. Ping della Morte). In genere questi tipi di pacchetti devono essere scartati (DROP). Questo modulo al momento è ancora sperimentale, quindi non dovrebbe essere utilizzato se non per dei test. 12.2. Opzioni Non sono disponibili opzioni. Esempi #!/bin/bash # # Esempio # # -------------------------------------------------------------------------------- # Appendiamo una regola alla catena INPUT (-A INPUT) che per tutti i # pacchetti provenienti dall'interfaccia ppp0 (-i ppp0) malformati (-m unclean) # provveda a registrarli e ... # -------------------------------------------------------------------------------- iptables -A INPUT -i ppp0 -m unclean -j LOG --log-prefix "Ricevuto pacc. malformato: " # -------------------------------------------------------------------------------- # ... a scartarli # -------------------------------------------------------------------------------- iptables -A INPUT -j DROP 13. Owner · Modulo: insmod ipt_owner · Tipo: estensione (-m owner) · Es.: iptables -A OUTPUT -m owner --uid-owner 0 -j ACCEPT 13.1. Descrizione Questo modulo aggiunge la possibilità di creare delle regole che possano controllare e prendere delle decisioni in base a chi ha creato il pacchetto. Ciò è possibile solo per i pacchetti generati localmente e destinati alla catena OUTPUT. Inoltre non è sempre possibile per ogni pacchetto stabilire chi è il proprietario (es. risposte a ping ICMP). 13.2. Opzioni Opzioni disponibili: · --uid-owner userid · --uid-owner groupid · --pid-owner processid · --sid-owner processid --uid-owner userid Il pacchetto soddisfa la regola se è stato creato dal userid (numerico) specificato. --uid-owner groupid Il pacchetto soddisfa la regola se è stato creato dal groupid (numerico) specificato. --uid-owner processid Il pacchetto soddisfa la regola se è stato creato dal processo con id (numerico) specificato. --uid-owner processid Il pacchetto soddisfa la regola se è stato creato dal processo con gruppo sessione (numerico) specificato. E' inoltre possibile far precedere a queste opzioni il carattere '!' per negare. Per ottenere una lista dei processi con relativi USER e PID numerici usare il comando: # ps -auxn USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND 0 1 0.0 0.7 1120 476 ? S 09:32 0:00 init 0 2 0.0 0.0 0 0 ? SW 09:32 0:00 [kswapd] 0 3 0.0 0.0 0 0 ? SW 09:32 0:00 [kflushd] 0 4 0.0 0.0 0 0 ? SW 09:32 0:00 [kupdate] 0 246 0.0 0.8 1168 524 ? S 09:32 0:00 syslogd -m 0 0 255 0.0 0.8 1168 520 ? S 09:32 0:00 klogd 99 269 0.0 1.0 1292 628 ? S 09:32 0:00 identd -e -o 2 287 0.0 0.7 1144 496 ? S 09:32 0:00 /usr/sbin/atd 13.3. Esempi #!/bin/bash # # Esempio # # -------------------------------------------------------------------------------- # Aggiungiamo una regola alla catena OUTPUT (-A OUTPUT) che accetti (-j ACCEPT) solo i pacchetti, # generati localmente, che appartengono all'utente con userid uguale a 0 (root). # -------------------------------------------------------------------------------- iptables -A OUTPUT -m owner --uid-owner 0 -j ACCEPT # -------------------------------------------------------------------------------- # il resto dei pacchetti sono rifiutati (-j REJECT) # -------------------------------------------------------------------------------- iptables -A OUTPUT -j REJECT 14. Mac · Modulo: insmod ipt_mach · Tipo: estensione (-m mac) · Es.: iptables -A INPUT -p tcp -m mac --mac-source 08:00:39:00:2F:C3 -j ACCEPT 14.1. Descrizione A volte può essere utile conoscere da quale interfaccia ethernet proviene un pacchetto. Il modulo 'ipt_mach.o' si occupa proprio di questo. Ogni scheda Ethernet si suppone che abbia un unico indirizzo "hardware" MAC (Media Access Control) a 48 bit (es. 00:60:08:91:CC:B7). Con alcune schede è possibile modificarlo con altre no, comunque attraverso questo indirizzo siamo in grado di verificare con maggior sicurezza da quale macchina arriva un pacchetto (o meglio da quale interfaccia). Questo modulo deve essere specificato esplicitamente con '-m mac' oppure '--match mac', inoltre può essere utilizzato solo con le catene PREROUTING e INPUT. 14.2. Opzioni --mac-source [!] XX:XX:XX:XX:XX:XX Permette di specificare l'indirizzo ethernet, es. 00:60:08:91:CC:B7. Può essere seguito da '!' (NOT) per indicare gli indirizzi ethernet diversi da quello specificato es. -m mac --mac-source ! 00:60:08:91:CC:B7. 14.3. Esempi #!/bin/bash # # Esempio 1 # MAC_ADDR=08:00:39:00:2F:C3 PC1=192.168.0.5 # -------------------------------------------------------------------------------- # Accettiamo i pacchetti provenienti dall'interfaccia lo # -------------------------------------------------------------------------------- iptables -A INPUT -i lo -j ACCEPT # -------------------------------------------------------------------------------- # Accettiamo (-j ACCEPT) le richieste di connessione e i dati diretti alla porta telnet (--dport telnet) # solo se provengono da PC1 (-s $PC1) e hanno indirizzo MAC associato pari a # MAC_ADDR (--mac-source $MAC_ADDR) # -------------------------------------------------------------------------------- iptables -A INPUT -p tcp -m mac --mac-source $MAC_ADDR -s $PC1 --dport telnet -j ACCEPT # -------------------------------------------------------------------------------- # accettiamo eventuali pacchetti icmp (vedi cap. ICMP) # -------------------------------------------------------------------------------- iptables -A INPUT -j icmp-accept # -------------------------------------------------------------------------------- # resto è rifiutato # -------------------------------------------------------------------------------- iptables -A INPUT -j REJECT iptables -A FORWARD -j DROP # -------------------------------------------------------------------------------- # Accettiamo i pacchetti diretti all'interfaccia lo # -------------------------------------------------------------------------------- iptables -A OUTPUT -o lo -j ACCEPT # -------------------------------------------------------------------------------- # Accettiamo (-j ACCEPT) i pacchetti inviati in risposta a PC1 (-d $PC1) # -------------------------------------------------------------------------------- iptables -A OUTPUT -p tcp -d $PC1 --sport telnet -j ACCEPT # -------------------------------------------------------------------------------- # Accettiamo i pacchetti icmp (vedi cap. ICMP) # -------------------------------------------------------------------------------- iptables -A OUTPUT -j icmp-accept # -------------------------------------------------------------------------------- # Resto rifiutato # -------------------------------------------------------------------------------- iptables -A OUTPUT -j REJECT 15. MARK · Modulo: insmod ipt_MARK · Tipo: obiettivo (-j MARK) · Es.: iptables -A PREROUTING -i eth0 -t mangle -p tcp --dport telnet -j MARK --set-mark 1 15.1. Descrizione In alcuni casi può essere utile marcare i pacchetti per poi prendere, in base a queste, delle decisioni di instradamento particolari (routing). In particolare può essere utilizzato assieme al comando tc del pacchetto iproute2 per gestire il controllo del traffico. I pacchetti sono sottoposti a tutte le regole presenti in questa tabella, anche se ad esempio soddisfano già la prima regola. 15.2. Opzioni --mark-value[/mask] Permette di specificare il valore ed eventualmente anche la maschera che contrassegnerà i pacchetti specificati. E' possibile far precedere all'opzione il carattere '!' per negare. 15.3. Esempi Esempio1 #!/bin/bash # # Esempio 1 # modprobe ipt_MARK ETH=eth0 FTP=1 TELNET=2 PC1=192.168.0.2 PC2=192.168.0.3 FAST=1 SLOW=0 # -------------------------------------------------------------------------------- # Prima che i pacchetti generati localmente siano immessi nella rete in base alla # porta di destinazione sono marcati con un valore. # NOTA: Qui si utilizza la catena OUTPUT ma della tabella mangle ! # -------------------------------------------------------------------------------- iptables -A OUTPUT -o $ETH -t mangle -p tcp --dport ftp -j MARK --set-mark $FTP iptables -A OUTPUT -o $ETH -t mangle -p tcp --dport telnet -j MARK --set-mark $TELNET # -------------------------------------------------------------------------------- # Prima che i pacchetti siano instradati sono marcati in base all'indirizzo di destinazione # Il kernel potrà utilizzare queste informazioni ad esempio per indirizzare i # pacchetti FAST su una "banda" veloce e i SLOW su una lenta. # -------------------------------------------------------------------------------- iptables -A PREROUTING -t mangle -p tcp -d $PC1 -j MARK --set-mark $FAST iptables -A PREROUTING -t mangle -p tcp -d $PC2 -j MARK --set-mark $SLOW 16. TOS (Type Of Service) · Modulo: insmod ipt_TOS · Tipo: obiettivo (-j TOS) · Es.: iptables -A PREROUTING -t mangle -p tcp --dport telnet -j TOS --set-tos Minimize-Delay 16.1. Descrizione Questo modulo permette di impostare i bit TOS (Type Of Service). Questi bit sono presenti nell'intestazione IP dei pacchetti e influenzano come devono essere trattati dalla macchina che li invia. Ognuno ha un suo scopo e non è possibile combinarli assieme. 16.2. Opzioni --set-tos value Permette di specificare quale bit impostare 16.3. Bit I bit sono cinque: · Minimize-Delay (16, 0x10) ritardo minimo · Maximize-Throughput (8, 0x08) massima velocità di trasmissione · Maximize-Reliability (4, 0x04) massima affidabilità · Minimize-Cost (2, 0x02) costo minimo · Normal-Service (0, 0x00) servizio normale L'uso comune è quello di impostare telnet e ftp a "Minimize-Delay", ftp-data, www a "Maximize-Throughput", snmp, dns a "Maximize- Reliability" e nntp, smtp a "Minimize-Cost". Per l'elenco completo compresi valori esadecimali utilizzare il comando: iptables -j TOS --help Per impostare i bit tos è necessario utilizzare la tabella mangle usando l'opzione '-t mangle', specificare il protocollo (-p), la porta (--dport), l'obiettivo (-j) e il bit da impostare (--set-tos). Le regole devono essere aggiunte alla catena PREROUTING, in quanto si possono modificare solo i pacchetti che sono in uscita dalla macchina e prima del routing. 16.4. Esempi # -------------------------------------------------------------------------------- # TOS # -------------------------------------------------------------------------------- iptables -A PREROUTING -t mangle -p tcp --dport telnet -j TOS --set-tos Minimize-Delay iptables -A PREROUTING -t mangle -p tcp --dport ftp -j TOS --set-tos Minimize-Delay iptables -A PREROUTING -t mangle -p tcp --dport ftp-data -j TOS --set-tos Maximize-Throughput 16.5. ipchains vs. iptables Anche ipchains permette di impostare i bit TOS usando il seguente comando: ipchains -A output -p tcp -d 0.0.0.0/0 telnet -t 0x01 0x10 Questa linea con iptables dovrebbe diventare: iptables -A PREROUTING -p tcp --dport telnet -d 0.0.0.0/0 -j TOS --set-tos Minimize-Delay 17. MIRROR · Modulo: insmod ipt_MIRROR · Tipo: obiettivo (-j MIRROR) · Es.: iptables -A -p tcp -s 213.15.12.3 -j MIRROR 17.1. Descrizione Questo modulo aggiunge la possibilità di specificare MIRROR come target (-j MIRROR), in questo modo i pacchetti che soddisfano la regola saranno rispediti indietro al mittente. In pratica non fa altro che inverire i campi indirizzo sorgente e indirizzo destinazione contenuti nell'intestazione IP dei pacchetti. Questo modulo è ancora sperimentale e da utilizzare esclusivamente per effettuare dei test. 17.2. Opzioni Non sono disponibili opzioni 18. REJECT · Modulo: insmod ipt_REJECT · Tipo: obiettivo (-j REJECT) · Es.: iptables -A INPUT -p tcp --syn -j REJECT --reject-with proto-unreach 18.1. Descrizione Questo modulo aggiunge la possibilità di specificare REJECT come target (-j REJECT), in questo modo se la regola è soddisfatta sarà spedito al mittente un pacchetto icmp. Si può usare in alternativa di DROP che invece scarta il pacchetto senza inviare alcun messaggio alla macchina che lo ha spedito. 18.2. Opzioni --reject-with Con questa opzione è possibile indicare quale tipo di pacchetto icmp inviare alla macchina mittente. I pacchetti supportati attualmente sono: · icmp-net-unreachable o net-unreach · icmp-host-unreachable o host-unreach · icmp-port-unreachable o port-unreach · icmp-proto-unreachable o proto-unreach · echo-reply o echoreply 18.3. Esempi #! /bin/sh # # Esempio # ... # -------------------------------------------------------------------------------- # Inviamo un pacchetto icmp 'icmp-net-unreachable' a chi invia pacchetti destinati # alla rete 192.168.1.0 perché ad esempio non presente # -------------------------------------------------------------------------------- iptables -A INPUT -p tcp -d 192.168.1.0 -j REJECT --reject-with icmp-net-unreachable # -------------------------------------------------------------------------------- # Inviamo un pacchetto icmp 'port-unreach' a chi invia pacchetti destinati alla porta ftp # -------------------------------------------------------------------------------- iptables -A INPUT -p tcp --dport ftp -j REJECT --reject-with port-unreach # -------------------------------------------------------------------------------- # tutto il resto è scartato # -------------------------------------------------------------------------------- iptables -A INPUT -j DROP ... 19. TCP/IP Il modello più diffuso per la trasmissione dei dati attraverso le reti è oggi il TCP/IP. Il nome deriva dai suoi due protocollo principali: TCP (Transmission Control Protocol) e IP (Internet Protocol). I dati che viaggiano nella rete sono organizzati in pacchetti, ciascuno contiene un'intestazione IP in cui sono presenti alcune informazioni molto importanti (indirizzo sorgente, indirizzo destinazione, lunghezza totale, ...) che permettono loro di giungere a destinazione. Inoltre se i pacchetti sono di tipo TCP allora conterranno anche un'intestazione TCP che raccoglie un insieme di informazioni (porta sorgente, porta destinazione, Type Of Service, flags, ...) utili per verificare la correttezza dei pacchetti, per riordinarli nell'ordine corretto, per stabilire a quale servizio sono destinati (ftp, telnet, mail, www, ...). Il protocollo TCP è orientato alla connessione affidabile, si occupa di riassemblare, frammentare, riordinare, ritrasmettere, controllare i pacchetti. Esiste anche una "versione" più semplice nota come UDP (User Datagram Protocol) non basata su connessione e quindi inaffidabile ma estremamente veloce, in alcuni casi è preferita al TCP ad esempio per richieste al DNS (Domain Name System) o per tftp (Trivial ftp). Il protocollo IP ha come compito invece quello di instradare e consegnare i pacchetti a destinazione. I pacchetti possono essere graficamente rappresentati in questo modo: +------------+------------+------------- - - |intestazione|intestazione| DATI | IP | TCP | .... +------------+------------+------------- - - 20 bytes 20 bytes [ Pacchetto ] Sempre nei pacchetti IP sono inoltre incapsulati anche i pacchetti UDP e i pacchetti ICMP, questi ultimi usati per lo più per segnalare errori o problemi riscontrati nella rete o nella consegna dei pacchetti. Per una completa descrizione dei campi delle varie intestazioni consultare l'appendice. Il filtraggio dei pacchetti si basa proprio su queste informazioni per stabilire se un pacchetto deve essere accettato o meno. In particolare è importante conoscere come si stabilisce una connessione, come sono scambiati i dati, e quali sono i punti deboli. La maggior parte dei servizi (ftp, telnet, mail) oltre all'indispensabile protocollo IP utilizzano anche il protocollo TCP che è affidabile, completo e basato su connessione. 19.1. Connessione "Three-way handshake" La connessione si basa sul "Three-way handshake" ossia tre fasi in cui due computer stabiliscono e negoziano la connessione. La prima fase prevede che il client richieda una connessione (SYN) alla macchina server, ossia invii un pacchetto completo di intestazione IP e TCP con il flag SYN impostato: +---+ +-------+ |PC1|------------ SYN --------------->|SERVER | +---+ +-------+ La seconda fase prevede che il server, se disponibile, invii un pacchetto di risposta affermativo (SYN/ACK): +---+ +-------+ |PC1|<------- SYN/ACK ------------- |SERVER | +---+ +-------+ La terza fase prevede che il client invii a sua volta un pacchetto di conferma (ACK): +---+ +-------+ |PC1| ---------- ACK -----------> |SERVER | +---+ +-------+ Concluse con successo queste fasi il client può cominciare a inviare i pacchetti con i dati. NOTA: questo schema è semplificato e non ha preso in esame le porte e il 'sequence number'. 19.2. Porte Per poter stabilire una connessione con un computer è necessario indicare a quale servizio (telnet, ftp, www, finger, rlogin, ...) si è interessati. Nel file /etc/services è possibile trovare un elenco dei servizi standard che si possono richiedere completi di numero, protocollo e in alcuni casi breve descrizione. Esempio: ... echo 7/tcp telnet 23/tcp ftp 21/tcp www 80/tcp http # WorldWideWeb HTTP www 80/udp # HyperText Transfer Protocol domain 53/tcp nameserver # name-domain server domain 53/udp nameserver ... NOTA: in alcuni casi si possono trovare nomi differenti a seconda della distribuzione Linux (es. pop3 e pop-3) i numeri sono comunque gli stessi. Le porte sono suddivise in porte note o privilegiate (well-known port) e porte non privilegiate. Le porte note appartengono all'intervallo da 1 a 1023, ad ognuna è associato un servizio e protocollo, secondo quanto stabilito dallo IANA (RFC 1700). Se un computer vuole offrire un servizio ftp a qualsiasi utente allora si dovrà mettere in "ascolto" sulla porta 21 in attesa che qualcuno invii una richiesta di connessione, quindi provvedere a stabilire la connessione (caso TCP) e a scambiare i dati. Le porte che appartengono all'intervallo 1024-65535 sono invece utilizzato in genere dal client come vedremo. L'intestazione TCP comprende due campi importanti: porta sorgente e porta destinazione. Quando si vuole stabilire una connessione per accedere ad una macchina presente nella rete utilizzando ad esempio il telnet è necessario che questi due campi siano impostati in modo appropriato, le fasi nel caso del telnet sono le seguenti: Il client invia pacchetto inizio connessione specificando anche il servizio alla quale è interessato (es. telnet), indica inoltre verso quale porta devono essere indirizzati i pacchetti in risposta (ne seleziona una libera tra quelle dell'intervallo 1024-65535 partendo da 1024) e il protocollo: +---+ +-------+ |PC1|----------- SYN ----------->|SERVER | PD = Porta Destinazione +---+ PD=23 +-------+ PS = Porta Sorgente PS=1024 PT = Protocollo (tcp/udp/icmp) PT=tcp In questo caso è inviata una richiesta di connessione alla porta 23 (telnet) del server specificando che le risposte dovranno essere indirizzate alla porta 1024 del client, protocollo tcp. Se il server offre quel servizio ed è in "ascolto" sulla porta 23 (telnet), se decide di accettare la connessione, invierà un pacchetto di conferma (ACK) dove specificherà che deve essere destinato alla porta 1024 del client, proveniente dalla sua porta 23: +---+ +-------+ |PC1| <------- SYN/ACK ---------- |SERVER | PD = Porta Destinazione +---+ PD=1024 +-------+ PS = Porta Sorgente PS=23 PT = Protocollo (tcp/udp/icmp) PT=tcp Nota che ora la porta destinazione è 1024 e non più 23, la situazione si è insomma invertita. Poi si prosegue più o meno nella stesso modo anche nella fase di invio/ricezione dei dati. E' necessario precisare che in qualche caso alcuni servizi, ad esempio www, possono essere presenti su porte differenti. E' infatti possibile che ad esempio www sia disponibile invece che sulla porta 80 sulla 8080, sono comunque casi noti. Altri servizi come RealPlayer, X Window, Quake, utilizzano porte prestabilite ma appartenenti all'intervallo 1024-65535, e non una delle note (1-1023). Ciò è dovuto al fatto che sono servizi resi disponibili recentemente. In alcuni casi un servizio (es. dns/domain) è disponibile sia con protocollo tcp sia udp. Nel caso di dns ad esempio è utilizzato in genere il protocollo udp (veloce e privo di connessione 3-way handshake), ma in alcuni casi si rende necessario anche l'utilizzo del protocollo tcp più completo e affidabile. Ciò è importante per chi deve realizzare un firewall. La porta sorgente è utile anche per distinguere tra due diverse connessioni alla stessa porta destinazione. Ad esempio quando si accede all'indirizzo www.linux.org e si aprono due pagine dello stesso sito con netscape come fa il client a riconoscere quali dati riguardano una e quali l'altra ? In base alla porta sorgente che sarà ovviamente diversa. +=============================+ | Netscape | +-----------------------------+ | www.linux.org/index.html |<-----SP=80 (www) DP=1024 ... --- +------------+ |^^^+============================+ | SERVER WWW | | | Netscape | | | | +----------------------------+ | | | |www.linux.org/page1.html |<--SP=80 (www) DP=1025 ... --- | linux.org | | |^^^^^^^^^^^^^^^^^^^^^^^^^^^^| | | | | | +------------+ . . . 19.3. Esempio Esempio di una connessione ad un www server per reperire delle pagine web: Supponiamo di voler instaurare una connessione con il sito internet www.linux.com e di aver la seguente situazione: +----+ +----------+ |PC1 | |SERVER WWW| | | |linux.com | +----+ +----------+ 151.186.5.4 198.186.203.55 Inseriamo l'indirizzo www.linux.com nel nostro browser e iniziamo una connessione. L'applicazione Netscape richiede quindi al kernel una connessione TCP al server www.linux.com. A questo punto è selezionata una porta sorgente tra quelle disponibili nell'intervallo 1024-65535 a partire però dalla 1024 se è disponibile. Il nome www.linux.com viene risolto attraverso il dns (Domain Name System), ossia un computer, il cui indirizzo deve essere presente nel file /etc/resolv.conf, che ha il compito di restituire l'indirizzo IP numerico corrispondente: 198.186.203.55. Quindi tenta di instaurare una connessione al WEB server inviando un pacchetto con indirizzo sorgente l'indirizzo 151.186.5.4 (PC1), indirizzo destinazione 198.186.203.55 (www.linux.com), porta sorgente 1024, porta destinazione ovviamente 80 (porta nota www), flag SYN impostato. E' inoltre scelto arbitrariamente da Linux un 'sequence number' (numero di sequenza) es. 1000000. +----+ +----------+ |PC1 | ------------o-------------> |SERVER WWW| | | / \ |linux.org | +----+ / \ +----------+ 151.186.5.4 / \ 198.186.203.55 ______________/ \______________________ / \ +----------------------------------------------------+ | IP IS=151.186.5.4 ID=198.186.203.55 | IS=indirizzo sorgente | ... | ID=indirizzo destinazione +----------------------------------------------------+ | TCP PS=1024 PD=80 (www) | PS=porta sorgente | FLAG=SYN SEQ_NR=1000000 | PD=porta destinazione | ... | +----------------------------------------------------+ Il server WEB www.linux.com riceve il pacchetto, accetta la connessione e risponde inviando un pacchetto di conferma con flag ACK impostato. Questo pacchetto inoltre conterrà il sequence number inviato con in più sommato 1 (SYN) (posto nel campo 'acknowledgement number') e il sequence number scelto dal server es. 2000000. +----+ +----------+ |PC1 | <-----------o------------- |SERVER WWW| | | / \ |linux.org | +----+ / \ +----------+ 151.186.5.4 / \ 198.186.203.55 ______________/ \______________________ / \ +----------------------------------------------------+ | IP IS=151.190.20.12 ID=198.186.203.55 | IS=indirizzo sorgente | ... | ID=indirizzo destinazione +----------------------------------------------------+ | TCP PS=80 (www) PD=1024 | PS=porta sorgente | FLAG=SYN+ACK SEQ_NR=2000000 | PD=porta destinazione | ... ACK_NR=1000001 | +----------------------------------------------------+ La macchina PC1 riceve il pacchetto controlla che il campo 'acknowledgement number' sia corretto e conclude la fase di connessione inviando un ultimo pacchetto TCP di conferma ossia con il flag ACK impostato. Il sequence number sarà 1000000 + 1 inoltre sarà inviato anche il sequence number del server con sommato 1 (SYN) ossia 2000001 nel campo 'acknowledgement number'. +----+ +----------+ |PC1 | ------------o-------------> |SERVER WWW| | | / \ |linux.org | +----+ / \ +----------+ 151.186.5.4 / \ 198.186.203.55 ______________/ \______________________ / \ +----------------------------------------------------+ | IP IS=151.186.5.4 ID= 198.186.203.55 | IS=indirizzo sorgente | ... | ID=indirizzo destinazione +----------------------------------------------------+ | TCP PS=1024 PD=80 (www) | PS=porta sorgente | FLAG=ACK SEQ_NR=1000001 | PD=porta destinazione | ... ACK_NR=2000001 | +----------------------------------------------------+ A questo punto PC1 da Netscape può effettuare una richiesta HTTP, inoltrata come sempre con un pacchetto TCP sequence number 1000001 e ack number 2000001, flag ACK impostato. Il server riceve e risponde con un pacchetto TCP con sequence number 2000001, acknowledgement number pari a 1000001 + (dimensione pacchetto TCP inviato da PC1), e i dati (pagina web) richiesti. Quest'ultime due fasi poi si ripetono per ogni invio/ricezione di richieste/dati. Terminata la visita al sito, PC1 chiude la connessione inviando un pacchetto TCP con il flag FIN impostato. NOTA: l'utilizzo dei campi 'sequence number' e 'acknowledgement number' è fondamentale in quanto consente ai computer di controllare e verificare l'ordine e la correttezza dei pacchetti scambiati. 19.4. Problemi Il meccanismo che permette di stabilire una connessione e scambiare dati non è perfetto, in alcuni casi anche a causa di errori presenti nelle varie implementazioni dello stack TCP/IP, è possibile aggirare e intromettersi nella comunicazione. Sono note diverse tecniche che possono creare problemi riguardanti l'area della sicurezza, tra queste le più note sono: IP spoofing, smurfing, Blind spoofing, ... 19.4.1. IP spoofing Quando si richiede una connessione ad una macchina, come si è visto, si inviano una serie di pacchetti dove nelle intestazioni sono presenti varie informazioni tra cui indirizzo sorgente, indirizzo destinazione, porta destinazione, ... In particolare l'indirizzo sorgente specifica l'indirizzo IP di chi invia i pacchetti, l'IP spoofing si basa proprio su questo campo, che può essere modificato, forgiato da un attacker per effettuare un attacco. E' possibile cioè che qualcuno possa creare e inviare dei pacchetti in modo tale che sembrino provenire da un qualunque indirizzo IP. Ciò consente di agire senza essere facilmente rintracciabilili. Questo tipo di attacco è particolarmente pericoloso per quei servizi che sono impostati in modo da non richiedono login e password, e che quindi fanno affidamento per identificare l'utente solo sull'indirizzo IP. Per proteggersi da questo tipo di attacchi è possibile impostare il parametro "rp_filter" presente nella directory /proc/sys/net/ipv4/conf/default in modo che tutti i pacchetti che arrivano dalla rete esterna aventi come indirizzo sorgente un'indirizzo della propria rete locale siano scartati. Per impostare questo parametro in modo che protegga tutte le interfacce presenti nella macchina (es. firewall) utilizzare: if [ -e /proc/sys/net/ipv4/conf/all/rp_filter ] then for f in /proc/sys/net/ipv4/conf/*/rp_filter do echo 1 > $f done fi Questa è la soluzione migliore, un'alternativa può essere quella di utilizzare iptables: # Scartiamo tutti i pacchetti in entrata dall'interfaccia esterna (qui eth0) con indirizzo # uguale a quello della nostra rete iptables -A FORWARD -i eth0 -s 207.102.5.0/24 -j DROP Con questo comando tutti i pacchetti che arrivano all'interfaccia esterna eth0 aventi per indirizzo sorgente un indirizzo della nostra rete locale (207.102.5.0/24) sono scartati (DROP). E' anche consigliato impedire che dalla nostra rete locale possano uscire dei pacchetti con indirizzo sorgente diverso da quello atteso, che dovrebbe essere ovviamente del tipo 207.102.5.x. Questo per impedire che qualcuno cerchi di inviare pacchetti di tipo "spoofing" dalla nostra rete locale. +---+ |PC1|---+ eth1 eth0 +---+ | | | +---+ | \+---+/ |MAC|---+---| |---- INTERNET +---+ | +---+ . [RETE LOCALE] [firewall] 207.102.5.0/24 # iptables -A FORWARD -i eth1 ! -s 207.102.5.0/24 -j REJECT I pacchetti giunti dalla rete locale (-i eth1) con indirizzo sorgente diverso da 207.102.5.0/24 (! -s 207.102.5.0/24) sono rifiutati (-j REJECT). Dovrebbero essere eseguiti comandi simili per ogni interfaccia del firewall ed anche per la catena INPUT. Proteggersi dall'IP spoofing è molto importante in quanto molti attacchi ne fanno ancora uso. 19.4.2. Blind spoofing Questa tecnica si basa sull'IP spoofing e ha come scopo stabilire una connessione con un server utilizzando un indirizzo sorgente fasullo. +---+ +---+ | | <----o---- | | +---+ ^ +---+ [SERVER] | [ATTACKER] | +---+ '-------- pacchetto con indirizzo sorgente fasullo 213.120.4.3 | | +---+ [213.120.4.3] A prima vista potrebbe sembrare molto semplice ma in realtà non lo è. Quando si invia un pacchetto con indirizzo sorgente fasullo ad un server quest'ultimo invierà le risposte non all'attacker ma alla macchina con l'indirizzo IP uguale a quello fasullo indicato nel pacchetto. +---+ +---+ | | | | +---+ +---+ [SERVER] [ATTACKER] | o <-- pacchetto di risposta diretto a 213.120.4.3 e non all'attacker | v +---+ |PC2| +---+ [213.120.4.3] Il problema è che la macchina 213.120.4.3 riceve il pacchetto, rileva che non ha effettuato alcuna richiesta per quella connessione (infatti è stata fatta dall'attacker) e quindi invierà di conseguenza un pacchetto di RST per annullarla. Questo chiuderebbe la connessione impedendo all'attacker di stabilire e concludere la connessione. L'attacker deve quindi impedire che ciò avvenga e ciò è possibile se riesce a bloccare PC2. A questo scopo si può utilizzare un DoS (Denial of Service) che non deve far altro che "disabilitare" forzatamente e per un certo tempo PC2 in modo che non sia in grado di inviare i pacchetti RST. Risolto questo problema è necessario infine predire il sequence number iniziale inviato dal server, per concludere la "Three-way handshake" infatti è necessario che l'attacker invii un pacchetto di conferma (ACK) contenente l'acknowledgement number (basato sul sequence number inviato dal server) corretto. Fino a qualche tempo fa ciò era possibile e in alcuni casi era banale quindi l'attacker poteva concludere la connessione con successo, ora lo stack TCP/IP di vari sistemi operativi generano numeri di sequenza casuali difficilmente predicibili. Abilitando la protezione contro l'IP spoofing e grazie alla capacità di Linux di generare sequence number casuali non facilmente predicibili, questo tipo di attacco è evitabile. 19.4.3. Port scanning Tra gli strumenti utilizzati per ottenere informazioni utili per scoprire eventuali punti deboli di un computer connesso in rete ci sono i cosiddetti port scanner. Attraverso questi programmi è possibile ottenere di una macchina un elenco delle porte aperte, ossia dei servizi (ftp, www, ...) che offre volutamente, potrebbe essere un server WWW, oppure no (macchina malconfigurata). Le porte aperte rappresentano un potenziale canale di comunicazione, utilizzabile per scambiare dati e per portare un eventuale attacco. Le tecniche adottate sono diverse e permettono di ottenere un certo grado di anonimato, in genere non si desidera che la "macchina vittima" possa rilevare e registrare i port scanning. Tra le tecniche più note troviamo: · Vanilla TCP connect() scanning · TCP SYN (half-open) scanning · TCP FIN (stealth) scanning · UDP ICMP port unreachable scanning Vanilla TCP connect() Questa è la tecnica più semplice e consiste nella chiamata alla routine di sistema connect(). Se la porta desiderata (es. www) è aperta allora avrà successo altrimenti la porta risulterà irraggiungibile. I vantaggi di questa tecnica sono la velocità e il fatto che per eseguirla non è necessario possedere particolari privilegi (es. root). Lo svantaggio è che può essere facilmente rilevata e registrata dal server vittima. TCP SYN (half-open) scanning In questo caso non è necessario completare la "Three hand- shake", ossia si invia un pacchetto di richiesta connessione (SYN) alla porta della macchina vittima, e si attende una risposta che potrebbe essere RST (porta/servizio non disponibile) o SYN-ACK (porta/servizio disponibile), in quest'ultimo caso si provvederà allora ad inviare un pacchetto RST per chiudere immediatamente la connessione. Utile in quanto in alcuni casi i server non rilevano e registrano queste prove. TCP FIN (stealth) scanning Questa tecnica è stato implementata in quanto i tentativi basati sui pacchetti SYN è molto nota e quindi in molti casi i server sono in grado di rilevarla utilizzando anche specifici programmi. La soluzione in questo caso consiste nell'invio di un pacchetto FIN, in genere utilizzato per chiudere una connessione stabilita. La macchina che riceve questo pacchetto si è osservato che in genere, se la porta/servizio non è disponibile, invia un pacchetto in risposta di tipo RST, in caso contrario nulla è inviato. In base a queste informazioni è così possibile stabilire se un determinato servizio è o meno disponibile e senza dover utilizzare un pacchetto SYN. NOTA: macchine con sistema operativo Microsoft non operano in questo modo (standard), in caso di pacchetti FIN rispondono in ogni caso con un pacchetto RST. UDP ICMP port unreachable scanning In questo caso non si invia un pacchetto TCP ma bensì UDP (User Datagram Protocol). Questi pacchetti sono molto semplici ma non sono affidabili. In molti casi si è notato che inviando questi pacchetti verso una porta UDP si è ottenuto in risposta un pacchetto ICMP_PORT_UNREACH, ciò permette di conoscere quali porte UDP non sono sicuramente disponibili, mentre sulle altre è possibile fare solo alcune considerazioni. UDP è un protocollo inaffidabile che non si basa sul concetto di connessione quindi i pacchetti che si inviano o che si dovrebbero ricevere potrebbero andare persi, e quindi le informazioni ricavate potrebbero non corrispondere al vero. Altro problema è la scarsa velocità offerta. Utile però per verificare quale delle porte alte (1024-65535) UDP sono aperte. 20. FRAMMENTI 20.1. Descrizione I pacchetti che viaggiano attraverso la rete hanno una dimensione, questa può variare da caso a caso. Nel caso Ethernet i pacchetti hanno una dimensione di 1500 byte, nel caso invece di pacchetti inviati verso internet attraverso l'interfaccia ppp0 (dialup) è in genere pari a 296 byte, ma è comunque possibile variarla modificando il parametro MTU (Maximum Transmission Unit). Di questi 296 byte una parte è occupata dalle intestazioni (IP e TCP, o IP e ICMP ...) il resto dai dati. In particolare un'intestazione TCP occupa 20 byte, e visto che deve essere incapsulato sempre in un pacchetto IP è necessario aggiungere anche l'intestazione IP (20 byte), quindi lo spazio a disposizione per i dati in ciascun pacchetto sarà pari a 296 (MTU) - 20 (intestazione IP) - 20 (intestazione TCP) = 256 byte. Graficamente possiamo rappresentarli così: 0 20 40 295 +-------+-------+------------------------+ | IP | TCP | DATI | +-------+-------+------------------------+ Questo è valido per il primo pacchetto, infatti i pacchetti/frammenti successivi conterranno solo l'intestazione IP e i dati, l'intestazione TCP non sarà più necessaria: 0 20 295 +-------+--------------------------------+ | IP | DATI | +-------+--------------------------------+ Quindi se volessimo inviare 1500 byte di dati attraverso l'interfaccia ppp0, in realtà, come visto, non sarà spedito un solo pacchetto da 1500 byte, ma diversi pacchetti/frammenti: · Pacchetto iniziale con intestazione IP (20 byte), TCP (20 byte) e dati (256 byte, totale 296 byte) · Pacchetto successivo con solo intestazione IP (20 byte) e dati (276 byte, totale 296 byte) · Pacchetto successivo con solo intestazione IP (20 byte) e dati (276 byte, totale 296 byte) · ... La macchina che li riceverà provvederà poi a ordinarli, riassemblarli e a ricostruire i pacchetti originali. 20.2. Ping della morte, Teardrop, ... I frammenti sono stati, particolarmente in passato, causa di notevoli problemi e crash delle macchine. Questi problemi sono derivati da una non corretta implementazione di molti stack TCP/IP. Tra i più noti e citati ci sono il Ping della Morte (Ping of Death), Teardrop, Bonk, Zero Length Fragments. Il Ping della morte si basa sul campo "Total Lenght" (lunghezza totale) del pacchetto IP. Un pacchetto IP non può essere lungo più di 65535 byte. Il ping della morte consiste nell'inviare un frammento con lunghezza di 1000 bytes e impostare il campo "Fragment Offset" del pacchetto stesso a 65400 byte, lo stack TCP/IP vulnerabile della macchina che lo riceve cercherà quindi di assemblare un pacchetto di lunghezza 65400+1000 byte = 66400 byte con risultati spiacevoli (crash). Ora gran parte dei sistemi operativi sono immuni da questo tipo di attacco, ossia controllano la dimensione dei pacchetti riassemblati, anche linux ha sofferto di questo problema fino alla versione 2.0.24 del kernel. Teardrop, Bonk, ... invece creano ad arte dei frammenti in modo tale che con il riassemblamento i frammenti si "sovrappongano" confondendo e mettendo in crisi la macchina destinataria. I Zero length Fragments hanno creato problemi a Linux fino alla serie 2.2.4 del kernel. Questo attacco si basa sull'invio di un frammento di lunghezza zero, la macchina erroneamente lo accoda assieme agli altri frammenti da riassemblare, invece di scartarlo. Per quanto riguarda il filtraggio dei pacchetti il problema riguarda la struttura dei frammenti successivi al primo, che come abbiamo visto non contengono l'intestazione TCP. Questo significa che non sarà possibile controllare i relativi campi. Esistono comunque diverse soluzioni, ad esempio se la propria macchina firewall è l'unica che protegge la rete locale è possibile compilare il kernel con la voce "always defragment" selezionata, in questo modo tutti i frammenti diretti alle macchine della rete locale, prima di essere inoltrati, saranno riassemblati dal firewall. Questo inoltre permette di utilizzare iptables/ipchains senza doversi preoccupare dei frammenti. In questo caso è necessario fare attenzione nel caso ci siano più firewall, se i frammenti dovessero arrivare parte a uno e parte all'altro il riassemblaggio fallirebbe miseramente. Altrimenti sarà necessario accettare i frammenti e lasciare alle macchine destinatarie della rete locale il compito di riassemblarli (non consigliato). Con iptables è necessario specificare esplicitamente che i frammenti devono essere accettati con l'opzione '-f'. Ad esempio è possibile accettare tutti i frammenti diretti alla rete locale, in questo modo: iptables -A FORWARD -f -j ACCEPT Oppure potremmo voler accettare solo i pacchetti www e i frammenti e rifiutare il resto: iptables -A INPUT -p tcp ! --syn --sport www -j ACCEPT iptables -A INPUT -p tcp --sport www -f -j ACCEPT ... iptables -A INPUT -j REJECT Nota: se si utilizza il tracciamento delle connessioni o il NAT, i frammenti prima di essere filtrati dal firewall saranno sempre riassemblati. 21. ICMP 21.1. Descrizione ICMP (Internet Control Message Protocol) è un protocollo designato per effettuare test, controlli e gestire situazioni di errore. Per essere indirizzati nella rete anch'essi si appoggiano al protocollo IP, che contiene le informazioni di instradamento (indirizzo sorgente, destinazione). +-------+--------+ | IP | ICMP | +-------+--------+ Un programma molto noto che utilizza questo protocollo è ping, il cui scopo principale è di verificare se una macchina nella rete è raggiungibile e in funzione oppure no. Per verificare se la macchina con indirizzo IP 192.168.0.1 è presente nella rete è sufficiente quindi impartire il comando: ping 192.168.0.1 Ping non fa altro che inviare un pacchetto ICMP di tipo 0 (echo request) alla macchina destinataria e attendere che questa risponda con un pacchetto ICMP di tipo 8 (echo reply). 21.2. Tipi ICMP Ecco un elenco dei pacchetti ICMP più importanti: ICMP tipo 0 - Echo reply (pong) Come visto è il pacchetto inviato dalle macchine in risposta ad un pacchetto ICMP tipo 8 echo request (ping). In genere non sono filtrati. ICMP tipo 3 - Destination Unreachable Questo tipo di pacchetti segnalano all'host che ha spedito un pacchetto che non è stato possibile consegnarlo all'host destinatario in quanto non raggiungibile (unreachable) o perchè il servizio (porta) richiesto non era disponibile (Port Unreachable). Il codice associato può essere uno dei seguenti: · 0 Net Unreachable · 1 Host Unreachable · 3 Port Unreachable · 4 Fragmentation Needed but DF set · 5 Source route failed Quando in una regola si utilizza l'obiettivo REJECT (-j REJECT) il firewall per ogni pacchetto che soddisfa quella regola provvederà a spedire all'host che l'ha inviato un pacchetto ICMP di tipo 3. Per default il codice associato è 3 (Port Unreachable) ma può essere cambiato. Può essere utilizzato per attachi DoS, comunque è sconsigliato filtrare questi pacchetti, in quanto si potrebbero ottenere malfunzionamenti e ritardi nelle risposte. In particolare 'Fragmentation Needed but DF set' è molto importante in quanto utilizzato per stabilire la dimensione massima che può avere un pacchetto senza dover essere frammentato. Scartare questi pacchetti potrebbe causare malfunzionamenti e un calo di prestazione. ICMP tipo 4 - Source Quench Congestione nella rete. Gli host in genere reagiscono a questo tipo di pacchetti ICMP "rallentando" la comunicazione, potrebbero quindi essere usati per un attacco DoS. Pare che siano utilizzati da alcuni server SMTP. In genere comunque non sono filtrati. ICMP tipo 5 - Redirect Questi pacchetti devono essere filtrati, in quanto sono utilizzati per modificare la tabella di routing, ciò può consentire a qualcuno di redirigere il traffico della propria rete. Possono essere utilizzati anche per attacchi DoS. ICMP tipo 8 - Echo Request (ping) Questo pacchetto ICMP è utilizzato per verificare se una macchina è presente nella rete o per effettuare dei test. In molti casi si preferisce filtrare e limitare i ping provenienti dall'esterno. Con iptables è possibile comunque accettarli e utilizzare '-m limit' per evitare attacchi DoS. ICMP tipo 11 - Time Exceeded in Transit Nell'intestazione IP è presente un campo TTL (Time To Live) utilizzato come un vero e proprio contatore. Questo contatore misura il "tempo da vivere" che ha un pacchetto ed è decrementato in pratica ad ogni salto da un router all'altro. Lo scopo è quello di impedire che un pacchetto possa viaggiare nella rete per un tempo indeterminato. Se un router riceve un pacchetto con il campo TTL uguale a 0 provvederà a scartarlo e ad inviare un pacchetto ICMP TTL Exceeded (codice 0) alla macchina che lo ha inviato. Altro caso si ha quando un host non è in grado di assemblare i frammenti di un pacchetto entro il TTL, anche in questo caso il pacchetto è scartato e un ICMP Fragment reassembly timeout (codice 1) è inviato alla macchina mittente. Un programma noto che utilizza questi pacchetti è 'traceroute'. In genere non è filtrato. Il codice associato può essere quindi uno dei seguenti: · 0 TTL Exceeded · 1 Fragment reassembly timeout ICMP tipo 12 - Parameter Problem Se un router o un host dovessero ricevere un pacchetto con qualche problema riguardante i parametri delle intestazioni, ad esempio argomenti non corretti presenti nelle opzioni, potrebbero decidere di scartarlo e di inviare un pacchetto ICMP Parameter Problem all'host che lo ha inviato. In alcuni casi può essere indicatore di un attacco. In genere non è filtrato. Se si utilizza il connection tracking e il modulo 'state' non è necessario preoccuparsi di questi pacchetti. In caso contrario è necessario filtrarli, a questo scopo è possibile creare una catena apposita che accetti solo i tipi che non rappresentano un pericolo o che sono indispensabili: iptables -N icmp-accept iptables -A icmp-accept -p icmp --icmp-type destination-unreachable -j ACCEPT iptables -A icmp-accept -p icmp --icmp-type source-quence -j ACCEPT iptables -A icmp-accept -p icmp --icmp-type time-exceeded -j ACCEPT iptables -A icmp-accept -p icmp --icmp-type parameter-problem -j ACCEPT NOTA: deve precede le regole che utilizzano -j DROP/REJECT e anche -j LOG se presente es.: ... iptables -A INPUT -j icmp-accept iptables -A INPUT -j LOG --log-level info iptables -A INPUT -j DROP Per quanto riguarda ping (echo-request) e pong (echo-reply) si preferisce specificarli separatamente in base alla catena e alle proprie scelte. 22. Masquerading, port forwarding 22.1. Masquerading Il mascheramento (masquerading) è una tecnica con cui il primo pacchetto di una connessione provenienti dalla rete locale e diretto verso ad esempio internet, subisce da parte del firewall una modifica del campo source address (indirizzo sorgente) presente nell'intestazione IP, in modo che il pacchetto e i successivi sembreranno provenire dal firewall e non dalla macchina della rete locale, nascondendone così l'esistenza. Questa tecnica si utilizza in quanto spesso si possiede un unico indirizzo IP statico (registrato), ma si desidera utilizzarlo con tutte le macchine della propria rete locale ad esempio per collegarsi ad internet. Senza il mascheramento ciò non sarebbe possibile, bisognerebbe infatti registrare un indirizzo statico per ogni macchina della propria rete locale (scomodo e costoso). +---+ 192.168.1.5 |PC1|----+ +---+ | | +---+ | +---+ |MAC|----+-------| |-MASQ--+ INTERNET +---+ | +---+ | 151.99.180.5 +---+ | |PC2|----+ +---+ LAN Linux box Internet [ firewall ] Nell'esempio supponiamo che la macchina PC1 voglia iniziare una connessione con www.kernelnotes.org, quindi invierà un pacchetto che avrà nell'intestazione le seguenti informazioni: indirizzo IP sorgente 192.168.1.5 (indirizzo di PC1) indirizzo IP destinazione 192.130.8.25 (ossia www.kernelnotes.org) +---+ +---+ +---+ |PC1| --->|FW | |KER| +---+ +---+ +---+ [firewall] Quando il pacchetto giunge al firewall, se abbiamo impostato una regola di mascheramento l'intestazione del pacchetto subirà la seguente modifica: indirizzo IP sorgente 151.99.180.5 (indirizzo IP del firewall) indirizzo IP destinazione 192.130.8.25 (www.kernelnotes.org) +---+ +---+ +---+ |PC1| |FW | --->|KER| +---+ +---+ +---+ [firewall] E quindi verrà spedito nella rete. Nota che quando arriverà da www.kernelnotes.org il pacchetto di risposta, questo avrà nell'intestazione le seguenti informazioni: indirizzo IP sorgente 192.130.8.25 (www.kernelnotes.org) indirizzo IP destinazione 151.99.180.5 (indirizzo IP del firewall) +---+ +---+ +---+ |PC1| |FW |<--- |KER| +---+ +---+ +---+ [firewall] A questo punto si nota che il pacchetto è destinato al firewall, ma in realtà deve arrivare a PC1! Nessun problema in quanto il firewall tiene traccia dei pacchetti inviati e mascherati, quando arriva il pacchetto di risposta, il firewall provvederà automaticamente a identificarlo, a modificare l'intestazione e a inviarlo a PC1, in questo modo tutto funziona correttamente. Gran parte del lavoro viene effettuato da netfilter e dai moduli, in modo trasparente all'utente. 22.2. Port-forwarding, load-balancing, proxy trasparente In molti casi invece si ha la necessità di cambiare dove i pacchetti sono destinati, ad esempio potremmo creare una rete con diversi server tra cui uno web e uno mail. +---+ |PC1|----+ +---+ | | Linux box +---+ | +---+ |MAC|----+-------|PC0|---------- INTERNET +---+ | +---+ | | +---+ | | +---+ |PC2|----+ +-|WWW| +---+ | +---+ | +----+ +-|MAIL| +----+ LAN SERVERS Internet [rete locale] Come abbiamo visto abbiamo un solo indirizzo statico (151.99.180.5) ora però vogliamo che dall'esterno i nostri utenti possano accedere al nostro WWW server, in questo caso tutti i pacchetti saranno destinati al firewall (PC0), che dovrà quindi dirottarli rispettivamente al WWW server, se sono pacchetti www, o al server MAIL se sono pacchetti smtp. Per ottenere ciò è necessario che il firewall modifichi l'indirizzo di destinazione dei pacchetti con quello del server corrispondente. +---+ |PC1|----+ +-- + | | Linux box +---+ | +---+<========= |MAC|----+-------|PC0|---------- INTERNET +---+ | +---+ | !! | +---+ | !! | +---+ |PC2|----+ !>>+-|WWW| +---+ | +---+ | +----+ +-|MAIL| +----+ LAN SERVERS Internet [rete locale] In altri casi si può desiderare di distribuire il traffico web su diversi server WWW (load-balancing), in altri ancora semplicemente inviare i pacchetti su porte differenti (proxy trasparente). Tutte queste operazioni richiedono la modifica dell'indirizzo destinazione dei pacchetti, che con netfilter si realizzano utilizzando l'obiettivo DNAT. 23. FTP 23.1. Descrizione Il protocollo FTP (File Trasfert Protocol) è un protocollo molto noto e utilizzato che consente di trasferire file da una macchina ad un'altra. Per effettuare operazioni FTP sono disponibili due modalità: attiva e passiva. La modalità attiva in particolare è nota per i problemi che crea a chi deve impostare un firewall a protezione ad esempio di una rete locale. Il protocollo FTP richiede che inizialmente sia comunque stabilita una connessione FTP, indipendentemente dal tipo (passiva o attiva), tra il client e il server. Questo avviene attraverso una richiesta inviata dal client alla porta 21 (FTP) del server, il quale se disponibile accetterà la connessione. Quindi nel nostro caso il firewall dovrà accettare le richieste inviate da un computer della rete locale (client) ad un server presente nella rete esterna. +---+ ...... |PC1|----+ . +---+ | . | . +---+ | ....> +---+ .......................> +---+ |MAC|----+-------|PC0|---------- INTERNET ----- | | +---+ | +---+ +---+ . LAN Linux Box Internet Server FTP [rete locale] In questo caso non ci sono grossi problemi, se usiamo iptables possiamo utilizzare: # -------------------------------------------------------------------------------- # Appendiamo una regola che accetti tutti i pacchetti provenienti dalla rete locale # (LAN) e destinati alla porta ftp # -------------------------------------------------------------------------------- iptables -A FORWARD -s $LAN -p tcp --dport ftp -j ACCEPT # Appendiamo una regola che accetti tutti i pacchetti provenienti da un computer presente nella rete internet # con porta sorgente ftp e che non siano di richiesta connessione iptables -A FORWARD -s $INTERNET -p tcp ! --syn --sport ftp -j ACCEPT NOTA: è importante impedire che dall'esterno qualcuno cerchi di effettuare connessioni con le macchine della LAN. In genere le macchine della rete locale non dovrebbero offrire alcun servizio (FTP, telnet, mail, ...) all'esterno. Ciò si può realizzare utilizzando l'opzione ! --syn, ossia non accettando pacchetti con il flag SYN (richiesta connessione) impostato. A questo punto è necessario stabilire una seconda connessione, quella che si occuperà dello scambio dei dati. E' possibile utilizzare sia una connessione attiva sia passiva come detto. La modalità attiva crea grossi problemi in quanto è il client a stabilire indirizzo e porta su cui deve avvenire la trasmissione dei dati e ad inviare un pacchetto con queste informazioni e il comando PORT al server. Questa situazione richiede che il server accetti e stabilisca una connessione con il client, solo che se il client è protetto da un firewall, quest'ultimo in genere rifiuta (e deve rifiutare!) questo tipo di connessioni dall'esterno verso l'interno, oltretutto effettuate su una porta qualsiasi. Ciò richiederebbe al firewall di aprire una grossa falla, ossia praticamente accettare tutte le richieste connessioni provenienti dall'esterno. +---+ |PC1|----+ +---------- il pacchetto viene scartato (DROP) +---+ | | | V +---+ | +---+X<...................... +---+ |MAC|----+-------|PC0|---------- INTERNET ----- | | +---+ | +---+ +---+ . LAN Linux Box Internet Server FTP [rete locale] Nel caso della modalità passiva la situazione è esattamente il contrario, il client invia un pacchetto contenente il comando PASV, e poi è il server a inviare al client indirizzo IP e porta per la connessione. Questa situazione è quindi molto simile alla connessione ftp vista all'inizio. Il client si può così connettere. +---+ ...... |PC1|----+ . +---+ | . | . +---+ | ....> +---+ .......................> +---+ |MAC|----+-------|PC0|---------- INTERNET ----- | | +---+ | +---+ +---+ . LAN Linux Box Internet Server FTP [rete locale] Il firewall non crea problemi, la connessione viene stabilita e i dati sono scambiati. In alcuni casi si noterà che la modalità attiva utilizza esclusivamente la porta 20 (ftp-data), questa modifica è stata introdotta da non molto tempo, quindi alcuni server potrebbero non accettarla. In questo caso il meccanismo è lo stesso del caso descritto prima solo che la porta sorgente utilizzata è la porta 20, ciò permette di identificare i pacchetti ftp-data e di ridurre i rischi. # -------------------------------------------------------------------------------- # In questo caso i pacchetti provenienti dall'esterno hanno la porta sorgente # impostata a 20 (ftp-data) ciò permette di facilitare al firewall il riconoscimento. # 1024: indica una porta alta (compresa tra 1024 e 65535). # -------------------------------------------------------------------------------- iptables -A FORWARD -s $INTERNET -p tcp --sport ftp-data -d $LAN --dport 1024: -j ACCEPT iptables -A FORWARD -s $LAN -p tcp ! --syn --sport 1024: -d $INTERNET --dport ftp-data -j ACCEPT NOTA: in questo caso non è possibile utilizzare nella seconda linea l'opzione '--syn', in quanto la connessione è stabilita dal server. Se possibile comunque è meglio utilizzare la modalità passiva, altrimenti è necessario caricare il modulo 'ip_conntrack_ftp.o' (usa insmod ip_conntrack_ftp) il quale si occuperà di cercare nel pacchetto eventuali comandi PORT e quindi ad aggiungere e riscrivere le informazioni in modo che tutto funzioni nel modo corretto. Se si utilizza inoltre il masquerading è necessario caricare anche il modulo 'ip_nat_ftp.o'. Ecco un esempio di come impostare una connessione ftp data passiva: # -------------------------------------------------------------------------------- # La connessione è stabilita da una macchina della rete locale. # Le porte scelte sono due porte alte. # -------------------------------------------------------------------------------- iptables -A FORWARD -s $LAN -p tcp --sport 1024: -d $INTERNET --dport 1024: -j ACCEPT iptables -A FORWARD -s $INTERNET -p tcp ! --syn --sport 1024: -d $LAN --dport 1024: -j ACCEPT NOTA: i browser MSIE, Netscape, Mozilla utilizzano la modalità passiva, quindi non dovrebbero esserci problemi. Altri programmi come quelli a riga di comando (es. ftp) e win utilizzano spesso la modalità attiva per default ma supportano anche la modalità passiva. Il programma ftp di Linux ad esempio usa la modalità attiva, per passare a quella passiva utilizzare: # ftp ftp> passive Passive mode on. ftp> o (o) ... E' necessario segnalare inoltre che alcuni server, in genere pochi e molto vecchi, non supportano la modalità passiva. 23.2. Esempi Esempio 1 Supponiamo che la nostra macchina appartenga ad una LAN e che la vogliamo più sicura, inoltre utilizziamo per comodità il connection tracking. modprobe ip_conntrack_ftp modprobe ip_nat_ftp iptables -A FORWARD -j REJECT # -------------------------------------------------------------------------------- # prima di tutto dobbiamo accettare e far passare i pacchetti destinati alla porta ftp (indispensabile) # -------------------------------------------------------------------------------- iptables -A OUTPUT -p tcp --sport 1024: --dport ftp -j ACCEPT # -------------------------------------------------------------------------------- # modalità attiva utilizzando ftp-data # -------------------------------------------------------------------------------- iptables -A OUTPUT -p tcp --sport 1024: --dport ftp-data -j ACCEPT # -------------------------------------------------------------------------------- # modalità passiva # -------------------------------------------------------------------------------- iptables -A OUTPUT -p tcp --sport 1024: --dport 1024: -j ACCEPT # -------------------------------------------------------------------------------- # altro (es. www, telnet ...) # -------------------------------------------------------------------------------- # ... # -------------------------------------------------------------------------------- # Il resto invece sarà scartato # -------------------------------------------------------------------------------- iptables -A OUTPUT -j REJECT # -------------------------------------------------------------------------------- # se il pacchetto appartiene ad una connessione stabilita (ESTABLISHED) o comunque relativa (RELATED) # allora pacchetto accettato. # -------------------------------------------------------------------------------- iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT # -------------------------------------------------------------------------------- # altrimenti registriamo i dati di questo pacchetto nel file di log e ... # -------------------------------------------------------------------------------- iptables -A INPUT -j LOG --log-level info --log-prefix "FIREWALL (INPUT): " # -------------------------------------------------------------------------------- # ... rifiutiamolo # -------------------------------------------------------------------------------- iptables -A INPUT -j REJECT 24. DoS (Denial of Service) 24.1. Introduzione Gli attacchi di tipo DoS (Denial of Service) sono differenti rispetto ai precedenti (IP spoofing, ...) in quanto l'obiettivo non è più quello di ottenere l'accesso ad una rete, ma bensì di rendere un servizio (www, ftp, mail, ...) offerto da una macchina indisponibile agli utenti, utilizzando diverse tecniche. Le principali consistono nell'esaurire le risorse della macchina, in particolare memoria e spazio su disco fino a causarne addirittura il blocco, oppure nel consumare la bandwidth a disposizione in modo che la "vittima" non sia più in grado di operare correttamente, di stabilire o accettare nuove connessioni, di inviare pacchetti nella rete. Questi attacchi possono quindi sfruttare i difetti e limiti delle implementazioni dello stack TCP/IP, oppure il meccanismo di inizio connessione (3-way handshake), o ancora macchine configurate male. In molti casi per risolvere il problema di alcuni di questi attacchi è stato necessario correggere lo stack TCP/IP, e ricercare vulnerabilità simili. Per realizzare attacchi DoS viene spesso coinvolto anche l'IP spoofing, quindi come primo passo per prevenire i DoS è senz'altro raccomandato bloccare questo attacco. In alcuni casi è possibile effettuare un attacco DoS perfino utilizzando un vecchio Pc dotato di un modem lento contrapponendolo ad una macchina o rete veloce. Questo tipo di attacco è noto come attacco asimmetrico. Tra i DoS più noti ci sono: TCP SYN flooding, smurfing, UDP port. Molto recenti sono inoltre gli attacchi cosiddetti DDoS (Distributed Denial of Service). Questo tipo di attacco ha le stesse funzioni del classico DoS solamente che l'attacco viene effettuato sfruttando più macchine. In questo modo il traffico che si può generare è talmente notevole da poter mettere in difficoltà anche grandi nomi come Yahoo, Amazon, ... che dispongono di notevoli risorse. Per effettuare un DDoS è necessario comunque impossessarsi di diverse macchine della rete, in genere non è difficile trovare macchine/server configurate male da "conquistare". Successivamente l'attacker provvederà ad installare dei programmi, spesso troiani, che permetteranno di nasconderne la presenza, e quindi il programmma che controllato da remoto permetterà di sferrare l'attacco. Questa è sicuramente la fase più complicata. Questi attacchi sono notevoli e difficilmente contrastabili, tra le poche soluzioni c'è sicuramente quella di migliorare la sicurezza delle macchine presenti in internet, in modo che non possano essere conquistate e utilizzate per questi attacchi. 24.2. TCP SYN Flooding Questo attacco riguarda in particolare i protocolli IP+TCP e ancora una volta è la fase di inizio connessione ad essere presa di mira. In particolare lo scopo non è quello di accedere ad una macchina ma piuttosto quello di esaurire e consumare la banda a disposizione della macchina "vittima" in modo che non riesca più a soddisfare le richieste di connessione ai servizi (www, ftp, ...) effettuate dagli utenti e ad operare correttamente. Come già descritto quando un utente vuole stabilire una connessione con una macchina deve inviare un pacchetto con flag SYN impostato. Il server riceve la richiesta e inoltra un pacchetto SYN-ACK in risposta allocando inoltre spazio in memoria dove poter memorizzare le informazioni sulla connessione. A questo punto attende il pacchetto ACK di conferma. L'attacker però non invia questo pacchetto lasciando volontariamente la connessione pendente (half-open connection), e anzi continua a inviare a raffica una moltitudine di pacchetti di inizio connessione (SYN). Il server li riceverà e allocherà per ciascuno di essi altra memoria. In molti casi questa situazione porterà il server ad esaurire la memoria, a non poter soddisfare altre richieste di connessione, e addirittura al crash. E' necessario specificare che in genere un server o una qualsiasi macchina che offre dei servizi accetta solo un determinato numero di richieste connessione, di solito 5 per porta, inoltre se un pacchetto di ACK non arriva entro un certo limite di tempo allora le connessioni pendenti sono annullate e lo spazio di memoria allocato recuperato. Ciò però potrebbe non essere sufficiente se i pacchetti dovessero arrivare a raffica in un brevissimo lasso di tempo. Questo attacco è diffuso e in genere è utilizzato anche l'IP spoofing per nascondere l'origine dell'attacco. Linux è in grado di contrastarlo però è necessario compilare il kernel con la voce "IP: TCP syncookie support" (Networking options) selezionata e impostare il parametro tcp_syncookies da script o linea di comando: if [ -e /proc/sys/net/ipv4/tcp_syncookies ] then echo 1 > /proc/sys/net/ipv4/tcp_syncookies fi 24.3. Smurfing Lo smurfing è un altro attacco DoS basato sempre sull'IP spoofing e sui pacchetti ICMP ping, utilizzati in genere per verificare se una macchina è presente e attiva nella rete. Questo attacco consiste nell'inviare un pacchetto ICMP echo request (ping) con indirizzo sorgente fasullo e con indirizzo destinazione l'indirizzo broadcast di una rete. L'indirizzo broadcast è utilizzato per inviare un pacchetto contemporaneamente a tutte le macchine di una rete, ad esempio per una rete 192.168.0.0/24 l'indirizzo di broadcast corrisponde a 192.168.0.255, per una rete 192.168.0.0/16 a 192.168.255.255. Graficamente si può rappresentare in questo modo: +---+ +---+ |PC1|-<<. | | [ATTACKER] +---+ ^ +---+ +---+ ^ 213.76.5.2 |PC2|-<<. +---+ | +---+ |<<<<<| | <---- o -----. +---+ v +---+ \_______________________ pacchetto ping "broadcast" |PC3|-<<. [ROUTER] +---+ +---+ v | | [VITTIMA] +---+ v +---+ |PC4|-<<. 213.72.10.1 +---+ [LAN] Il pacchetto ICMP echo request (ping), con indirizzo destinazione l'indirizzo broadcast, è ricevuto dal router che provvede quindi a inoltrarlo a tutte le macchine della rete che in genere risponderanno inviando un pacchetto echo reply (pong) alla macchina mittente. In questo caso i pong arriveranno alla macchina "vittima", con indirizzo IP pari a quello indicato dall'attacker nel pacchetto. Se la banda a disposizione della vittima dovesse essere limitata questo flusso di pacchetti potrebbe consumarla rapidamente, impedendo quindi alla macchina di stabilire connessioni e di operare correttamente. +---+>>>>>. +---+ |PC1|---+ v | | [ATTACKER] +---+ | v +---+ +---+>>>>>. 213.76.5.2 |PC2|---+ v +---+ +---+ |_v_>>>>>| |>>>>>>>>>>>>>>. +---+>>>>>. +---+ v |PC3|---+ ^ [ROUTER] +---+ +---+ | ^ | | [VITTIMA] +---+>>>>>. +---+ |PC4|---+ 213.72.10.1 +---+ [LAN] In questo caso la soluzione per proteggere la propria rete da questo attacco richiede di impostare il ROUTER affinché ignori, scarti i pacchetti IP broadcast, ossia aventi come indirizzo destinazione l'indirizzo broadcast della propria rete. Per quanto riguarda le macchine della rete locale è consigliato impostarle in modo che non rispondano a pacchetti ICMP echo request (ping) aventi come indirizzo destinazione l'indirizzo broascast. Quest'ultimo caso è importante perché se un attacker riesce ad accedere ad una delle macchine della rete locale è in grado di aggirare il router e di utilizzare un attacco smurf dall'interno. Con Linux è disponibile il parametro 'icmp_ignore_echo_broadcast' che può essere impostato per ignorare gli icmp echo request (ping) broadcast. Per quanto riguarda il firewall, se si usa il connection tracking ('-m state -state ESTABLISHED,RELATED') questo tipo di attacco proveniente dall'esterno è respinto. In caso contrario è meglio scartare specificatamente questi pacchetti: ## Caso di pacchetti icmp echo-request (ping) # iptables -A FORWARD -i eth0 -p icmp -icmp-type ping -d 255.255.255.255 -j DROP 24.4. UDP Port DoS Esistono attacchi DoS che utilizzano anche il protocollo UDP (User Datagram Protocol). In questo caso quando due macchine trasmettono dati utilizzando due servizi UDP che generano entrambe dell'output (es. chargen ed echo) possono generare un traffico così notevole da causare una situazione di DoS. In genere sono proprio i servizi chargen ed echo ad essere utilizzati per questo attacco, quindi se possibile è raccomandabile disabilitarli modificando il file /etc/inetd.conf nelle macchine della propria rete locale e impostare il firewall in modo che questi servizi siano filtrati. E' inoltre raccomandato disabilitare, filtrare allo stesso modo tutti i servizi UDP che non sono necessari o utilizzati. 24.5. LOG In genere può essere utile registrare le informazioni riguardanti quei pacchetti che si ritengono anomali. Netfilter e iptables permettono di registrare queste informazioni utilizzando l'obiettivo LOG (-j LOG). I pacchetti che soddisferanno la regola saranno registrati per poter essere poi analizzati. Il problema che può però sorgere è che qualcuno potrebbe intenzionalmente inviare una raffica di pacchetti affinchè siano registrati. Siccome le registrazioni richiedono spazio su disco, infatti in genere sono memorizzati nel file /var/log/messages, potrebbero essere usate per un attacco DoS, mirato a esaurire lo spazio disponibile. In questo caso è raccomandato utilizzare assieme a LOG anche il modulo limit, che consente di specificare quante registrazioni effettuare in un dato arco di tempo (es. 10 registrazioni ogni ora). # -------------------------------------------------------------------------------- # connessioni telnet accettate # -------------------------------------------------------------------------------- iptables -A INPUT -p tcp -dport telnet -j ACCEPT # -------------------------------------------------------------------------------- # tutto gli altri pacchetti sono registrati (10 pacchetti ogni ora) e ... # -------------------------------------------------------------------------------- iptables -A INPUT -m limit -limit 10/h -j LOG -log-level info -log-prefix "Firewall: " # -------------------------------------------------------------------------------- # ... scartati # -------------------------------------------------------------------------------- iptables -A INPUT -j DROP 25. Nessus e nmap 25.1. Introduzione Per effettuare un controllo sul grado di sicurezza e affidabilità della propria rete è possibile utilizzare i programmi Nessus e nmap. 25.2. nmap Nmap è un'utility per l'esplorazione e l'auditing della propria rete. Disponibile per quasi tutte i sistemi UNIX (Linux, FreeBSD, NetBSD, OpenBSD, Solaris ...) attualmente non ne esiste una versione per Windows. Supporta ping scanning (determina quali host sono attivi), diverse tecniche di port scanning (determinano quali servizi offrono gli host presenti nella rete) e TCP/IP fingerprinting (identificazione del sistema operativo utilizzato dall'host remoto). Inoltre offre specificazione delle porte, obiettivi flessibili, decoy scanning, sunRPC scanning, reverse-identd scanning, ... E' disponibile sia in versione per X sia per terminale (Nmap). In particolare per X esistono due front-end grafici: · NmapFE - usa la libreria GTK+ (GNOME) · kmap - usa la libreria qt (KDE) Nominato "Security Product of the Year" dalla Info World e Codetalker Digest. 25.2.1. Dove si trova ? nmap è reperibile alla pagina www.insecure.org/nmap/ <http://www.insecure.org/nmap/>. Nel momento in cui scrivo sono disponibili, sia in formato tgz che rpm, la versione stabile 2.53 e la beta 1 della nuova versione 2.54. 25.2.2. Installazione Per installare il formato tarball (.tgz) e necessario eseguire i seguenti comandi: # gzip -cd nmap-VERSION.tgz | tar -xvf # NOTA: al posto di VERSION inserire la versione di nmap utilizzata es. nmap-2.53.tgz # cd nmap-VERSION # ./configure # make # su root # make install Per installare la versione x86/rpm utilizzare: # rpm -vhU ftp://ftp.server51.freshmeat.net/pub/nmap/nmap-2.53-1.rpm # rpm -vhU ftp://ftp.server51.freshmeat.net/pub/nmap/nmap-frontend-0.2.53-1.i386.rpm Nota: il primo comando installa nmap, la seconda installa l'interfaccia grafica che fa uso di X e della libreria GTK+. 25.2.3. Esecuzione Per eseguire un semplice test sulla propria macchina utilizzare il comando da terminale: # nmap -v -sS -O 127.0.0.1 Starting nmap V. 2.30BETA17 by fyodor@insecure.org ( www.insecure.org/nmap/ ) Host localhost.localdomain (127.0.0.1) appears to be up ... good. Initiating SYN half-open stealth scan against localhost.localdomain (127.0.0.1) Adding TCP port 21 (state Open). Adding TCP port 514 (state Open). Adding TCP port 513 (state Open). Adding TCP port 98 (state Open). Adding TCP port 23 (state Open). Adding TCP port 79 (state Open). Adding TCP port 113 (state Open). Adding TCP port 6000 (state Open). The SYN scan took 180 seconds to scan 1517 ports. For OSScan assuming that port 21 is open and port 30938 is closed and neither are firewalled sendto in send_tcp_raw: sendto(3, packet, 60, 0, 127.0.0.1, 16) => Operazione non permessa For OSScan assuming that port 21 is open and port 32223 is closed and neither are firewalled sendto in send_tcp_raw: sendto(3, packet, 60, 0, 127.0.0.1, 16) => Operazione non permessa For OSScan assuming that port 21 is open and port 40569 is closed and neither are firewalled sendto in send_tcp_raw: sendto(3, packet, 60, 0, 127.0.0.1, 16) => Operazione non permessa Interesting ports on localhost.localdomain (127.0.0.1): (Ports scanned but not shown below are in state: filtered) Port State Service 21/tcp open ftp 23/tcp open telnet 79/tcp open finger 98/tcp open linuxconf 113/tcp open auth 513/tcp open login 514/tcp open shell 6000/tcp open X11 TCP Sequence Prediction: Class=random positive increments Difficulty=750295 (Good luck!) Sequence numbers: 6B85B59E 6B85B59E 6B6DA5EE 6B6DA5EE 6B844A25 6B844A25 No OS matches for host (If you know what OS is running on it, see http://www.insecure.org/cgi-bin/nmap-submit.cgi). TCP/IP fingerprint: TSeq(Class=RI%gcd=1%SI=B69A5) TSeq(Class=RI%gcd=1%SI=B72D1) TSeq(Class=RI%gcd=1%SI=B72D7) T1(Resp=Y%DF=Y%W=2D24%ACK=S++%Flags=AS%Ops=MNNTNW) T2(Resp=N) T3(Resp=Y%DF=Y%W=2D24%ACK=S++%Flags=AS%Ops=MNNTNW) T4(Resp=Y%DF=Y%W=0%ACK=O%Flags=R%Ops=) T5(Resp=Y%DF=Y%W=0%ACK=S++%Flags=AR%Ops=) T6(Resp=Y%DF=Y%W=0%ACK=O%Flags=R%Ops=) T7(Resp=Y%DF=Y%W=0%ACK=S++%Flags=AR%Ops=) PU(Resp=Y%DF=Y%TOS=C0%IPLEN=164%RIPTL=148%RID=E%RIPCK=E%UCK=E%ULEN=134%DAT=E) 25.2.4. Documentazione La documentazione di nmap si trova sempre al sito citato precedentemente www.insecure.org/nmap/ <http://www.insecure.org/nmap/> sono disponibili la man page (formato HTML), un articolo su nmap e il port scanning e una guida. 25.3. Nessus Nessus è un progetto che ha come scopo quello di fornire alla comunità uno strumento potente, facile, free per analizzare e scoprire le vulnerabilità di una rete. Nessus è composto da due parti: un server (nessusd) e un client (nessus). Per il corretto funzionamento è necessario installarli entrambi. Il suo funzionamento è semplice, attraverso il client (nessus) è possibile impostare gli host (computer) della rete da sottoporre ai test, quali e che tipo di test effettuare, oltre ad altre opzioni (es. dove salvare i risultati, in quale formato, ...). Il client (nessus) una volta ricevute queste informazioni contatta il server nessusd che si occuperà di effettuare i vari test selezionati. Il client (nessus) e il server (nessusd) possono essere installati nella stessa macchina oppure su macchine diverse. Esistono inoltre client grafici per Windows, Posix/GTK+ (Linux, Solaris, ...) e JAVA. 25.3.1. Dove si trova ? Nessus è reperibile all'indirizzo www.nessus.org/download.html <http://www.nessus.org/download.html>, esiste anche un sito dedicato in italiano all'indirizzo url="http://www.it.nessus.org" "name="www.it.nessus.org.">. Sono presenti due link per Windows e Java, questi link permetteno di prelevare i rispettivi CLIENT grafici. Non sono invece disponibile per questi sistemi il server nessusd, è necessario per forza usare Linux o altro sistema Unix. E' raccomandato inoltre installare anche nmap in quanto Nessus è in grado di rilevarne la presenza e di utilizzarlo per effettuare ulteriori controlli. Per Linux, FreeBSD, Solaris selezionare il link Posix download page quindi se si ha una distribuzione Linux che supporta il formato rpm prelevare il file .rpm da uno dei siti ftp indicati, altrimenti prelevare i tarball (sempre da uno dei siti ftp indicati): libsnal-1.0.3.tar.gz (218Kb) nessus-core-1.0.3.tar.gz (497Kb) nessus-libraries-1.0.3.tar.gz (1512Kb) nessus-plugins-1.0.3.tar.gz (365Kb) L'installazione dei pacchetti .rpm è semplice e rapida, mentre per installare i tarball è necessario un po' di lavoro in più. Prima di tutto si devono scompattare i file: tar -zxvf nessus-libraries-x.x.tar.gz tar -zxvf libsnal-x.x.tar.gz tar -zxvf nessus-core.x.x.tar.gz tar -zxvf nessus-plugins.x.x.tar.gz Poi ci si deve assicurare che nel PATH sia presente /usr/local/bin altrimenti usare il comando: # export PATH=$PATH:/usr/local/bin Altro passo necessario è verificare che /usr/local/lib sia presente nel file /etc/ld.so.conf, altrimenti impartire i seguenti comandi: # echo "/usr/local/lib" >> /etc/ld.so.conf # ldconfig 25.3.2. nessus-libraries Completate le fasi precedenti è necessario compilare i sorgenti cominciando da nessus-libraries. Nota: se si pensa di utilizzare i client grafici di Windows o Java allora non si avrà bisogno del cypher quindi si potranno usare i seguenti comandi: # cd nessus-libraries # ./configure --disable-cipher # make # make install Altrimenti, se si desidera utilizzare esclusivamente Linux, usare: # cd nessus-libraries # ./configure # make # make install Il passo successivo è quello di compilare libnasl: cd nessus-libnasl # ./configure # make # make install 25.3.3. nessus-core A questo punto è necessario accedere alla directory nessus-core e poi specificare se si intende utilizzare l'interfaccia grafica (richiede la libreria GTK+ e X!) o il terminale. Se la libreria GTK+ è installata (se GNOME o gimp sono installati l'avete) potete usare i seguenti comandi: cd nessus-core # ./configure # make # make install Altrimenti è sempre possibile utilizzare nessus dalla linea comando del terminale: cd nessus-core # ./configure --disable-gtk # make # make install 25.3.4. nessus-plugins Infine compilare nessus-plugins: cd nessus-plugins # ./configure # make # make install A questo punto se tutto è stato eseguito correttamente dovrebbero essere presenti nella directory /usr/local/bin i seguenti comandi: nasl, nasl-config, nessus, nessus-build, nessus-config. Se non c'è nessus allora è stato sbagliato qualcosa, ripetere la compilazione di nessus-core e fare attenzione al messaggio visualizzato alla fine. Il passo successivo consiste nel configurare nessusd, a questo scopo è necessario impostare il file /usr/local/etc/nessus/nessusd.conf. Se si hanno dei dubbi è possibile leggere e prelevare il file nessusd.conf.txt all'indirizzo www.nessus.org/demo/nessusd.conf.txt <http://www.nessus.org/demo/nessusd.conf.txt> Non resta quindi che aggiungere un utente con il comando: # nessus-adduser E avviare il server nessusd: # nessusd -D A questo punto si può eseguire un client windows, java oppure se si usa Linux e X il comando: # nessus Se si è compilato con l'opzione --disable-gtk allora è necessario innanzi tutto leggere l'help: # nessus --help L'help è abbastanza chiaro, comunque un esempio di utilizzo può essere il seguente: # nessus 192.168.0.154 3001 marco myhosts.txt result.txt Nota: 192.168.0.154 è l'indirizzo della macchina che esegue nessusd 3001 è la porta di default usata da nessusd per i test marco è il nome dell'utente che ho creato precedentemente myhosts.txt è un file di testo in cui ho inserito gli indirizzi IP delle macchine da sottoporre ai test result.txt è il file in cui voglio che siano memorizzati i risultati dei test Se si desidera che il file con i risultati sia in formato html è possibile specificare l'opzione '-T html'. Altri formati disponibili sono: text, tex, nsr. Segue un esempio di output (html) ottenuto: 127.0.0.1 Repartition of the level of the security problems : [Back to the index] List of open ports : ftp (21/tcp) telnet (23/tcp) finger (79/tcp) linuxconf (98/tcp) (Security warnings found) auth (113/tcp) login (513/tcp) shell (514/tcp) printer (515/tcp) unknown (1027/tcp) unknown (1032/tcp) unknown (1033/tcp) unknown (1035/tcp) unknown (1036/tcp) unknown (3001/tcp) unknown (6000/tcp) general/tcp (Security notes found) general/udp (Security notes found) [ back to the list of ports ] Warning found on port linuxconf (98/tcp) Linuxconf is running on this port [ back to the list of ports ] Information found on port general/tcp Nmap found that this host is running Linux 2.1.122 - 2.2.14 [ back to the list of ports ] Information found on port general/udp For your information, here is the traceroute to 127.0.0.1 : 127.0.0.1 This file was generated by Nessus, the open-sourced security scanner. Per ulteriori informazioni vedere www.nessus.org/demo/first.html <http://www.nessus.org/demo/first.html> Per selezionare i plugin e apportare altre modifiche riguardanti il funzionamento del programma nessus, modificare il file '.nessusrc'. Sono disponibili inoltre numerosi script in grado di effettuare altri controlli riguardanti la sicurezza. E' possibile reperirli alla pagina www.nessus.org/scripts.html <http://www.nessus.org/scripts.html>. Dopo il download è sufficiente copiarli nella directory /usr/local/lib/nessus/plugins/ o quella usata (vedi nessusd.conf), quindi riavviare nessusd. Se il file ha suffisso .tar.gz è necessario "scompattare" il file nella directory sopra indicata. Esiste anche un metodo più semplice per scaricarli e installarli, ossia eseguire il programma (da root): nessus-update-plugins 25.3.5. Documentazione La documentazione di Nessus è reperibile all'indirizzo www.nessus.org/documentation.html <http://www.nessus.org/documentation.html> sono disponibili istruzioni su come effettuare l'installazione, pagine dimostrative con immagini, una FAQ, le man pages e altro. 26. Risorse Per scrivere questo documento ho trovato di notevole interesse i seguenti siti: · www.linux-firewall-tools.com/LINUX/ <http://www.linux-firewall- tools.com/LINUX/> · www.robertgraham.com/pubs/network-intrusion-detection.html <http://www.robertgraham.com/pubs/network-intrusion-detection.html> · www.pointman.org <http://www.pointman.org> (pmfirewall) · www.interhack.net/pubs/fwfaq/ <http://www.interhack.net/pubs/fwfaq/> (FAQ) 27. Marchi registrati Tutti i marchi sono registrati. Linux è un marchio registrato di Linus Torvalds. MS-DOS, Windows NT sono marchi registrati di Microsoft Corporation. Apple e MacOS sono marchi registrati da Apple Computer Inc. 28. Appendice 28.1. Intestazione IP (Internet Protocol) 0 1 2 3 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 ----------------------------------------------------------------- |Version| IHL |Type of Service| Total Length | ----------------------------------------------------------------- | Identification |Flags| Fragment Offset | ----------------------------------------------------------------- | Time to Live | Protocol | Header Checksum | ----------------------------------------------------------------- | Source Address | ----------------------------------------------------------------- | Destination Address | ----------------------------------------------------------------- | Options | Padding | ----------------------------------------------------------------- Version Versione del protocollo utilizzata. Attualmente è utilizzato l'IPv4 è comunque già disponibile anche la versione più recente dell'internet protocol (IPv6). IHL Lunghezza dell'intestazione espressa in parole di 32 bit. Type of Service (TOS) Consente di specificare il tipo di servizio desiderato (ritardo minimo, massimo throughput, massima affidabilità, costo minimo). In particolare contiene 3 bit per indicare la precedenza (Precedence), 3 flag (D, T ed R), e 2 bit inutilizzati. Total length Lunghezza totale del pacchetto (intestazioni e dati). La lunghezza massima prevista è di 65535 byte. Identification Questo campo permette di stabilire a quale pacchetto appartiene il frammento arrivato. In caso di frammentazione solo il primo frammento ha sia l'intestazione IP sia l'intestazione UDP o TCP, il secondo e i successivi hanno solo l'intestazione IP. Flags Il campo flags è composto da 3 bit, il primo è inutilizzato, il secondo detto DF (Don't Fragment) se impostato serve a segnalare di non frammentare i pacchetti. Il terzo bit MF (More Fragments) serve ad indicare che il "pacchetto" è in realtà un frammento, a parte l'ultimo tutti i frammenti hanno questo bit impostato. Fragment Offset Serve per specificare in quale posizione del pacchetto corrente si trova questo frammento. Time to Live (TTL) Questo campo è impostato con un valore che stabilisce quanto può vivere un pacchetto. In genere ad ogni salto da un host all'altro è decrementato. Quando un host riceve un pacchetto con campo TTL pari a zero provvede ad eliminarlo. Questa operazione è necessaria per impedire che i pacchetti continuino a viaggiare nella rete a tempo indeterminato. Protocol Un pacchetto IP incapsula in genere un pacchetto TCP o ICMP o UDP. Questo campo è utilizzato per specificare il tipo di pacchetto. Header checksum Questo campo è utilizzato per controllare se il pacchetto è corretto o se è stato danneggiato durante il passaggio da un host all'altro. Source Address Indirizzo IP sorgente dell'host che ha inviato il pacchetto Destination Address Indirizzo IP destinazione ossia indirizzo IP dell'host a cui è destinato il pacchetto. Options Questo campo è stato aggiunto per supportare le nuove caratteristiche, informazioni richieste da nuove versioni del protocollo. 28.2. Intestazione TCP (Transmission Control Protocol) 0 1 2 3 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 ----------------------------------------------------------------- | Source Port | Destination Port | ----------------------------------------------------------------- | Sequence Number | ----------------------------------------------------------------- | Acknowledgment Number | ----------------------------------------------------------------- | Data | |U|A|P|R|S|F| | | Offset| Reserved |R|C|S|S|Y|I| Window | | | |G|K|H|T|N|N| | ----------------------------------------------------------------- | Checksum | Urgent Pointer | ----------------------------------------------------------------- Source Port Il campo Source Port (porta sorgente) è indispensabile per specificare a quale porta devono essere indirizzati i pacchetti tcp di risposta. Destination Port Destination Port (porta destinazione) serve per specificare a quale porta (telnet, www, ...) è destinato il pacchetto tcp. Sequence Number e Acknowledgment Number Numeri di sequenza utilizzati per riordinare i pacchetti ed effettuare controlli. Data Offset Questo campo è utilizzato per specificare la lunghezza in parole di 32 bit dell'intestazione TCP. Reserved Campo riservato per uso futuro. URG,ACK,PSH,RST,SYN,FIN Flag (1 bit ciascuno) con ciascuno con diversa funzione. URG è impostato per segnalare dati urgenti. ACK è utilizzato per indicare che il pacchetto è di conferma. PSH (PUSH) da impostare se si desidera che il pacchetto giunga a destinazione e direttamente all'applicazione senza essere memorizzato temporaneamente in un buffer. RST (RESET) è impostato quando si desidera reinializzare una connessione a causa di problemi. SYN è utilizzato per indicare che il pacchetto è di richiesta connessione. La "three way handshake" utilizzata per stabilire una connessione richiede l'invio di pacchetti SYN e ACK. FIN quando si desidera chiudere una connessione stabilita è richiesto l'invio di un pacchetto con il flag FIN impostato. Window Size Questo campo è utilizzato per specificare quanti byte possono essere spediti a partire dal byte confermato. Checksum Come nel caso dell'intestazione IP, anche TCP prevede un campo dedicato alla verifica della correttezza dell'intestazione. Urgent Pointer E' utilizzato per specificare lo scostamento in byte a partire dal numero di sequenza attuale dove possono essere trovati i dati urgenti. 28.3. Intestazione UDP (User Datagram Protocol) 0 1 2 3 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 ----------------------------------------------------------------- | Source Port | Destination Port | ----------------------------------------------------------------- | Lenght | Checksum | ----------------------------------------------------------------- Source Port Porta sorgente. Destination Port Porta destinazione. Lenght Dimensione del pacchetto (intestazione + dati). Checksum Utilizzato per garantire l'affidabilità e la correttezza delle informazioni contenute. Anche i pacchetti UDP sono incapsulati in pacchetti IP. 28.4. Intestazione ICMP (Internet Control Message Protocol) I pacchetti ICMP possono avere intestazioni con campi diversi, tutti comunque hanno i campi Type, Code e Checksum. Seguono le intestazioni dei pacchetti ICMP "destination unreachable" (tipo 3) e "echo- request/reply" (tipo 8 e 0): Destination unreachable 0 1 2 3 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 ----------------------------------------------------------------- | Type | Code | Checksum | ----------------------------------------------------------------- | Unused | ----------------------------------------------------------------- echo-request/echo-reply 0 1 2 3 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 ----------------------------------------------------------------- | Type | Code | Checksum | ----------------------------------------------------------------- | Identifier | Sequence number | ----------------------------------------------------------------- Type Tipo di pacchetto icmp. I tipi disponibili sono: Echo Reply (0), Destination Unreachable (3), Source Quench (4), Redirect (5), Echo (8), Time Exceeded (11), Parameter Problem (12), Timestamp (13), Timestamp Reply (14), Information Request (15) e Information Reply (16). Code Codice associato. Ad esempio al tipo "Destination Unreachable" può essere associato: net unreachable (code=0), host unreachable (1), protocol unreachable (2), port unreachable (3), fragmentation needed and DF set (4), source route failed (5). Identifier e Sequence number Utilizzati per identificare i pacchetti icmp. 28.5. Servizi I seguenti servizi presentano dei problemi per quanto riguarda la sicurezza se si permette di accedervi dall'esterno. Se non servono allora è il caso di filtrarli. NOME SERVIZIO PORTA PROTOCOLLO ------------- ----- ---------- echo 7 TCP/UDP systat 11 TCP netstat 15 TCP bootp 67 UDP tftp 69 UDP link 87 TCP supdup 95 TCP sunrpc 111 TCP/UDP NeWS 144 TCP snmp 161 UDP xdmcp 177 UDP exec 512 TCP login 513 TCP shell 514 TCP printer 515 TCP biff 512 UDP who 513 UDP syslog 514 UDP uucp 540 TCP route 520 UDP openwin 2000 TCP NFS 2049 UDP/TCP X11 6000 6000+n TCP n = numero max. di server X. Fonte: www.linux-firewall-tools.com/linux/papers/AUSCERT_checklist1.1 <http://www.linux-firewall- tools.com/linux/papers/AUSCERT_checklist1.1>