Archivi tag: dns

Logica di funzionamento del DNS (Domain Name System)

Prima di approfondire un argomento che avevo già trattato tempo addietro, ovvero il DNS cache poisoning (vedi qui per ulteriori dettagli), è utile illustrare la logica di funzionamento su cui si basa il Domain Name System.

Esistono, in soldoni, 2 tipologie di query DNS:
1) ricorsive;
2) iterative.

Supponiamo che il client voglia risolvere l’FQDN www.ciao.com

Nel primo caso il client contatterà il proprio resolver (ad esempio il nameserver dell’ISP) sottoponendogli la query. Se la risposta non è contenuta all’interno
della sua cache, esso effettuerà una query ai root nameserver. I root nameserver forniranno una risposta di tipo referral (con ANSWER SECTION vuota ed AUTHORITY SECTION non vuota), contenente una lista di nameserver da contattare per il top level domain (in gergo TLD) .com.
A questo punto il resolver contatterà uno dei nameserver autoritativi appena individuati, il quale fornirà una risposta di tipo referral indicando il nameserver autoritativo per il dominio cercato. Infine, quest’ultimo verrà interrogato e fornirà una risposta alla query (ANSWER SECTION non vuota) indicando l’indirizzo IP relativo al record A (www) ricercato (sempre se il suddetto record esiste).
La risposta, una volta giunta al resolver, verrà quindi girata al client.

recursiveDa notare che sia i root nameserver che i nameserver autoritativi per i TLD forniscono esclusivamente risposte di tipo referral, ergo funzionano solo
in modalità iterativa. Infatti, pensate a cosa accadrebbe se ciascun root nameserver interrogato (13 in tutto) iniziasse a fare query ricorsive per individuare
un determinato indirizzo IP… sarebbe una scelta davvero sconveniente (per usare un’espressione moderata) sia in termini di carico che in termini di latenza.

Inoltre, ciascun software che svolge funzioni di namserver utilizza degli algoritmi ben precisi per individuare il server a cui sottoporre la query (root, TLD o autoritativo che sia).
Nella fattispecie, bind usa la tecnica dell’RTT (Round Trip Time), grazie alla quale dovrebbe riuscire ad individuare il namserver più peformante (che coincide con quello che ha risposto più velocemente alla query).

Per ciò che concerne le query iterative, esse prevedono (in generale) il coinvolgimento diretto del client. Per prima cosa esso sottoporrà la query al proprio resolver, che gli risponderà con la lista dei root nameserver (risposta di tipo referral). Il root nameserver successivamente contattato dal client, gli fornirà una risposta di tipo referral indicando una lista di namserver autoritativi per il TLD .com. Dopodichè il client sottoporrà la query ad uno dei predetti nameserver, il quale gli fornirà come risposta una lista dei namserver autoritativi per il dominio ciao.com.
Infine, il client contatterà uno dei nameserver autoritativi per ciao.com che gli girerà la risposta contenente l’indirizzo IP per www.ciao.com (sempre se il record esiste).

Un esempio di query iterativa più essere facilmente ricavato utilizzando dig con l’opzione +trace, ad esempio:

[root@linuxbox ~]# dig +trace www.ciao.com

; <<>> DiG 9.8.2rc1-RedHat-9.8.2-0.37.rc1.el6_7.2 <<>> +trace www.ciao.com
;; global options: +cmd
.                       440639  IN      NS      b.root-servers.net.
.                       440639  IN      NS      m.root-servers.net.
.                       440639  IN      NS      h.root-servers.net.
.                       440639  IN      NS      k.root-servers.net.
.                       440639  IN      NS      a.root-servers.net.
.                       440639  IN      NS      i.root-servers.net.
.                       440639  IN      NS      f.root-servers.net.
.                       440639  IN      NS      e.root-servers.net.
.                       440639  IN      NS      j.root-servers.net.
.                       440639  IN      NS      d.root-servers.net.
.                       440639  IN      NS      l.root-servers.net.
.                       440639  IN      NS      g.root-servers.net.
.                       440639  IN      NS      c.root-servers.net.
;; Received 496 bytes from 192.168.1.1#53(192.168.1.1) in 38 ms

com.                    172800  IN      NS      a.gtld-servers.net.
com.                    172800  IN      NS      b.gtld-servers.net.
com.                    172800  IN      NS      c.gtld-servers.net.
com.                    172800  IN      NS      d.gtld-servers.net.
com.                    172800  IN      NS      e.gtld-servers.net.
com.                    172800  IN      NS      f.gtld-servers.net.
com.                    172800  IN      NS      g.gtld-servers.net.
com.                    172800  IN      NS      h.gtld-servers.net.
com.                    172800  IN      NS      i.gtld-servers.net.
com.                    172800  IN      NS      j.gtld-servers.net.
com.                    172800  IN      NS      k.gtld-servers.net.
com.                    172800  IN      NS      l.gtld-servers.net.
com.                    172800  IN      NS      m.gtld-servers.net.
;; Received 490 bytes from 192.203.230.10#53(192.203.230.10) in 4323 ms

ciao.com.               172800  IN      NS      dns2.progtech.net.
ciao.com.               172800  IN      NS      dns.progtech.net.
;; Received 111 bytes from 192.33.14.30#53(192.33.14.30) in 623 ms

www.ciao.com.           86400   IN      A       185.60.164.38
ciao.com.               86400   IN      NS      dns2.progtech.net.
ciao.com.               86400   IN      NS      dns.progtech.net.
;; Received 127 bytes from 80.190.149.57#53(80.190.149.57) in 82 ms

Per completezza, riporto il contenuto di una risposta ad una quey DNS, con le relative sezioni (QUERY, ANSWER, AUTHORITY, ADDITIONAL)

[root@linuxbox ~]# dig libero.it

; <<>> DiG 9.8.2rc1-RedHat-9.8.2-0.37.rc1.el6_7.2 <<>> libero.it
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 23298
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 2, ADDITIONAL: 2

;; QUESTION SECTION:
;libero.it.                     IN      A

;; ANSWER SECTION:
libero.it.              300     IN      A       37.9.239.32

;; AUTHORITY SECTION:
libero.it.              10799   IN      NS      n2.libero.it.
libero.it.              10799   IN      NS      n1.libero.it.

;; ADDITIONAL SECTION:
n2.libero.it.           10799   IN      A       156.154.67.47
n1.libero.it.           10799   IN      A       156.154.66.47

;; Query time: 256 msec
;; SERVER: 10.1.1.1#53(10.1.1.1)
;; WHEN: Tue May 31 09:29:06 2016
;; MSG SIZE  rcvd: 109

essa ci tornerà utile quando vedremo più nel dettaglio la logica su cui si basa il DNS cache poisoning.

dnsmasq ed Ubuntu: configurare un server DNS/DHCP per ambienti SOHO

Premesso che per mettere in piedi un nameserver locale si possono utilizzare diverse soluzioni open source, anche di tipo enterprise (una su tutte è rappresentata da bind/named), ho deciso di installare dnsmasq su un server Ubuntu per 2 motivi:

1) la rete aveva dimensioni estremamente ridotte (un server, qualche workstation e 3 stampanti), quindi rientrava nell’ambito delle infrastrutture SOHO (Small Office Home Office);

2) vi era la necessità di tirar su anche un servizio di DHCP, configurabile direttamente sull’applicativo in questione (che quindi può svolgere, contemporaneamente, sia il ruolo di nameserver che quello di DHCP server).

dnsmasq

Configurazione del DHCP server

Fare in modo che dnsmasq svolga le funzioni tipiche di un server DHCP è un’operazione abbastanza banale. Infatti, è sufficiente editare la configurazione del demone in questione (operando sul file /etc/dnsmasq.conf), aggiungendo le seguenti direttive:

no-dhcp-interface=eth1

dhcp-range=eth1,192.168.0.100,192.168.0.199,8h

In particolare, ho messo in ascolto il server DHCP sulla sola interfaccia eth0 (dato che si tratta di una macchina dual homed, in cui la scheda eth1 è collegata ad Internet mediante uno screened router). Inoltre, ho definito il pool di indirizzi che possono assere assegnati ai client che ne fanno richiesta, con relativo lease time (8h).

Configurazione del nameserver

Tale configurazione è un po’ più complessa rispetto alla precedente ma risulta comunque abbordabile.

Diciamo che dnsmasq è un nameserver “giocattolo”, in cui molti record DNS devono essere definiti all’interno di un file “piatto”, quale, ad esempio, /etc/hosts (anche se è possibile definire un file ad hoc per tale scopo), senza che vi sia quindi la necessità di creare una specifica zona DNS (cosa che invece risulta essere mandatoria con altri nameserver “un po’ più seri”).

I record di tipo A presenti nel file /etc/hosts avevano un formato simile al seguente:

192.168.0.2     proxy
192.168.0.4     server1
192.168.0.5     PC1
192.168.0.6     stampante1
192.168.0.7     stampante2
192.168.0.9     stampante3
192.168.0.10    PC2

Per quanto riguarda, invece, la configurazione del servizio DNS, ho abilitato le seguenti direttive (all’interno del file /etc/dnsmasq.conf):

interface=eth0
except-interface=eth1
listen-address=192.168.0.2

expand-hosts

domain=soho.loc

Le prime 3 servono a mettere in ascolto il server solo ed esclusivamente sull’interfaccia rivolta verso la LAN. Con expand-hosts e domain=soho.loc, invece,  ho fatto in modo che le query DNS vadano a buon fine anche nel caso in cui venga fornito il solo hostname della macchina di cui si vuole conoscere l’indirizzo IP.

Poichè il suddetto nameserver deve risolvere solo ed esclusivamente gli indirizzi locali, ho dovuto definire i forwarder (o nameserver di upstream) a cui inviare le query per tutte le zone DNS pubbliche. La direttive che ho utilizzato sono le seguenti:

resolv-file=/etc/resolv.dnsmasq
strict-order

dove il contenuto del file /etc/resolv.dnsmasq era il seguente:

nameserver 8.8.8.8
nameserver 208.67.222.222
nameserver 8.8.4.4
nameserver 208.67.220.220

La direttiva strict-order faceva in modo che i forwarder venissero contattati seguendo  l’ordine con cui sono stati definiti all’interno del suddetto file (il secondo nameserver viene contattato solo nel caso in cui il primo non sia raggiungibile, ergo, per ottenere una maggiore ridondanza, ho deciso di alternare ai nameserver di Google quelli di OpenDNS).

Per avere un maggiore controllo sulle query inoltrate al nameserver locale, ho deciso di loggarle su un apposito file di testo grazie ai seguenti parametri di configurazione:

log-queries
log-facility=/var/log/dnsmasq/query.log

Ho anche configurato la rotazione dei log mediante il file dnsmasq posto all’interno della directory /etc/logrotate.d:

/var/log/dnsmasq/query.log {
        rotate 7
        weekly
        compress
        missingok
        notifempty
}

Infine, affinchè i client della LAN riuscissero a “riconoscere” i record DNSSEC (garantendo loro una maggiore sicurezza durante la navigazione su Internet), ho fatto in modo che dnsmasq girasse le query DNSSEC ai forwarder (demandando loro il ruolo di validator).

La direttiva che mi ha consentito di fare ciò è la seguente:

proxy-dnssec

Il fatto che il nameserver primario di Google (8.8.8.8) sia il primo della lista dei forwarder non è certamente un caso. Infatti, esso garantisce dei tempi di risposta più brevi rispetto a quelli di OpenDNS, oltre ad essere anche DNSSEC compliant (cosa che OpenDNS non è).

In definitiva, la configurazione di dnsmasq (in base alle mie esigenze) si è rivelata essere la seguente:

no-dhcp-interface=eth1

dhcp-range=eth1,192.168.0.100,192.168.0.199,8h

interface=eth0
except-interface=eth1
listen-address=192.168.0.2

expand-hosts

domain=soho.loc

resolv-file=/etc/resolv.dnsmasq
strict-order

log-queries
log-facility=/var/log/dnsmasq/query.log

proxy-dnssec

Dopo aver effettuato un controllo sintattico della suddetta configurazione mediante il comando:

root@ubuntubox:~# dnsmasq --test

ed aver riavviato il demone:

root@ubuntubox:~# service dnsmasq restart

sono passato ai test funzionali mediante dig. Per prima cosa ho effettuato una query di tipo A per il record proxy, utilizzando dapprima il solo hostname:

root@fw-scar:~# dig @localhost proxy

; <<>> DiG 9.8.1-P1 <<>> @localhost proxy
; (2 servers found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 3216
;; flags: qr aa rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 0

;; QUESTION SECTION:
;proxy.                         IN      A

;; ANSWER SECTION:
proxy.                  0       IN      A       192.168.0.2

;; Query time: 1 msec
;; SERVER: 127.0.0.1#53(127.0.0.1)
;; WHEN: Fri May 20 15:50:11 2016
;; MSG SIZE  rcvd: 39

e successivamente l’intero FQDN:

 root@fw-scar:~# dig @localhost proxy.soho.loc

; <<>> DiG 9.8.1-P1 <<>> @localhost proxy.soho.loc
; (2 servers found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 30251
;; flags: qr aa rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 0

;; QUESTION SECTION:
;proxy.soho.loc.                        IN      A

;; ANSWER SECTION:
proxy.soho.loc.         0       IN      A       192.168.0.2

;; Query time: 1 msec
;; SERVER: 127.0.0.1#53(127.0.0.1)
;; WHEN: Fri May 20 15:52:15 2016
;; MSG SIZE  rcvd: 48

Successivamente mi sono concentrato sui tempi di risposta per i domini pubblici (da parte dei forwarder), ottenendo i seguenti tempi pre-cashing:

root@fw-scar:~# dig @localhost repubblica.it | grep "Query time"
;; Query time: 50 msec

e post caching:

root@fw-scar:~# dig @localhost repubblica.it | grep "Query time"
;; Query time: 0 msec

Infine, ho testato la risoluzione dei record DNSSEC, utilizzando il comando:

root@fw-scar:~# dig @localhost pir.org +dnssec +multi

; <<>> DiG 9.8.1-P1 <<>> @localhost pir.org +dnssec +multi
; (2 servers found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 35285
;; flags: qr rd ra ad; QUERY: 1, ANSWER: 2, AUTHORITY: 0, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags: do; udp: 512
;; QUESTION SECTION:
;pir.org.               IN A

;; ANSWER SECTION:
pir.org.                299 IN A 97.107.141.235
pir.org.                299 IN RRSIG A 5 2 300 20160602204000 (
                                20160519204000 58424 pir.org.
                                cJwr7HlIMA+DyQ8vqqmkNtHRAqsGVdKWTQkJeP/a5698
                                UTyK/cF08uYhH8xMk9I0RMWqtkJDM8od8hWmYUZgidzi
                                7Fh26m1FQYGAcN/PMw2/6wEnNh4ErWZtXe2fXRAS8btx
                                I+nyRPOCoAHR3CjC0cjKqtniUoWHt5x/51iEBw4= )

;; Query time: 86 msec
;; SERVER: 127.0.0.1#53(127.0.0.1)
;; WHEN: Fri May 20 15:57:36 2016
;; MSG SIZE  rcvd: 219

ricevendo come risposta sia il record A che il relativo RRSIG.

Alla fine della fiera ho messo in piedi un server DNS/DHCP funzionante e funzionale.

Alla prossima.

CentOS 6 e Postfix: tenere a bada il fenomeno denominato backscatter

In questo e questo post ho mostrato come configurare Postfix in modo da farlo funzionare come antispam. In quest’altro post, invece, ho illustrato la configurazione di postgrey e qui ho parlato di opendkim e di come integrarlo a Postfix.

Adesso vedremo come mitigare un fenomeno tipico dello spam e sempre più in aumento, ovvero il backscatter.

postfixUn po’ di teoria

Supponiamo che uno spammer voglia utilizzare il vostro dominio come mittente di una mail fraudolenta appositamente forgiata, da inoltrare ad un server SMTP autoritativo per un dominio X, che chiameremo dominiotarget.com.

La sequenza dei comandi che lo spammer utilizzerà sarà simile alla seguente:

ehlo mail.dominiotarget.com
mail from:<pluto@vostrodominio.com>
rcpt to:<pippo@dominiotarget.com>
data
some data
.
quit

Come potete notare, lo spammer ha utilizzato il vostro dominio (mail from:) come mittente della mail di spam che intende inviare ad utente@dominiotarget.com.

Supponiamo adesso che, per qualche ragione, il server SMTP di dominiotarget.com respinga la suddetta email fraudolenta (poichè, ad esempio, non esiste la mailbox pippo@dominiotarget.com), generando, successivamente, un messaggio apposito per indicare che tale email è stata respinta (mail bounced). Tale messaggio di “errore” verrà successivamente inoltrato al server SMTP autoritativo (ovvero quello specificato nei record MX della zona DNS) per vostrodominio.com.

A questo punto, se non opportunamente configurato, il vostro server SMTP riceverà il suddetto messaggio e lo inoltrerà alla casella di posta dell’utente spoofato dallo spammer, ovvero pluto@vostrodominio.com (se esiste), oppure verrà semplicemente scartata. Nel primo caso si rischia di saturare abbastanza velocemente la casella email del malcapitato utente (soprattutto se dotata di DISK QUOTA); nel secondo caso, invece, si rischia di creare eccessiva entropia, non consentendo all’amministratore della macchina di discernere (ad esempio attraverso l’analisi del file maillog) tra le email di backscatter e quelle che sono state respinte per un motivo lecito.

Come fare dunque per limitare tale fenomeno? Ecco alcune possibili soluzioni.

Utilizzare SPF

Se il server SMTP di dominiotarget.com è stato configurato in modo da utilizzare il framework SPF, e nella vostra zona DNS è presente un record di tipo TXT che specifica l’elenco dei server che possono inviare email utilizzando vostrodominio.com, esso sarà in grado di bloccare il tentativo di inoltro senza inviare alcun messaggio di errore al vostro server SMTP. Purtroppo però l’SPF non è configurato su tutti i server SMTP sparsi per la Rete, ergo bisogna correre ai ripari configurando opportunamente Postfix sul server antispam che intendiamo utilizzare.

Configurazione di Postfix

Per prima cosa occorre fare in modo che le email dirette a caselle di posta non esistenti vengano automaticamente respinte. Per fare ciò è possibile configurare la seguente direttiva all’interno del file /etc/postfix/main.cf:

unknown_local_recipient_reject_code = 550

Tale settaggio rappresenta comunque un’ottima prima difesa contro il backscatter, poichè, nella stragrande maggioranza dei casi, lo spammer forgerà delle email pseudorandomiche da utilizzare come mittente, del tipo AjsheUbjdX@vostrodominio.com. Esistono, però, dei casi particolari in cui lo spammer è a conoscenza di alcuni indirizzi leciti (ed attivi) su vostrodominio.com, ragion per cui occorre affinare ulteriormente la nostra opera di filtraggio. In particolare, è possibile impostare delle regole opportune basate su espressioni regolari in grado di “capire” quando un messaggio di mail bounced è stato causato dal backscatter e quando no. Tali regole potranno essere applicate durante l’analisi dell’header e del corpo del messaggio.

Ad esempio, possiamo popolare il file /etc/postfix/header_checks con le seguenti direttive:

if /^Received:/
/^Received: +from +(vostrodominio\.com) +/
        reject forged client name in Received: header: $1
/^Received: +from +[^ ]+ +\(([^ ]+ +[he]+lo=|[he]+lo +)(vostrodominio\.com)\)/
        reject forged client name in Received: header: $2
/^Received:.* +by +(vostrodominio\.com)\b/
        reject forged mail server name in Received: header: $1
endif
/^Message-ID:.* <!&!/ DUNNO
/^Message-ID:.*@(vostrodominio\.com)/
        reject forged domain name in Message-ID: header: $1

Inoltre, le suddette entry dovranno essere collocate anche all’interno del file /etc/postfix/body_checks.

Infine, è necessario editare il file /etc/postfix/master.cf come segue:

body_checks = pcre:/etc/postfix/body_checks

header_checks = pcre:/etc/postfix/header_checks

Da notare che non occorre postmappare i suddetti file ed è sufficiente un semplice reload di Postfix per rendere effettive le modifiche apportate:

[root@antispam ~]# service postfix reload

Adesso il nostro server antispam sarà sicuramente in grado di filtrare un gran numero di messaggi di backscatter ma non sarà comunque a prova di bomba (ecco perchè ho parlato di “mitigare” e non di “bloccare” tale fenomeno). Ciò è dovuto al fatto i messaggi di mail bounced possono variare sia nella sostanza che nella forma in base all’applicativo che funge da SMTP, rendendo comunque possibile l’eventualità che esso non venga matchato dai filtri appena configurati.

A presto.

Cisco 2811: utilizzare le route-map per creare delle regole di destination NAT basate su IP sorgente

Scenario

Supponiamo che si abbia a che fare con un ufficio centrale (main office) a cui sono collegati N uffici periferici (branch office) tramite dei tunnel VPN IPsec Site-to-Site dedicati (che concorrono a formare la classica topologia a stella). Supponiamo, inoltre, che i suddetti uffici periferici, per questioni di failover, debbano essere in grado di raggiungere i servizi presenti nell’ufficio centrale anche nel caso in cui i tunnel VPN non siano disponibili (passando quindi  direttamente per Internet).

vpn-ipsec1Utilizzando delle regole di destination NAT classiche, del tipo:

ip nat inside source static tcp 192.168.2.4 80 interface fastethernet0/0 80

(dove 192.168.4.2 è l’IP locale del server Web esposto su Internet), i branch office non saranno in grado di raggiungere il server in questione tramite il tunnel VPN (utilizzando il protocollo HTTP).

Ergo, il fatto che un determinato servizio sia pubblicato su Internet, implica automaticamente l’impossibilità di raggiungerlo anche tramite il tunnel VPN.

Per ovviare a tale problematica esistono 2 soluzioni: la prima, meno impegnativa (ma che richiede la modifica della URL lato client in caso di failover), consiste nel modificare la configurazione del server in modo tale che rimanga in ascolto su 2 porte distinte, ad esempio la TCP 80 per Internet e la TCP 81 per la VPN;  la seconda, più impegnativa (ma anche molto più scalabile), consiste nel creare sul nostro router Cisco 2811 (main office) delle route-map (che si avvalgono di opportune ACL) in grado di filtrare gli indirizzi IP sorgenti dei client che vogliono collegarsi al server Web. In questo modo, se la richiesta di connessione proviene da un determinato IP privato tipico di una VPN Site-to-Site (ad esempio 192.168.3.1), per essa non viene applicato il destination NAT; viceversa, nel caso in cui la richiesta di connessione provenga da Internet, verrà applicato il destination NAT come di consueto.

Ho definito la seconda soluzione come la più scalabile delle 2 per un semplice motivo: impostando la route-map sul router del main office e modificando sul nameserver locale il record di tipo A che punta all’IP del server Web, si può fare in modo che quest’ultimo possa essere contattato tramite tunnel VPN o tramite Internet a seconda dei casi senza dover modificare la URL lato browser (passando, ad esempio, da http://www.vostrodominio.com a http://www.vostrodominio.com:81).

Vediamo adesso come mettere in pratica la soluzione #2.

Configurazione del router Cisco 2811 (main office)

Per prima cosa occorre creare l’ACL in grado di “riconoscere” gli IP locali e di negare il destination NAT:

Router(config)# access-list 150 deny ip host 192.168.2.4 192.168.3.0 0.0.0.255
Router(config)# access-list 150 deny ip host 192.168.2.4 192.168.4.0 0.0.0.255
Router(config)# access-list 150 deny ip host 192.168.2.4 192.168.5.0 0.0.0.255
Router(config)# access-list 150 deny ip host 192.168.2.4 192.168.6.0 0.0.0.255
Router(config)# access-list 150 permit ip host 192.168.2.4 any

Successivamente creiamo la route-map vera e propria:

Router(config)# route-map nonat
Router(config-route-map)# match ip address 150

dove 150 è il numero dell’ACL estesa precedentemente definita.

Infine, associamo la route-map appena creata alla regola di destination NAT:

Router(config)# ip nat inside source static tcp 192.168.2.4 <IP Pubblico> 80 route-map nonat extendable

Ovviamente, affinchè la suddetta soluzione sia realmente scalabile, è necessario che il vostro collegamento ad Internet sia dotato di indirizzo IP pubblico statico.

Salviamo adesso la configurazione del nostro router:

Router# copy run start

e passiamo al vaglio alcune soluzioni alternative alle route-map.

1) Utilizzo dei record DNS di tipo SRV (vedi qui per ulteriori dettagli). Essi ci consentono non solo di specificare il protocollo di comunicazione ma anche la porta su cui è in ascolto il server, definendo una priorità per ciascuna entry che li compone:

_http._tcp.vostrodominio.com. 86400 IN SRV 0 5 81 www.vostrodominio.com.
_http._tcp.vostrodominio.com. 86400 IN SRV 1 5 80 www1.vostrodominio.com.

dove 0 e 1 sono le priorità, 81 e 80 le porte su cui è in ascolto il server. In caso di timeout sulla porta 81 e l’IP di www (raggiungibile via VPN) il browser “dovrebbe” switchtare automaticamente sulla 80 e l’IP di www1. Ho utilizzato il condizionale poichè non tutti i broswer supportano tale meccanismo ed un workaround (applicato però solo da alcuni di essi), consiste nel definire record A con il medesimo hostname ma indirizzi IP differenti: nel caso in cui la connessione al primo IP della lista vada in timeout, il broswer tenterà automaticamente di connettersi al secondo IP (e così via).

2) Utilizzo di un firewall interno per filtrare le connessioni in uscita (outbound). ln questo caso, grazie ad esso, potremmo creare delle regole ad hoc (source NAT) per il mapping delle porte di destinazione, ad esempio (utilizzando iptables):

[root@firewall ~]# iptables -t nat -A OUTPUT -p tcp -d www.vostrodominio.com --dport 80 -j DNAT --to-destination www.vostrodominio.com:81

Anche in questo caso, prima di applicare la suddetta regola di firewalling, sarà necessario modificare sul nameserver il record A per l’hostname www.

E’ tutto. Alla prossima.

WI-FI IP camera made in China: ennesima stranezza

Ok, avete ragione, sono un maledettissimo freak control. Però non è colpa mia se questo aggeggio continua a comportarsi in modo strano. Infatti, oltre a questa anomalia, ho notato che ogni tanto prova a contattare l’ennesimo server cinese, questa volta un nameserver (almeno sulla carta).

Inoltre, molto probabilmente quel nameserver (sempre se di nameserver si tratta) è di proprietà del costruttore di questi aggeggi, tant’è che un semplice whois mi ha rivelato le seguenti informazioni:

nightfly@nightbox:~$ whois 211.154.141.240
% [whois.apnic.net node-1]
% Whois data copyright terms    http://www.apnic.net/db/dbcopyright.html

inetnum:        211.154.128.0 - 211.154.159.255
netname:        ChinaMotion
country:        CN
descr:          China Motion Network Communication
descr:          9F,Yu Hua Industrial & Trading Building,Bao Gang Rd.
descr:          Luo Hu District,Shenzhen, Guangdong Province
admin-c:        BY158-AP
tech-c:         BY158-AP
status:         ALLOCATED PORTABLE
mnt-by:         MAINT-CNNIC-AP
mnt-lower:      MAINT-CNNIC-AP
mnt-irt:        IRT-CNNIC-CN
mnt-routes:     MAINT-CNCGROUP-RR
changed:        hm-changed@apnic.net 20060523
source:         APNIC

person:         Binghua Yang
nic-hdl:        BY158-AP
e-mail:         idc-service@hotmail.com
address:        9F,Yu Hua Industrial & Trading Building,Bao Gang Rd.Luo
address:        Hu District,Shenzhen
phone:          +86-0755-82189782
fax-no:         +86-755-82189789
country:        CN
changed:        shenzhi@cnnic.cn 20041126
changed:        ipas@cnnic.net.cn 20070514
mnt-by:         MAINT-CN-CMNET
source:         APNIC

Ma bando alle ciance, ecco cosa succede sniffando un pò di pacchetti con tcpdump:

18:13:28.222925 IP 10.1.x.x.3072 > 8.8.8.8.53: 125+ A? dns.camcctv.com. (33)
        0x0000:  4500 003d 62c7 4000 4011 bcd3 0a01 0105  E..=b.@.@.......
        0x0010:  0808 0808 0c00 0035 0029 af81 007d 0100  .......5.)...}..
        0x0020:  0001 0000 0000 0000 0364 6e73 0763 616d  .........dns.cam
        0x0030:  6363 7476 0363 6f6d 0000 0100 01         cctv.com.....
18:13:28.288413 IP 8.8.8.8.53 > 10.1.x.x.3072: 125 1/0/0 A[|domain]
        0x0000:  4500 004d a392 0000 2f11 ccf8 0808 0808  E..M..../.......
        0x0010:  0a01 0105 0035 0c00 0039 28b5 007d 8180  .....5...9(..}..
        0x0020:  0001 0001 0000 0000 0364 6e73 0763 616d  .........dns.cam
        0x0030:  6363 7476 0363 6f6d 0000 0100 01c0 0c00  cctv.com........
        0x0040:  0100 0100 0009 6800 04d3 9a8d            ......h.....
18:13:28.325038 IP 10.1.x.x.3072 > 211.154.141.240.2011: UDP, length 84
        0x0000:  4500 0070 0000 4000 4011 cdec 0a01 0105  E..p..@.@.......
        0x0010:  d39a 8df0 0c00 07db 005c e3b5 4d4f 5f48  ...........MO_H
        0x0020:  0000 0000 3738 2d41 352d 4444 2d30 342d  ....78-A5-DD-04-
        0x0030:  4138 2d33 4500 0000 3130 2e31 2e31 2e35  A8-3E...10.1.x.x
        0x0040:  0000 0000 0000 0000 0000 0000            ............

Che significa tutto ciò? Brevemente: dapprima manda una query DNS di tipo A al suo nameserver primario (8.8.8.8), richiedendo l’IP associato all’hostname dns.camcctv.com:

18:13:28.222925 IP 10.1.x.x.3072 > 8.8.8.8.53: 125+ A? dns.camcctv.com

La risposta alla suddetta query è la seguente:

18:13:28.288413 IP 8.8.8.8.53 > 10.1.x.x.3072: 125 1/0/0 A[|domain]

Una volta individuato l’indirizzo IP di dns.camcctv.com (ovvero 211.154.141.240) procede con l’invio, verso la porta UDP 2011, del proprio MAC address e del proprio indirizzo IP locale.

Facendo due più due il conto è presto fatto: con il dyndns abilitato di default, l’IP pubblico del network a cui la telecamera appartiene diventa di dominio pubblico (e soprattutto di dominio del costruttore). A questo aggiungeteci le info che manda a quel nameserver e praticamente, nel caso in cui ci fosse una qualche backdoor all’interno del codice dell’interfaccia Web di cui è dotata, il costruttore (o chi per lui) avrebbe la possibilità di accedere liberamente alla nostra IP camera. A questo aggiungeteci l’eventualità che tutto il traffico in ingresso su quella porta del nameserver potrebbe essere loggato, rilevando quindi l’indirizzo IP pubblico della rete a cui appartiene la telecamera.

Ora, poichè tale device ha un server FTP integrato, mi sono preso la briga di accedervi e di scaricare in locale tutte le pagine Web (.htm) che concorrono al funzionamento dell’interfaccia di gestione. Inutile dire che non ci ho trovato granchè, anche perchè tutte le modifiche alla configurazione vengono effettuate mediante delle chiamate AJAX a determinate pagine *.xml (che, naturalmente, non sono scaricabili).

Infatti, per capire cosa sia possibile fare tramite delle semplici chiamate alle suddette pagine, è sufficiente consultare questo documento:

IPCamera_AJAX (English Translation) – GadgetVictimsCom.pdf

Per completezza, se volete provare ad accedere al suddetto server FTP (della vostra telecamera, non di certo della mia) è necessario:

1) utilizzare un client ben preciso, ovvero CuteFTP (con tutti gli altri, client FTP Linux da CLI, client FTP Windows da CLI, FireFTP, eccetera, il demone della telecamera crasha miseramente);

2) loggarsi con username MayGion e con password maygion.com (credenziali case sensitive e non modificabili – dove maygion è il produttore del firmware).

Come ho risolto? Di nuovo, regola Iptables del tipo:

iptables -A FORWARD -i eth1 -o eth0 -p udp -d 211.154.141.240 –dport 2011 -j DROP

Sto anche monitorando tutto il traffico diretto alla porta HTTP della telecamera, vediamo cosa ne verrà fuori.

Alla prossima.

Aggiornamento del 16/12/2012

A quanto pare l’hostname dns.camcctv.com è qualcosa di hard coded all’inteno dei sorgenti del firmware (a giudicare dal questo 3D). Inoltre, sembra che si tratti dell’ennesimo servizio di DDNS ma, non essendoci alcuna opzione che mi consenta di disabilitarlo via interfaccia Web, lo terrò comunque in DROP.

Attacco a GoDaddy.com: alcune precisazioni

Ok, in questo post vi avevo parlato di un attacco che molto probabilmente coinvolgeva i siti hostati su GoDaddy. In realtà, però, ultimanente è cresciuto a dismisura il numero di Web Hosting violati, ergo parlare solo di GoDaddy sarebbe estremamente riduttivo.

 

cracker2.jpg

Mi spiego meglio: sia sul mio server FTP (casalingo) che su 2 server hostati su 2 differenti farm si sono verificati tentativi di accesso usando credenziali FTP lecite. Ciò significa che in circolazione è presente un malware che riesce ad intercettare il contenuto delle email ed a ricavare le credenziali dei server FTP scambiate attraverso il suddetto canale di comunicazione (che di per sè è poco sicuro).

Per quanto mi riguarda, sul mio server ho provveduto a rimuovere completamente gli account relativi agli utenti le cui credenziali sono state violate, in un altro caso ho provveduto a monitorare gli accessi FTP mediante i file di log, arrivando sempre e comunque alla stessa conclusione, ovvero che alcuni cracker sono riusciti ad individuare le giuste credenziali per eccedere ai server.

Inoltre, entrambe le pagine dei server Web su hosting provider presentavano del codice javascrip creato ad-hoc, ovvero:

http://fossfotography.com/wp-content/uploads/process.js

In realtà, però, se puntiamo alla directory uploads, il risultato è il seguente:

nightfly@nightbox:~$ wget http://fossfotography.com/wp-content/uploads/
--2012-07-25 11:10:24--  http://fossfotography.com/wp-content/uploads/
Resolving fossfotography.com... 173.201.146.128

Connecting to fossfotography.com|173.201.146.128|:80... connected.
HTTP request sent, awaiting response... 301 Moved Permanently
Location: http://fossfotography.com/var/chroot/home/content/90/5954490/html/wp-content/htttp://reltime2012.ru/frunleh?9 [following]
--2012-07-25 11:10:25--  http://fossfotography.com/var/chroot/home/content/90/5954490/html/wp-content/htttp://reltime2012.ru/frunleh?9
Reusing existing connection to fossfotography.com:80.
HTTP request sent, awaiting response... 301 Moved Permanently
Location: http://fossfotography.com/htttp://reltime2012.ru/frunleh?9 [following]
--2012-07-25 11:10:25--  http://fossfotography.com/htttp://reltime2012.ru/frunleh?9
Reusing existing connection to fossfotography.com:80.

ovvero avviene un redirect sulla URL htttp://reltime2012.ru/frunleh?9

No, non è un errore di battitura, è proprio htttp e non http.

A questo punto ho deciso di lanciare un wget su http://reltime2012.ru/frunleh?9

ed il risultato è stato questo:

nightfly@nightbox:~$ wget http://reltime2012.ru/frunleh?9
--2012-07-25 11:11:28--  http://reltime2012.ru/frunleh?9
Resolving reltime2012.ru... 67.215.65.132
Connecting to reltime2012.ru|67.215.65.132|:80... connected.
HTTP request sent, awaiting response... 303 See Other
Location: http://guidetest.a.id.opendns.com/?url=reltime2012%2Eru%2Ffrunleh%3F9 [following]
--2012-07-25 11:11:28--  http://guidetest.a.id.opendns.com/?url=reltime2012%2Eru%2Ffrunleh%3F9
Resolving guidetest.a.id.opendns.com... 67.215.67.10
Connecting to guidetest.a.id.opendns.com|67.215.67.10|:80... connected.
HTTP request sent, awaiting response... 302 Found
Location: http://w10.guidetest.b.id.opendns.com/?url=reltime2012%2Eru%2Ffrunleh%3F9 [following]
--2012-07-25 11:11:29--  http://w10.guidetest.b.id.opendns.com/?url=reltime2012%2Eru%2Ffrunleh%3F9
Resolving w10.guidetest.b.id.opendns.com... 67.215.67.10
Connecting to w10.guidetest.b.id.opendns.com|67.215.67.10|:80... connected.
HTTP request sent, awaiting response... 302 Found
Location: http://w10.w10.guidetest.c.id.opendns.com/?url=reltime2012%2Eru%2Ffrunleh%3F9 [following]
--2012-07-25 11:11:29--  http://w10.w10.guidetest.c.id.opendns.com/?url=reltime2012%2Eru%2Ffrunleh%3F9
Resolving w10.w10.guidetest.c.id.opendns.com... 67.215.67.10
Connecting to w10.w10.guidetest.c.id.opendns.com|67.215.67.10|:80... connected.
HTTP request sent, awaiting response... 302 Found
Location: http://w10.w10.w10.guidetest.d.id.opendns.com/?url=reltime2012%2Eru%2Ffrunleh%3F9 [following]
--2012-07-25 11:11:30--  http://w10.w10.w10.guidetest.d.id.opendns.com/?url=reltime2012%2Eru%2Ffrunleh%3F9
Resolving w10.w10.w10.guidetest.d.id.opendns.com... 67.215.67.10
Connecting to w10.w10.w10.guidetest.d.id.opendns.com|67.215.67.10|:80... connected.
HTTP request sent, awaiting response... 302 Found
Location: http://w10.w10.w10.w10.guidetest.e.id.opendns.com/?url=reltime2012%2Eru%2Ffrunleh%3F9 [following]
--2012-07-25 11:11:30--  http://w10.w10.w10.w10.guidetest.e.id.opendns.com/?url=reltime2012%2Eru%2Ffrunleh%3F9
Resolving w10.w10.w10.w10.guidetest.e.id.opendns.com... 67.215.67.10
Connecting to w10.w10.w10.w10.guidetest.e.id.opendns.com|67.215.67.10|:80... connected.
HTTP request sent, awaiting response... 302 Found
Location: http://www.website-unavailable.com/?wc=EWJpExd9AQVABBJuAQ8=&url=reltime2012%2Eru%2Ffrunleh%3F9 [following]
--2012-07-25 11:11:31--  http://www.website-unavailable.com/?wc=EWJpExd9AQVABBJuAQ8=&url=reltime2012%2Eru%2Ffrunleh%3F9
Resolving www.website-unavailable.com... 208.69.33.136
Connecting to www.website-unavailable.com|208.69.33.136|:80... connected.
HTTP request sent, awaiting response... 200 OK
Cookie coming from www.website-unavailable.com attempted to set domain to www.website-unavailable.com
Length: 3877 (3.8K) [text/html]
Saving to: `frunleh?9'

Dall’output si evince che la URL non è più raggiungibile (non esiste alcuna entry DNS).

Successivamente un whois riportava le seguenti info:

nightfly@nightbox:~$ whois  reltime2012.ru
% By submitting a query to RIPN's Whois Service
% you agree to abide by the following terms of use:
% http://www.ripn.net/about/servpol.html#3.2 (in Russian)
% http://www.ripn.net/about/en/servpol.html#3.2 (in English).

domain:        RELTIME2012.RU
nserver:       ns1.reg.ru.
nserver:       ns2.reg.ru.
state:         REGISTERED, NOT DELEGATED, VERIFIED
person:        Private Person
registrar:     REGRU-REG-RIPN
admin-contact: http://www.reg.ru/whois/admin_contact
created:       2012.07.03
paid-till:     2013.07.03
free-date:     2013.08.03
source:        TCI

Last updated on 2012.07.25 14:00:46 MSK

Gli NS del registrar sono ns1.reg.ru ed ns2.reg.ru. Vediamo se una query con dig riesce a darmi qualche indirizzo IP utile associato a quell’FQDN (alias record A):

nightfly@nightbox:~$ dig @ns1.reg.ru  reltime2012.ru

; <<>> DiG 9.7.0-P1 <<>> @ns1.reg.ru reltime2012.ru
; (2 servers found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 37008
;; flags: qr aa rd; QUERY: 1, ANSWER: 0, AUTHORITY: 1, ADDITIONAL: 0
;; WARNING: recursion requested but not available

;; QUESTION SECTION:
;reltime2012.ru.                        IN      A

;; AUTHORITY SECTION:
reltime2012.ru.         43200   IN      SOA     ns1.reg.ru. hostmaster.ns1.reg.ru. 1341617290 14400 3600 604800 21600

;; Query time: 161 msec
;; SERVER: 31.31.204.37#53(31.31.204.37)
;; WHEN: Wed Jul 25 12:13:24 2012
;; MSG SIZE  rcvd: 87

nightfly@nightbox:~$ dig @ns2.reg.ru  reltime2012.ru

; <<>> DiG 9.7.0-P1 <<>> @ns2.reg.ru reltime2012.ru
; (2 servers found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 36077
;; flags: qr aa rd; QUERY: 1, ANSWER: 0, AUTHORITY: 1, ADDITIONAL: 0
;; WARNING: recursion requested but not available

;; QUESTION SECTION:
;reltime2012.ru.                        IN      A

;; AUTHORITY SECTION:
reltime2012.ru.         43200   IN      SOA     ns1.reg.ru. hostmaster.ns1.reg.ru. 1341617290 14400 3600 604800 21600

;; Query time: 122 msec
;; SERVER: 31.31.204.25#53(31.31.204.25)
;; WHEN: Wed Jul 25 12:15:11 2012
;; MSG SIZE  rcvd: 87

Niente da fare, non riesco ad ottenere alcun indirizzo IP associato al suddetto FQDN.

Però, mi lascia riflettere la seguente stringa:

;; WARNING: recursion requested but not available

Ciò significa che i suddetti NS funzionano in modalità ricorsiva, ovvero sono a conoscenza degli NS autoritativi per quel particolare dominio, ma non sono autorizzati ad effettuare la suddetta richiesta.

Infine, mi son giocato la carta dei trasferimenti di zona forzosi, ma anche questo tentativo non è andato a buon fine:

nightfly@nightbox:~$ dig @ns2.reg.ru reg.ru axfr

; <<>> DiG 9.7.0-P1 <<>> @ns2.reg.ru reg.ru axfr
; (2 servers found)
;; global options: +cmd
; Transfer failed.
nightfly@nightbox:~$ dig @ns1.reg.ru reg.ru axfr

; <<>> DiG 9.7.0-P1 <<>> @ns1.reg.ru reg.ru axfr
; (2 servers found)
;; global options: +cmd
; Transfer failed.

Per la serie “i russi non si smentiscono mai”…

Reply dei root nameserver: mistero svelato

In riferimento a questo post, il fatto che il mio PIX 501 inizi a strillare per la dimensione “eccessiva” dei pacchetti provenienti da alcuni root nameserver (nella fattispecie K e J), è dovuto principalmente ad una questione di standard. Infatti, lo standard originario del DNS (risalente ormai al lontano 1980) prevedeva una dimensione massima di 512 byte per i pacchetti instradati mendiante il protocollo UDP.

servers.png

Successivamente, l’introduzione dell’IPv6, l’uso opzionale del protocollo TCP per il trasporto e la presenza di alcune flag aggiuntive, specificate all’interno dello standard EDNS0 (acronimo che sta per Extension Mechanism for DNS), ha fatto si che le reply potessero raggiungere delle dimensioni superiori ai 512 byte.

C’è da dire però che proprio tale “aggiornamento” ha reso possibili alcuni tipi di attacco DDoS diretti ai nameserver, tra cui il DNS amplification.

Spero di essere stato esaustivo.

Bye.

Root nameserver e pacchetti dalle dimensioni eccessive

E’ lunedì mattina e come al solito do un’occhiata ai log collezionati dal mio server. Apro in lettura quelli del PIX e mi ritrovo queste entry:

Mar 14 06:56:44 ***%PIX-4-410001: Dropped UDP DNS reply from outside:192.58.128.30/53 to inside:*.*.*.*/23803; packet length 685 bytes exceeds configured limit of 680 bytes
 Mar 14 06:56:45 ***%PIX-4-410001: Dropped UDP DNS reply from outside:193.0.14.129/53 to inside:*.*.*.*/27872; packet length 703 bytes exceeds configured limit of 680 bytes
dns.jpg

Lancio un host sugli IP sorgenti, il cui risultato è il seguente:

 nightfly@nightbox:/var/log$ host 193.0.14.129
 129.14.0.193.in-addr.arpa domain name pointer k.root-servers.net.
 nightfly@nightbox:/var/log$ host 192.58.128.30
 30.128.58.192.in-addr.arpa domain name pointer j.root-servers.net.

Dunque mi chiedo: come mai i root nameserver mandano dei pacchetti dalle dimensioni così elevate?

Non mi rimane che modificare le impostazioni del PIX per evitare ulteriori notifiche di questo tipo.

A presto.

Creare un server DNS casalingo su piattaforma *buntu con Bind9

Che un server DNS casalingo non sia proprio una necessità è risaputo, soprattutto quando gli host della nostra LAN si contano sulle dita di una mano. Però, nonostante tutto, ci sono alcuni vantaggi che mi hanno spinto a realizzare un nameserver sulla mia linux box, ovvero:

1) il caching, per non interrogare continuamente i DNS del mio ISP ed avere risposte più rapide (si spera) alle query;

2) creare una configurazione ad hoc in modo da riprendere confidenza con bind.

Bene, per prima cosa installiamo bind9 sulla box, sfruttando il solito aptitude:

nightfly@nightbox:~$ sudo apt-get install bind9

Una volta completata l’installazione posizioniamoci nella directory /etc/bind

nightfly@nightbox:~$ cd /etc/bind

Passiamo subito alla configurazione di bind, editando il file named.conf.options

nightfly@nightbox:~$ sudo nano named.conf.options

a questo punto sostituiamo

 // forwarders {
 // 0.0.0.0;
 // };

con

 forwarders {
 x.x.x.x;
 y.y.y.y;
 };

dove x.x.x.x ed y.y.y.y sono rispettivamente il DNS primario e secondario del nostro ISP.

Bene, ora passiamo alla configurazione del file named.conf.local, in cui specificare le zone per le quali il nostro nameserver risulta autoritativo:

nightfly@nightbox:~$ sudo nano named.conf.local

ed inseriamo la seguente configurazione:

 zone "mylittlelan.org" {
 type master;
 file "/etc/bind/db.mylittlelan";
 };

Abbiamo quasi finito. Non ci resta che creare il file db.mylittlelan all’interno della dir /etc/bind e metterci dentro i seguenti parametri:

 $TTL 10800
 @ IN SOA server.mylittlelan.org. root.mylittlelan.org. (
 2006050644 ; Serial
 10800 ; Refresh
 3600 ; Retry
 3600 ) ; Negative Cache TTL
 ;
 mylittlelan.org. NS server.mylittlelan.org.
 ;
 server IN A 192.168.1.1
 host1 IN A 192.168.1.4
 host2 IN A 192.168.1.2
 firewall IN A 192.168.1.7
 router IN A 192.168.1.8
 ;

Analizziamo tale configurazione passo passo:

la direttiva TTL (Time To Live) specifica la durata delle entry DNS (in secondi), ovvero per quanto tempo una data associazione IP – hostname deve rimanere memorizzata nel nostro nameserver.

Il record SOA fornisce informazioni fondamentali sulla zona, ovvero il nameserver autoritativo server.mylittlelan.org., l’indirizzo email dell’amministratore (ovvero root.mylittlelan.org., in cui la @, che in questo contesto ha ben altro significato, è stata sostituita con un . leggasi root@mylittlelan.org).

All’interno del record in questione notiamo inoltre la presenza di altre info, quali:

Serial, ovvero il nuero di serie (incrementale) associato ai record della zona, sfruttato per individuare le entry più aggiornate nel caso in cui vi siano più DNS autoritativi per la zona (master-slave);

Refresh, ovvero ogni quanto tempo un eventuale slave deve effettuare un refresh delle entry in suo possesso, contattando il master (le cui entry dovrebbero essere più recenti);

Retry, ovvero dopo quanto tempo un eventuale slave deve richiedere nuovamente un trasferimento di zona al master, poichè i tentativi precedenti non sono andati a buon fine.

Successivamente specifico il nameserver autoritativo per la mia zona (record NS):

mylittlelan.org. NS server.mylittlelan.org.

che è equivalente a scrivere:

@ IN NS server.mylittlelan.org.

e quindi l’associazione hostname – IP per la mia zona (record A):

 server IN A 192.168.1.1
 host1 IN A 192.168.1.4
 host2 IN A 192.168.1.2
 firewall IN A 192.168.1.7
 router IN A 192.168.1.8

che è equivalente a scrivere:

 server.mylittlelan.org. A 192.168.1.1
 host1.mylittlelan.org. A 192.168.1.4
 host2.mylittlelan.org. A 192.168.1.2
 firewall.mylittlelan.org. A 192.168.1.7
 router.mylittlelan.org. A 192.168.1.8

NB: il ; viene utilizzato per i commenti. Da notare, inoltre, il punto alla fine dell’hostname completo (ad esempio server.mylittlelan.org.). Questo dice a bind che l’hostname che gli è stato fornito è completo. Se infatti avessimo scritto server.mylittlelan.org senza punto finale, bind sarebbe andato alla ricerca di server.mylittlelan.org.mylittlelan.org.

Verifichiamo la configurazione di bind mediante il comando:

nightfly@nightbox:~$ named-checkconf

Se non viene visualizzato alcun messaggio vuol dire che la configurazione è corretta.

Successivamente saggiamo la validità del file che identifica la nostra zona, ovvero db.mylittlelan:

nightfly@nightbox:~$ named-checkzone mylittlelan.org db.mylittlelan

Se otteniamo un output simile al seguente:

zone mylittlelan.org/IN: loaded serial 2086050644
 OK

significa che anche il file di zona non presenta anomalie di sorta.

Per ragioni di sicurezza dobbiamo definire una specifica zona per gestire le query DNS inverse (che ci restituiscono l’hostname a partire da un dato indirizzo IP).

Poichè la nostra LAN sfrutta la tipica classe C privata (192.168.1.0) chiameremo la nostra zona 1.168.192.in-addr.arpa. A tal proposito creiamo il file db.192 ed inseriamo al suo interno la seguente configurazione:

$TTL 10800
 @               IN      SOA     server.mylittlelan.org. root.mylittlelan.org. (
 2086050644 ; Serial
 10800      ; Refresh
 3600       ; Retry
 604800     ; Expire
 86400)     ; Minimum TTL
 NS      server.mylittlelan.org.
 1          PTR     server.mylittlelan.org.
 2          PTR     host1.mylittlelan.org.
 4          PTR       host2.mylittlelan.org.
 7          PTR       firewall.mylittlelan.org.
 8          PTR       router.mylittlelan.org.

Verifichiamo che la zona sia configurata correttamente utilizzando ancora una volta il comando named-checkzone:

nightfly@nightbox:/etc/bind$ named-checkzone 1.168.192.in-addr.arpa db.192

se otteniamo il seguente output:

zone 1.168.192.in-addr.arpa/IN: loaded serial 2086050644
 OK

vuol dire che la zona è stata configurata correttamente.

Modifichiamo il file resolv.conf posizionato nella directory /etc:

nightfly@nightbox:~$ sudo nano /etc/resolv.conf

e nella prima riga inseriamo:

192.168.1.1

ovvero l’indirizzo IP del nostro DNS locale.

Riavviamo quindi bind digitando:

nightfly@nightbox:~$ sudo /etc/initd./bind9 restart

e finalmente il nostro nameserver è dovrebbe essere funzionante e pronto all’uso. Utilizziamo dig per esserne certi, provando dapprima una query diretta e successivamente una query inversa:

nightfly@nightbox:/etc/bind$ dig router.mylittlelan.org

e dovremmo ottenere un risultato simile al seguente:

; <<>> DiG * <<>> router.mylittlelan.org
;; global options:  printcmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 38471
;; flags: qr aa rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 1, ADDITIONAL: 1

;; QUESTION SECTION:
;router.mylittlelan.org.       IN      A

;; ANSWER SECTION:
router.mylittlelan.org. 10800  IN      A       192.168.1.8

;; AUTHORITY SECTION:
mylittlelan.org.             10800   IN      NS      server.mylittlelan.org.

;; ADDITIONAL SECTION:
server.mylittlelan.org.      10800   IN      A       192.168.1.1

;; Query time: 0 msec
;; SERVER: 192.168.1.1#53(192.168.1.1)
;; WHEN: Thu Aug 12 20:47:13 2010
;; MSG SIZE  rcvd: 94

Proviamo ora la query inversa, utilizzando l’opzione -x:

nightfly@nightbox:/etc/bind$ dig -x 192.168.1.8

Dovremmo ottenere:

; <<>> DiG * <<>> -x 192.168.1.8
;; global options:  printcmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 40059
;; flags: qr aa rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 1, ADDITIONAL: 1

;; QUESTION SECTION:
;8.1.168.192.in-addr.arpa.      IN      PTR

;; ANSWER SECTION:
8.1.168.192.in-addr.arpa. 10800 IN      PTR     router.mylittlelan.org.

;; AUTHORITY SECTION:
1.168.192.in-addr.arpa. 10800   IN      NS      server.mylittlelan.org.

;; ADDITIONAL SECTION:
server.mylittlelan.org.      10800   IN      A       192.168.1.1

;; Query time: 0 msec
;; SERVER: 192.168.1.1#53(192.168.1.1)
;; WHEN: Thu Aug 12 20:53:12 2010
;; MSG SIZE  rcvd: 115

Fine dei giochi 😀 See ya.

PS: per avviare bind basta digitare /etc/init.d/bind9 start, mentre per stopparlo occorre scrivere /etc/init.d/bind9 stop.

DNS zone transfer

In questo post abbiamo visto qual è la logica su cui si basa un attacco molto diffuso nell’ambito dell’hijacking (dirottamento), ovvero il DNS poisoning, conosciuto anche come pharming. Ora, invece, adremo a vedere come ottenere informazioni preziose durante la fase di footprinting (ovvero di preparazione di un attacco informatico) semplicemente forzando un trasferimento di zona su uno dei server DNS appartenenti al dominio di nostro interesse.

Sostanzialmente, una zona è costituita da un dominio e/o da uno o più sottodomini. Ad esempio, per il dominio .it ci sarà una zona dedicata a ciao.it e nell’ambito di ciao.it ci saranno altre zone dedicate a hello.ciao.it, hola.ciao.it e così via. Inoltre, i server DNS di livello top (nel nostro caso .it) delegheranno ai nameserver di zona (nella fattispecie di ciao.it) la gestione della risoluzione dei nomi, facendo in modo che i server DNS delegati divengano autoritativi per quella determinata zona. Allo stesso modo, i nameserver di ciao.it potranno delegare ai server DNS di hello.ciao.it e di hola.ciao.it la gestione delle accoppiate IP-dominio.

dns-1.png

 

E’ abbastanza diffusa, soprattutto per i domini di grande dimensioni, la pratica di utilizzare più server DNS contemporaneamente, in particolare un master (primario) ed uno o più slave (secondari), in modo tale da garantire la disponibilità del servizio anche nel caso in cui si verifichi un guasto ai nameserver. A tal proposito, appare abbastanza scontata la necessità di mantenere allineate le informazioni possedute da ciascun server DNS, per fare in modo che ognuno di essi possa svolgere correttamente la propria funzione.

Ma come avviene lo scambio dei record tra i server DNS appartenenti ad una determinata zona? La risposta è molto semplice. Partendo dal presupposto che il master viene utilizzato costantemente come punto di riferimento, ogni qual volta che si verifica un cambiamento relativo al database dei record in esso contenuto, il numero di serie associato alla zona di interesse subisce un incremento. Per evitare quindi che un server slave richieda uno zone transfer senza che ve ne sia la necessità, esso procederà dapprima con la richiesta del numero di serie associato dal server primario alla specifica zona (mediante un’interrogazione di tipo SOA) e successivamente lo confronterà con il numero di serie di cui è a conoscenza. Se quest’ultimo è inferiore allorà si procederà con lo zone transfer.

Occorre notare, inoltre, che i trasferimenti di zona possono essere totali (ovvero vengono copiati tutti i record DNS dal master allo slave – AXFR) oppure incrementali (vengono copiati solo i record di cui lo slave non è ancora a conoscenza – IXFR).

Ogni trasferimento di zona crea una sorta di collegamento client-server tra la macchina che effettua l’interrogazione *XFR e la macchina che dovrà rispondere a tale query. In realtà, però, le cose non stanno propriamente così, infatti le interrogazioni *XFR sono sempre precedute dalle interragazioni di tipo SOA. E’ bene notare, inoltre, che le richieste *XFR possono essere effettuate, in base alle necessità ed alla disponibilità del server, mediante protocollo TCP oppure mediante protocollo UDP.

Quindi il trasferimento di zona per la gestione dei record è la scelta più adeguata? Assolutamente no. Infatti esso non prevede la cifratura dei dati durante la loro trasmissione, sfrutta un pessimo meccanismo per la compressione delle informazioni e soprattutto garantisce un livello di sicurezza del tutto insufficiente. E proprio grazie alle query AXFR un utente malevolo può ottenere informazioni preziosissime riguardanti la rete target.

Bando alle ciance e passiamo subito ad un esempio pratico:

nightfly@nightbox:~$ dig unirc.it NS
; <<>> DiG 9.5.1-P2 <<>> unirc.it NS
;; global options:  printcmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 12144
;; flags: qr rd ra; QUERY: 1, ANSWER: 2, AUTHORITY: 0, ADDITIONAL: 0

;; QUESTION SECTION:
;unirc.it.                      IN      NS

;; ANSWER SECTION:
unirc.it.               3600    IN      NS      ns1.garr.net.
unirc.it.               3600    IN      NS      (nameserver omesso).

;; Query time: 211 msec
;; SERVER: 151.99.125.2#53(151.99.125.2)
;; WHEN: Wed Sep 30 18:26:09 2009
;; MSG SIZE  rcvd: 73

In questo modo abbiamo individuato i server autoritativi per il dominio unirc.it. Adiamo subito a testare la robustezza di uno dei nameserver sopra elencati:

nightfly@nightbox:~$ dig @(nameserver omesso) unirc.it axfr
; <<>> DiG 9.5.1-P2 <<>> @(nameserver omesso) unirc.it axfr
; (1 server found)
;; global options:  printcmd
unirc.it.               3600    IN      SOA     (nameserver omesso). root.*.unirc.it. 2009072401 7200 7200 604800 86400
unirc.it.               3600    IN      MX      10 msgbox2.unirc.it.
unirc.it.               3600    IN      MX      30 msgbox.unirc.it.
unirc.it.               3600    IN      NS      ns1.garr.net.
unirc.it.               3600    IN      NS      (nameserver omesso).
www.*.unirc.it. 3600 IN     A       193.*.*.130
www.*.unirc.it.      3600    IN      A       192.*.*.100
www.*.unirc.it.       3600    IN      A       193.*.*.130
www.*.unirc.it.      3600    IN      A       193.*.*.130
*.unirc.it.       3600    IN      NS      (nameserver omesso).
www.*.unirc.it. 3600  IN      A       192.*.*.100
www.*.unirc.it.        3600    IN      A       193.*.*.130
www.*.unirc.it.    3600    IN      A       193.*.*.130
www.*.unirc.it. 3600 IN  A       193.*.*.130
*.unirc.it.  3600    IN      NS      (nameserver omesso).
www.*.unirc.it.     3600    IN      A       192.*.*.100
www.*.unirc.it.      3600    IN      A       193.*.*.130

ecc. (una parte dell’output è stata volontariamente omessa).

In questo modo abbiamo formulato una query AXFR al nameserver, chiedendo informazioni sul dominio unirc.it. Quello che abbiamo ottenuto è tutta una serie di record A (address, ovvero gli indirizzi IP associati ai nomi di dominio), MX (Mail Exchange, ovvero i server di posta), ed NS (ovvero Name Server), i DNS autoritativi per quel determinato dominio.

Se andiamo ad eseminare meglio i record precedentemente elencati, noteremo la presenza di indirizzi privati di classe C (192.168.*.*), i quali rappresentano un’informazione preziosissima per ogni attacker, senza considerare alcuni nomi deltutto esplicativi, vedi CISCO*.unirc.it oppure CISCO-LWAPP*.unirc.it.

Come correre ai ripari? Per prima cosa si dovrebbe utilizzare un metodo alternativo agli zone transfer mediante AXFR, utilizzando, ad esempio, SSH + rsynch per il trasferimento incrementale dei record.

Si dovrebbe, inoltre, effettuare una netta separazione tra i record appartenenti agli host di rete interna da quelli relativi alla rete esterna (magari gestendoli mediante server DNS differenti).

Infine si dovrebbe impedire che un utente qualsiasi riesca a forzare uno zone transfer, consentendo tale operazione solo a client autorizzati (magari implementando l’autenticazione ed utilizzando la direttiva allow-transfer nel file di configurazione di bind in cui vengono definite le varie zone, ovvero named.conf.local).

NB: è buona pratica cercare di limitare l’uso di record TXT ed HINFO, in quanto potrebbero fornire informazioni utilissime ad un eventuale attaccante.

Attacchi DDoS

Da notare che converrebbe sempre disabilitare la ricorsione, in quanto il DNS potrebbe essere vittima di attacchi distribuited denial of service (DDoS), basati sostanzialmente su migliaia di query provenienti da host differenti (botnet). Poichè, per ogni query, il DNS si prende in carico la richiesta ed interroga ricorsivamente i vari server DNS autoritativi per le zone interessate, il carico di lavoro dello stesso potrebbe essere eccessivo, portandolo a crashare o rendendolo irraggiungibile anche per gli utenti legittimi.

Statistiche

Un server DNS che consente interrogazioni anche da parte di utenti non autorizzati può fornire informazioni di estrema utilità, soprattutto per i cybercriminali. Infatti, possono essere stilate delle statistiche in cui vengono identificati gli errori più frequenti che commettono i vari user legittimi quando effettuano le interrogazioni al server DNS (ad esempio digitando www.postre.it anzichè www.poste.it). Basta quindi creare un clone del sito legittimo (www.poste.it), metterlo sul dominio www.postre.it ed ecco che l’esca è pronta (leggasi phishing).

Morale della favola… fate molta attenzione durante la fase di configurazione dei server DNS.

A presto.