Archivi tag: DHCP

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.

DHCP e lease time: alcune considerazioni

Dopo la recente migrazione di un server DHCP da un dispositivo di tipo embedded ad un server dedicato (nella fattispecie un domain controller), mi sono soffermato sulla corretta configurazione del lease time.

dhcplease

Premesso che non esiste una configurazione “corretta” a prescindere, ma che essa dipende strettamente dal tipo di network su cui il servizio DHCP è in ascolto, occorre trovare la giusta quadra tra un tempo di lease ragionevole e l’utilizzo delle risorse locali del server (tenendo in cosiderazione, ovviamente, anche l’eventuale traffico previsto sulla rete).

Infatti, di per sè, il servizio DHCP (soprattutto quello messo a disposizione da Microsoft, almeno fino alla versione Windows Server 2008, secondo quanto riportato qui), prevede un uso “intensivo” del disco (leggasi I/O rate), in quanto il database con le associazioni IP/MAC viene consultato ogni volta che un nuovo dispositivo si “presenta” in rete oppure intende rinnovare il proprio tempo di lease. Ciascun client DHCP tenterà un rinnovo del tempo di lease allo scadere del 50% dello stesso (passando dallo status BOUND a quello RENEWING). Se tale attività non andrà a buon fine, verrà tentato un rinnovo allo scadere dell’87.5% del lease time (passando dallo status RENEWING a quello REBINDING). Se anche in questo caso non si otterrà l’estensione del suddetto tempo di lease, il client entrerà in status INIT per richiedere un nuovo indirizzo IP. E’ palese che tali tentativi sono tanto più frequenti quanto il tempo di lease è ridotto.

Ora, un tempo di lease “basso” è comunque una scelta corretta quando si ha a che fare con una rete che prevede la connessione di un numero abbastanza elevato di dispositivi (Wi-Fi), pur essendoci a disposizione un pool DHCP (leggasi scope) non molto esteso (ad esempio una classe /25). In questo caso un lease time di 360 minuti (6 ore) sembra abbastanza ragionevole. Invece, se si ha a che fare con network in cui il numero di dispositivi è piuttosto ridotto, va bene mantenere il lease time di default (pari a 8 giorni per il DHCP server di casa Microsoft).

Una volta impostato il lease time conviene sempre e comunque tenere sotto controllo lo stato del servizio DHCP, poichè un’errata configurazione dello stesso potrebbe portare all’impossibilità, da parte dei client, di connettersi alla rete (DHCPNAK ad ogni nuova richiesta per via dello scope ormai saturo).

Qui trovate un link in cui sono presenti le varie icone (con relativo significato) che possono comparire sullo “status” del server DHCP Microsoft.

E’ tutto. Alla prossima.

Cisco RV016 e firmware 4.2.3.03-tm: problemi con il server DHCP integrato

Premesso che il router Cisco RV016 sembrava uno dei migliori oggetti presenti sul mercato dedicato agli abienti SOHO, ho riscontrato, durante il suo normale utilizzo, tutta una serie di bug che ne inficiano il funzionamento e che mi hanno fatto ricredere sulla sua effettiva qualità.

Uno di questi bug riguarda il server DHCP integrato, il quale, di punto in bianco, ha smesso di rilasciare gli indirizzi IP (compresa subnet mask, gateway e nameserver) ai client connessi in rete.

Ho deciso di andare a fondo alla questione e, armato di sniffer (tcpdump), ho salvato le relative tracce, che si possono riassumere in quanto segue (nell’immagine seguente sono riportate le 4 fasi principali relative al “normale” funzionamento del protocollo DHCP) :

dhcp1) Il client invia in broadcast un messaggio del tipo DHCPDISCOVER, alla ricerca dei server DHCP in ascolto sulla porta UDP 67:

15:03:00.463759 IP (tos 0x0, ttl 128, id 29956, offset 0, flags [none], proto UDP (17), length 328)
    0.0.0.0.bootpc > 255.255.255.255.bootps: BOOTP/DHCP, Request from 74:e6:e2:0e:3d:a0 (oui Unknown), length 300, xid 0x24dc5170, Flags [none]
          Client-Ethernet-Address 74:e6:e2:0e:3d:a0 (oui Unknown)
          Vendor-rfc1048 Extensions
            Magic Cookie 0x63825363
            DHCP-Message Option 53, length 1: Discover
            Client-ID Option 61, length 7: ether 74:e6:e2:0e:3d:a0
            Hostname Option 12, length 10: "ClientPC"
            Vendor-Class Option 60, length 8: "MSFT 5.0"
            Parameter-Request Option 55, length 13:
              Subnet-Mask, Domain-Name, Default-Gateway, Domain-Name-Server

2) Al suddetto messaggio fa seguito un DHCPOFFER, inviato dal server al client (unicast), il quale contiene tutta una serie di informazioni, come l’indirizzo IP che intende assegnare al dispositivo che lo ha appena contattato:

15:03:00.470460 IP (tos 0x0, ttl 64, id 0, offset 0, flags [none], proto UDP (17), length 332)
    dhcpserver.domain.local.bootps > 192.168.18.203.bootpc: BOOTP/DHCP, Reply, length 304, xid 0x24dc5170, Flags [none]
          Your-IP 192.168.18.203
          Client-Ethernet-Address 74:e6:e2:0e:3d:a0 (oui Unknown)
          Vendor-rfc1048 Extensions
            Magic Cookie 0x63825363
            DHCP-Message Option 53, length 1: Offer
            Server-ID Option 54, length 4: dhcpserver.domain.local

3) Il client risponde al server accettando l’Indirizzo IP e gli altri parametri di rete che gli sono stati proposti, utilizzando un apposito messaggio denominato DHCPREQUEST (in broadcast):

15:03:00.473016 IP (tos 0x0, ttl 128, id 29957, offset 0, flags [none], proto UDP (17), length 345)
 0.0.0.0.bootpc > 255.255.255.255.bootps: BOOTP/DHCP, Request from 74:e6:e2:0e:3d:a0 (oui Unknown), length 317, xid 0x24dc5170, Flags [none]
 Client-Ethernet-Address 74:e6:e2:0e:3d:a0 (oui Unknown)
 Vendor-rfc1048 Extensions
 Magic Cookie 0x63825363
 DHCP-Message Option 53, length 1: Request
 Client-ID Option 61, length 7: ether 74:e6:e2:0e:3d:a0
 Requested-IP Option 50, length 4: 192.168.18.203
 Server-ID Option 54, length 4: dhcpserver.domain.local
 Hostname Option 12, length 10: "ClientPC"
 FQDN Option 81, length 13: "ClientPC"

4) Infine, il server, mediante un DHCPNAK (in broadcast), declina la suddetta richiesta inoltratagli dal client:

15:03:00.477422 IP (tos 0x0, ttl 64, id 0, offset 0, flags [none], proto UDP (17), length 278)    dhcpserver.domain.local.bootps > 255.255.255.255.bootpc: BOOTP/DHCP, Reply, length 250, xid 0x24dc5170, Flags [none]
          Client-Ethernet-Address 74:e6:e2:0e:3d:a0 (oui Unknown)
          Vendor-rfc1048 Extensions
            Magic Cookie 0x63825363
            DHCP-Message Option 53, length 1: NACK
            Server-ID Option 54, length 4: dhcpserver.domain.local

Il malfunzionamento è proprio questo, ovvero il server continuerà a rispondere con dei DHCPNAK (anzichè i DHCPACK), inibendo l’ottenimento dei parametri di rete a tutti i client.

Ho risolto “migrando” il server DHCP dal router al Domain Controller.

Per ulteriori info sui messaggi DHCP potete consultare questa pagina.

Alla prossima.

PS: tale bug sembra essere strettamente correlato alla versione del firmware (4.2.3.03-tm), infatti con la versione immediatamente precedente (4.2.2.08) non ho mai riscontrato malfunzionamenti in tal senso.