[successivo] [precedente] [inizio] [fine] [indice generale] [indice ridotto] [indice analitico] [home] [volume] [parte]


Capitolo 301.   DHCP

La sigla DHCP sta per Dynamic host configuration protocol e identifica un protocollo attraverso il quale un gruppo di nodi può essere configurato in modo automatico e dinamico, per ciò che riguarda la sua connessione nella rete.(1)

Per comprendere il problema, si immagini un ufficio con una rete locale chiusa, in cui si vogliono poter collocare dei nodi senza troppi problemi, soprattutto senza dover stabilire prima gli indirizzi IP e i nomi corrispondenti.

Per attuare questo meccanismo attraverso il protocollo DHCP, occorre un servente che sia in grado di rispondere a una richiesta del genere, con dei clienti in grado di fare tale richiesta adeguandosi alla risposta ricevuta.

Quando un cliente contatta un servente DHCP per la prima volta, tra i due viene concordato un tempo di validità per la configurazione assegnata al cliente. Ciò permette all'elaboratore cliente di mantenere quella configurazione per un certo tempo, senza che questa debba essere necessariamente ridefinita ogni volta che lo si riavvia. Questo tempo viene indicato con il termine lease ed è compito del servente tenere memoria dei nodi che possono trovarsi nella rete di sua competenza; i clienti devono richiedere ogni volta al servente i dati per la loro configurazione, ma almeno si cerca di fare in modo che questi restino uguali per il tempo di lease, che deve essere configurato in modo conveniente in base alle caratteristiche della rete.

Il termine inglese fa intendere che il cliente «affitta» la sua posizione nella rete.

301.1   Introduzione e sistemazioni generali

Il cliente che tenta di contattare un servente DHCP deve utilizzare una chiamata circolare. Per questo, nel caso di un sistema GNU/Linux, i kernel utilizzati negli elaboratori clienti e quello del servente, devono essere stati predisposti opportunamente per il multicasting (sezione 67.2.7).

Si verifica facilmente che sia disponibile questa caratteristica attraverso ifconfig, dando una configurazione transitoria a un'interfaccia e quindi visualizzando il suo stato come nel caso seguente:

ifconfig eth0[Invio]

eth0      Link encap:Ethernet  HWaddr 00:A0:24:77:49:97
          inet addr:192.168.1.1  Bcast:192.168.1.255  Mask:255.255.255.0
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:0 errors:0 dropped:0 overruns:0
          TX packets:87 errors:0 dropped:0 overruns:0
          Interrupt:12 Base address:0xff80 

In questo caso si vede apparire la parola MULTICAST, che rappresenta l'attivazione della modalità corrispondente, risolvendo ogni dubbio.

Un servente DHCP potrebbe avere qualche difficoltà a funzionare correttamente con le prime versioni dei kernel Linux (dovrebbe trattarsi delle versioni 2.0....). Il servente DHCP deve essere in grado di trasmettere dei pacchetti all'indirizzo IP 255.255.255.255, corrispondente idealmente a «tutti i nodi». Può darsi che per poterlo fare, si debba creare un instradamento apposito, su tutte le interfacce di rete attraverso cui il servente deve essere raggiungibile e da cui deve poter rispondere.

route add -host 255.255.255.255 dev eth0[Invio]

route add -host 255.255.255.255 dev eth1[Invio]

L'esempio, in particolare, mostra l'instradamento attraverso le interfacce eth0 e eth1.

Nelle versioni 2.2.* del kernel Linux, potrebbe essere necessario abilitare la funzionalità di IP boot agent, attraverso un comando simile a quello seguente:

echo 1 > /proc/sys/net/ipv4/ip_bootp_agent[Invio]

In ultima analisi, un kernel Linux deve essere stato predisposto per la gestione di {Packet socket} e {Socket filtering} (oppure {Network packet filtering}). Nel file di configurazione della compilazione del kernel, queste voci corrispondono a CONFIG_PACKET e a CONFIG_FILTER (oppure CONFIG_NETFILTER). Si veda eventualmente il capitolo 67.2.7.

301.1.1   Rete di competenza e router

Teoricamente, dovrebbe essere possibile fare in modo che il servente DHCP riceva le richieste dei clienti anche se queste devono attraversare dei router. In pratica, ciò richiede che i router siano in grado di trasferire tali richieste, oppure che presso di loro sia presente un servizio intermedio di relè (relay). Comunque, si tratterebbe di una politica amministrativa discutibile.

In generale, il servente DHCP dovrebbe essere collocato nella rete fisica che si trova a servire, mentre le richieste dei clienti non dovrebbero poter attraversare i router.

L'utilizzo del protocollo DHCP può costituire un problema serio di sicurezza; in questo senso, sarebbe meglio se i router non fossero in grado di trasferire le connessioni con questo protocollo.

301.1.2   Conflitto con il supervisore dei servizi di rete

Normalmente, il protocollo DHCP utilizza la porta 67 UDP, che di solito è denominata bootps. Pertanto, il supervisore dei servizi di rete potrebbe essere stato predisposto per la gestione del servizio BOOTP su quella porta. Per esempio, nel file /etc/inetd.conf, che riguarda precisamente la configurazione di Inetd, dovrebbe essere presente una riga simile a quella seguente, commentata nello stesso modo.

...
#bootps dgram   udp     wait    root    /usr/sbin/tcpd  bootpd
...

Se la gestione del servizio BOOTP fosse abilitata, ciò andrebbe in conflitto con i demoni usati per il DHCP, sia nel nodo del servente, sia nei nodi clienti.

301.1.3   Informazioni gestibili attraverso DHCP

Attraverso il protocollo DHCP, i nodi clienti possono ricevere una serie di informazioni utili a definire la loro collocazione nella rete circostante. Il minimo indispensabile di tali informazioni è costituito normalmente dall'indirizzo IPv4 e dalla maschera di rete relativa. Dipende dalle caratteristiche del servente la possibilità di offrire informazioni aggiuntive. L'elenco seguente è solo un esempio delle informazioni che potrebbero essere date:

301.2   Servente DHCP ISC

Il servente DHCP che si trova di solito nelle distribuzioni GNU è quello la cui produzione è finanziata da Internet Software Consortium. (2) Viene fatta questa precisazione, perché in seguito viene mostrato l'utilizzo di un cliente di origine differente.

Questo servente si compone del demone dhcpd, il quale si avvale della configurazione contenuta nel file dhcpd.conf (/etc/dhcpd.conf, /etc/dhcp*/dhcpd.conf o simile), inoltre utilizza il file dhcpd.leases (che potrebbe essere collocato nella directory /var/lib/dhcp*/) per annotare gli indirizzi concessi ai vari clienti, finché questi restano validi. Questo ultimo file, dhcpd.leases, deve esistere (vuoto) prima che il demone possa essere avviato la prima volta. Eventualmente, il demone dhcpd è in grado di offrire anche un servizio BOOTP, se la configurazione contiene le informazioni necessarie per la gestione di questo tipo di protocollo.

Il problema di organizzazione del servente si limita quindi alla configurazione del file dhcpd.conf.

Segue il modello sintattico per l'avvio del demone:

dhcpd [opzioni] [interfaccia...]

In generale, dhcpd non richiede alcun argomento nella riga di comando, limitandosi così a leggere la configurazione e a porsi in ascolto di tutte le interfacce in grado di gestire il multicast, funzionando come demone. L'indicazione di una o più interfacce di rete, alla fine degli argomenti, permette di specificare dove dhcpd deve porre la sua attenzione, ignorando le altre eventualmente presenti.

Opzione Descrizione
-p n_porta
dhcpd è in ascolto normalmente della porta UDP numero 67 (bootps), ma ciò può essere cambiato attraverso questa opzione.
-cf file_di_configurazione
Permette di definire un file di configurazione alternativo a quello predefinito.
-lf file_lease
Permette di definire un file alternativo a quello predefinito per l'accumulo delle informazioni sui nodi che hanno ottenuto un indirizzo IP.

La configurazione con il file dhcpd.conf permette di definire il funzionamento di dhcpd, sia per la gestione del protocollo DHCP, sia per BOOTP. Qui si intendono mostrare solo le direttive utili per il protocollo DHCP.

In questo file sono ammessi i commenti, preceduti dal simbolo # e terminati dalla fine della riga in cui appaiono. È consentito inoltre spaziare le direttive attraverso righe vuote o righe bianche, che vengono ignorate.

Le direttive sono organizzare in forma di struttura, in cui appare la dichiarazione di ciò a cui fa riferimento tale struttura, seguita dall'indicazione di una serie di parametri specifici, racchiusi tra parentesi graffe.

[parametro_globale;]
[parametro_globale;]
...
dichiarazione {
    [parametro_specifico;]
    ...
    [sotto_dichiarazione {
        [parametro_più_specifico;]
        ...
    }]
    ...
}
...

Lo schema sintattico è un po' confuso a prima vista, ma significa che il file può iniziare con una serie di direttive (facoltative) contenenti l'indicazione di alcuni parametri (viene chiarito in seguito di cosa può trattarsi), il cui effetto ha valore globale, salvo la possibilità di essere offuscati da definizioni contrastanti all'interno di direttive di dichiarazione.

Il file deve contenere almeno una direttiva di dichiarazione che può limitarsi a contenere dei parametri specifici, oppure può inglobare delle sotto-dichiarazioni.

La cosa migliore, per cominciare, è introdurre un esempio. Si supponga di volere servire la rete locale 192.168.1.0/255.255.255.0, specificando che gli indirizzi da 192.168.1.100 a 192.168.1.199 possono essere gestiti per le attribuzioni dinamiche di indirizzi IP. Il file di configurazione può limitarsi a contenere quanto segue:

subnet 192.168.1.0 netmask 255.255.255.0 {
    range 192.168.1.100 192.168.1.199;
}

La direttiva di dichiarazione subnet, come si può intuire, è quella più importante per la gestione del DHCP. Nella maggior parte dei casi, la configurazione si compone di una o più direttive di questo tipo, contenenti probabilmente più parametri di quanto visto nell'esempio.

Prima di mostrare più in dettaglio le altre direttive, viene presentato un altro esempio, che potrebbe soddisfare le esigenze più comuni di chi utilizza dhcpd (a parte i valori particolari che sono stati indicati). Rispetto all'esempio precedente si nota la presenza di due intervalli di indirizzi IP da utilizzare per l'attribuzione automatica; per il resto, momentaneamente, dovrebbe essere intuitivo il significato.

subnet 192.168.1.0 netmask 255.255.255.0 {
    range 192.168.1.100 192.168.1.149;
    range 192.168.1.200 192.168.1.249;
    default-lease-time 604800;  # una settimana
    max-lease-time 2592000;     # 30 giorni
    option subnet-mask 255.255.255.0;
    option broadcast-address 192.168.1.255;
    option routers 192.168.1.1;
    option domain-name-servers 192.168.1.1, 192.168.1.2;
    option domain-name "brot.dg";
}

Prima di proseguire con la descrizione di alcuni tra dichiarazioni e parametri, si osservi che i parametri sono terminati dal punto e virgola. È ammesso indicare più parametri sulla stessa riga, anche se in generale è preferibile evitarlo.

Dichiarazione Descrizione
shared-network nome {
    [parametro;]
    ...
    dichiarazione {
        ...
    }
    ...
}
Come si osserva dalla sintassi, una dichiarazione shared-network è fatta per l'inclusione di altre dichiarazioni e non solo di parametri. Permette di specificare una rete condivisa, nel senso di due o più reti logiche che si trovano sulla stessa rete fisica. In questa situazione, è normale che la direttiva includa l'indicazione di più dichiarazioni subnet, una per ogni rete logica. Il problema, semmai, è che quando si collocano dei nodi nuovi nella rete condivisa, non è possibile distinguere a quale delle reti logiche dovrebbero appartenere; di conseguenza, ottengono semplicemente il primo indirizzo libero nell'insieme globale.
group {
    [parametro;]
    ...
    dichiarazione {
        ...
    }
    ...
}
La dichiarazione group serve solo a definire un raggruppamento di dichiarazioni, a cui attribuire una serie di parametri in modo predefinito. Evidentemente si tratta dei parametri che precedono le direttive delle dichiarazioni annidate.
subnet indirizzo_di_rete netmask maschera_di_rete {
    [parametro;]
    ...
}
La dichiarazione subnet serve a contenere l'indicazione di parametri specifici per la sottorete. Permette di definire una sottorete, indicata attraverso l'indirizzo e la maschera di rete.
Parametro Descrizione
authoritative;
not authoritative;
L'opzione authoritative (opposta a not authoritative che invece è predefinita), consente di specificare che il servente è «autorevole» e che può riconfigurare i nodi che risultano configurati in modo errato.
default-lease-time n_secondi;
Definisce il tempo predefinito per la scadenza dell'associazione tra nodo e indirizzo IP assegnato. Viene utilizzato se il cliente non richiede una durata differente.
max-lease-time n_secondi;
Definisce il tempo massimo per la scadenza dell'associazione tra nodo e indirizzo IP assegnato. Il cliente non può ottenere un tempo maggiore (che comunque può essere rinnovato).
range indirizzo_ip_iniziale indirizzo_ip_finale;
Indica l'intervallo di indirizzi IP utilizzabili in modo dinamico. Più intervalli separati possono essere indicati utilizzando più volte questo tipo di parametro.
option subnet-mask maschera_di_rete;
Permette di specificare la maschera di rete, modificando eventualmente quanto stabilito in modo predefinito.
option broadcast-address indirizzo_broadcast;
Permette di definire l'indirizzo broadcast.
option routers indirizzo_ip_del_router;
Permette di indicare l'indirizzo IP del router predefinito.
option domain-name-servers indirizzo_dns[,...];
Permette di indicare un elenco di indirizzi di serventi DNS. Gli indirizzi sono separati attraverso una virgola.
option domain-name "dominio";
Stabilisce il nome di dominio. Di solito si tratta del dominio della rete o della sottorete a cui si fa riferimento.
option nis-domain dominio_nis;
Stabilisce il dominio NIS.
option nis-servers servente_nis\
  \[, servente_nis]...;
Indica uno o più serventi NIS.
option lpr-servers servente_lpr\
  \[, servente_lpr]...;
Indica uno o più serventi di stampa (stampanti di rete).
option log-servers servente_log\
  \[, servente_log]...;
Indica uno o più nodi in grado di ricevere annotazioni da aggiungere al registro del sistema.
option root-path "nodo:/percorso";
Indica il nodo e il percorso a partire dal quale è possibile innestare il file system.

Per conoscere tutte le «opzioni» che si possono inserire nelle direttive option, si deve leggere la pagina di manuale dhcp-options(5).

301.2.1   Avvio e arresto del servizio

In condizioni normali, il demone dhcpd viene controllato dalla procedura di inizializzazione del sistema, attraverso uno dei suoi script. L'esempio che segue rappresenta un modo semplice per ottenere questo, dove la variabile di ambiente INTERFACES viene usata per contenere l'elenco delle interfacce di rete da configurare:

#!/bin/sh
#
test -f /usr/sbin/dhcpd || exit 0
#
INTERFACES="eth0"
#
case "$1" in
  start)
        echo -n "Avvio del servizio DHCP: "
        /usr/sbin/dhcpd -q $INTERFACES
        echo
        ;;
  stop)
        echo -n "Disattivazione del servizio DHCP: "
        killall dhcpd
        echo
        ;;
  *)
        echo "Utilizzo: dhcp-server {start|stop}"
        exit 1
esac

Nel caso particolare della distribuzione GNU/Linux Debian, questo script è certamente più complesso, ma fa uso proprio della variabile di ambiente INTERFACES, che viene definita nel file /etc/default/dhcp3-server:

# Defaults for dhcp initscript
# sourced by /etc/init.d/dhcp
# installed at /etc/default/dhcp3-server by the maintainer scripts

#
# This is a POSIX shell fragment
#

# On what interfaces should the DHCP server (dhcpd) serve DHCP requests?
#       Separate multiple interfaces with spaces, e.g. "eth0 eth1".
INTERFACES="eth0"

301.2.2   Interfaccia di rete e alias con i sistemi GNU/Linux

Quando si utilizza il servente DHCP di ISC su un sistema GNU/Linux, occorre tenere presente che l'interfaccia di rete che si indica alla fine della riga di comando di dhcpd, deve essere reale; in pratica, non può trattarsi di un «alias», come potrebbe esserlo un nome del tipo eth0:1.

Figura 301.10. Un router per due reti che in realtà sono fisicamente la stessa.

router

Quando si configura un router con una sola interfaccia di rete reale (utilizzando il sistema GNU/Linux), diventa praticamente indispensabile fare riferimento al nome di interfaccia reale per ciò che si può considerare come la «rete esterna». Questa necessità dipende dal fatto che il programma iptables, usato, per esempio, per configurare il NAT e un sistema di filtri, richiede l'indicazione di un nome di interfaccia reale, ma dovendo scegliere, in questo caso, è importante che il nome reale sia riferito alla rete esterna.

Se si vuole attivare un servizio DHCP all'interno di un elaboratore che è collegato a due reti (reali o virtuali), è ragionevole supporre che questo servizio serva per quella rete che si considera, in qualche modo, interna. Se però si sta lavorando nelle condizioni ipotizzate, dove si dispone di una sola interfaccia reale e si attribuiscono degli alias, dovendo utilizzare il nome reale dell'interfaccia per la rete esterna, finisce che il servizio DHCP opera proprio dove non serve.

Figura 301.11. In questo caso, il servizio DHCP interviene in un gruppo di indirizzi della rete 192.168.1.*, ma si trova formalmente a essere fornito dall'indirizzo 1.2.3.4. In questo caso, succede in particolare che il file /tftpboot/kernel risulta trovarsi presso l'elaboratore 1.2.3.4, mentre un sistema senza disco fisso (diskless) della rete 192.168.1.* si trova in difficoltà a raggiungerlo.

router

Purtroppo, non c'è modo di istruire il demone dhcpd di rispondere utilizzando l'indirizzo mittente che si preferisce per la rete interna. Il programma dhclient che viene descritto in una sezione apposita, può superare il problema, purché ci sia un router che consente di raggiungere l'indirizzo del lato esterno (si suppone che sia lo stesso nodo che ha questa interfaccia singola che esegue il compito di router); tuttavia, altri programmi non ne sono in grado; in particolare l'avvio di un sistema senza disco potrebbe essere in crisi.

Eventualmente si può sfruttare un raggiro molto semplice: si configura temporaneamente l'interfaccia reale con l'indirizzo da usare per la rete interna; si avvia il demone dhcpd; si riconfigura l'interfaccia con l'indirizzo esterno e si dichiara un alias per l'indirizzo interno. In questo modo, il demone dhcpd continua a lavorare considerando l'indirizzo interno corretto:

ifconfig eth0 192.168.1.254[Invio]

/usr/sbin/dhcpd -q eth0[Invio]

ifconfig eth0 1.2.3.4[Invio]

ifconfig eth0:1 192.168.1.254[Invio]

...

Ovviamente, la sequenza mostrata delle operazioni è semplificata, in quanto non verifica la necessità eventuale di dover terminare il funzionamento di un demone dhcpd già attivo, inoltre non si considera la possibilità di disattivare l'interfaccia di rete prima di riconfigurarla.

301.3   Relè DHCP ISC

Nello stesso pacchetto del servente DHCP descritto nelle sezioni precedenti, si trova normalmente il demone dhcrelay. Questo è in grado di fungere da ripetitore per una richiesta fatta da un cliente DHCP, quando questa, diversamente, non può attraversare un router.

All'inizio del capitolo si è accennato al fatto che sarebbe meglio evitare che un servizio DHCP possa superare i router; tuttavia, chi desidera utilizzare ugualmente tale possibilità, lo può fare attraverso questo programma.

dhcrelay [opzioni] servente_dhcp...

Il programma dhcrelay è un demone in grado di ritrasmettere le richieste fatte da un cliente DHCP a un servente che altrimenti non sarebbe raggiungibile. Nello stesso modo, le risposte vengono rinviate all'origine.

Il programma dhcrelay non richiede configurazione; l'unica cosa indispensabile è l'indicazione di almeno un servente DHCP alla fine della riga di comando.

Tabella 301.12. Alcune opzioni.

Opzione Descrizione
-p n_porta
Permette di specificare un numero di porta differente da quella standard (67).
-i interfaccia
Permette di indicare in modo esplicito un'interfaccia di rete da cui dhcrelay può aspettarsi delle richieste da parte di clienti DHCP. Per indicare più interfacce, occorre usare più volte questa opzione. Questa opzione è utile in particolare per escludere eventualmente un'interfaccia di una rete fisica su cui potrebbe esserci già il servente DHCP relativo, in grado di intervenire da solo.

301.4   Cliente DHCP

Il cliente DHCP ha il compito di interpellare un servente attraverso una chiamata circolare fatta nella rete fisica in cui si trova lo stesso cliente, ottenendo da questo l'indicazione dell'indirizzo IPv4 da utilizzare, assieme ad altre informazioni di contorno eventuali. Successivamente, ha il compito di ripresentarsi presso il servente periodicamente, per evitare che scada il tempo concesso per l'identificazione che gli è stata attribuita (lease).

Il problema maggiore, semmai, è fare in modo che il sistema presso cui è in funzione il cliente DHCP sia in grado di adeguarsi alle informazioni ottenute in questo modo. Non basta sapere quale indirizzo IPv4 si può utilizzare per una certa interfaccia di rete, occorre anche configurarla e definire l'instradamento. A questo proposito, il cliente DHCP è un punto delicato, per cui la scelta, ammesso che ce ne sia più di una, va fatta pensando all'integrazione con il proprio sistema operativo.

301.4.1   Cliente DHCP ISC

Nel pacchetto DHCP di Internet Software Consortium è disponibile il programma cliente dhclient per l'interrogazione di tale servizio:

dhclient [opzioni] [interfaccia...]

Il programma dhclient, una volta terminata la prima fase di scansione, avvia uno script con il quale configura l'interfaccia di rete e l'instradamento, quindi si mette a funzionare sullo sfondo, come demone.

Tabella 301.13. Alcune opzioni.

Opzione Descrizione
-p n_porta
Permette di specificare un numero di porta differente da quella standard (68).
-r
Richiede espressamente di abbandonare l'indirizzo IPv4 ottenuto (current lease); con questa opzione, il programma termina di funzionare (non rimane in funzione come demone).
-1
Esegue una sola serie di tentativi; se non riesce a contattare un servente DHCP termina di funzionare.
-q
Fa in modo di non mostrare informazioni nel momento dell'avvio, prima di passare al funzionamento sullo sfondo.
-cf file_di_configurazione
Permette di definire un file di configurazione alternativo a quello predefinito.
-lf file_lease
Permette di definire un file alternativo a quello predefinito per l'accumulo delle informazioni ottenute (lease).
-sf file_script
Permette di definire uno script alternativo a quello predefinito, per la riconfigurazione in base ai dati ottenuti.

Una volta avviato, quando ottiene le informazioni che servono da un servente DHCP, le accumula nel file dhclient.leases che dovrebbe trovarsi nella directory /var/lib/dhcp*/, o nel file specificato con l'opzione -lf. Il contenuto di questo file potrebbe apparire in modo simile all'esempio seguente:

lease {
  interface "eth0";
  fixed-address 192.168.1.250;
  option subnet-mask 255.255.255.0;
  option routers 192.168.1.254;
  option dhcp-lease-time 86400;
  option dhcp-option-overload 3;
  option dhcp-message-type 5;
  option domain-name-servers 192.168.1.254;
  option dhcp-server-identifier 192.168.1.254;
  option broadcast-address 255.255.255.255;
  renew 1 2004/7/5 20:39:26;
  rebind 2 2004/7/6 07:57:59;
  expire 2 2004/7/6 10:57:59;
}

Il programma dovrebbe essere in grado di configurare automaticamente l'interfaccia di rete, l'instradamento locale e quello predefinito. Eventualmente può avere dei problemi a intervenire nel file /etc/resolv.conf, per indicare il servente DNS; in tal caso è necessario costruire un proprio script che estragga questa informazione dal file dhclient.leases.

Il programma dhclient prevede anche l'uso di un file di configurazione, dhclient.conf, che normalmente si colloca nella directory /etc/dhcp*/dhclient.conf, oppure può essere ridefinito con l'opzione -cf. Le cose più importanti da inserire in questo file sono le richieste da fare al servente DHCP, come si vede nell'esempio seguente che potrebbe essere usato per la maggior parte delle situazioni di utilizzo di tale programma:

request subnet-mask,
        broadcast-address,
        time-offset,
        routers,
        domain-name,
        domain-name-servers,
        host-name,
        netbios-name-servers,
        netbios-scope,
        time-servers,
        ntp-servers,
        root-path,
        nis-domain,
        nis-servers,
        lpr-servers,
        log-servers;

Per conoscere le altre direttive che, eventualmente, possono essere utilizzate per la configurazione, si deve consultare la pagina di manuale dhclient.conf(5); inoltre, per conoscere tutte le «opzioni» del protocollo, si deve leggere la pagina di manuale dhcp-options(5).

301.4.2   Script per l'utilizzo delle informazioni ottenute da un cliente DHCP ISC

Le informazioni che si possono ottenere attraverso un servizio DHCP sono molte e non è semplice standardizzarne l'utilizzo nell'ambito della procedura di inizializzazione del sistema. Pertanto, si può essere costretti a realizzare un proprio script per estrapolare i dati contenuti nel file /var/lib/dhcp*/dhclient.leases. L'esempio seguente rappresenta la parte saliente di uno script del genere, da inserire in qualche modo nella procedura di avvio del sistema. L'esempio ha il solo scopo di mostrare come si può fare in pratica a gestire tali informazioni. Una copia dovrebbe essere disponibile anche qui: <allegati/a2/dhcp-auto-configuration.sh>).

#!/bin/sh
#
# DHCP auto configuration.
#
function dhcp_auto_configuration () {
    #
    # DNS server.
    #
    AUTO_DNS_SERVER=`/bin/grep -m 1 "option  *domain-name-servers" \
        /var/lib/dhcp3/dhclient.leases \
        | sed "s/^ *option  *domain-name-servers  *\"*\([^ ;,\"]*\)\"*[ ;,]*.*$/\\1/"`
    #
    # Time server.
    #
    AUTO_TIME_SERVER=`/bin/grep -m 1 "option  *time-servers" \
        /var/lib/dhcp3/dhclient.leases \
        | sed "s/^ *option  *time-servers  *\"*\([^ ;,\"]*\)\"*[ ;,]*.*$/\\1/"`
    #
    # NTP server.
    #
    AUTO_NTP_SERVER=`/bin/grep -m 1 "option  *ntp-servers" \
        /var/lib/dhcp3/dhclient.leases \
        | sed "s/^ *option  *ntp-servers  *\"*\([^ ;,\"]*\)\"*[ ;,]*.*$/\\1/"`
    #
    # NFS root path.
    #
    AUTO_ROOT_PATH=`/bin/grep -m 1 "option  *root-path" \
        /var/lib/dhcp3/dhclient.leases \
        | sed "s/^ *option  *root-path  *\"*\([^ ;,\"]*\)\"*.*$/\\1/"`
    #
    # NIS domain.
    #
    AUTO_NIS_DOMAIN=`/bin/grep -m 1 "option  *nis-domain" \
        /var/lib/dhcp3/dhclient.leases \
        | sed "s/^ *option  *nis-domain  *\"*\([^ ;,\"]*\)\"*[ ;,]*.*$/\\1/"`
    #
    # NIS server.
    #
    AUTO_NIS_SERVER=`/bin/grep -m 1 "option  *nis-servers" \
        /var/lib/dhcp3/dhclient.leases \
        | sed "s/^ *option  *nis-servers  *\"*\([^ ;,\"]*\)\"*[ ;,]*.*$/\\1/"`
    #
    # LPR server.
    #
    AUTO_LPR_SERVER=`/bin/grep -m 1 "option  *lpr-servers" \
        /var/lib/dhcp3/dhclient.leases \
        | sed "s/^ *option  *lpr-servers  *\"*\([^ ;,\"]*\)\"*[ ;,]*.*$/\\1/"`
    #
    # Log server.
    #
    AUTO_LOG_SERVER=`/bin/grep -m 1 "option  *log-servers" \
        /var/lib/dhcp3/dhclient.leases \
        | sed "s/^ *option  *log-servers  *\"*\([^ ;,\"]*\)\"*[ ;,]*.*$/\\1/"`
    #
    # Restart the portmapper.
    #
    if [ "$AUTO_ROOT_PATH" != "" ] || [ "$AUTO_NIS_SERVER" != "" ]
    then
        #
        # Need to restart the portmapper.
        #
        /etc/init.d/portmap stop
        /etc/init.d/portmap start
    fi  
    #
    # Rebuild the file "/etc/resolv.conf"
    #
    if echo $AUTO_DNS_SERVER | grep "^[0-9]*\.[0-9]*\.[0-9]*\.[0-9]*$"
    then
        #
        # Update.
        #
        cp -f /etc/resolv.conf /etc/resolv.conf.orig
        #
        rm -f                                 /etc/resolv.conf
        echo "nameserver $AUTO_DNS_SERVER" >  /etc/resolv.conf
        #
    fi      
    #
    # Try to update the clock.
    #
    if [ "$AUTO_NTP_SERVER" != "" ]
    then
        #
        # We don't want to wait for the time server, so we
        # put all inside a (...) and send it in background.
        #
        (
            if ( [ -x /usr/sbin/ntpdate ] && ntpdate -u -b -s $AUTO_NTP_SERVER ) \
               || [ "$AUTO_TIME_SERVER" != "" ] \
                  && ( [ -x /usr/sbin/rdate ] && rdate -s $AUTO_TIME_SERVER )
            then
                hwclock -u -w 
            fi
        )  2>&1 > /dev/null &
        #
    elif [ "$AUTO_TIME_SERVER" != "" ]
    then
        #
        # We don't want to wait for the time server, so we
        # put all inside a (...) and send it in background.
        #
        (
            if ( [ -x /usr/sbin/rdate ] && rdate -s $AUTO_TIME_SERVER )
            then
                hwclock -u -w 
            fi
        )  2>&1 > /dev/null &
        #
    fi      
    #
    # Mount "/home/" from a remote NFS server, and
    # modify the "/etc/fstab".
    #
    if [ "$AUTO_ROOT_PATH" != "" ]
    then
        #
        # Remove last "/" if any.
        #
        AUTO_ROOT_PATH=`echo $AUTO_ROOT_PATH | sed "s/^\(.*\)\/$/\\1/"`
        #
        # Update.
        #
        echo "${AUTO_ROOT_PATH}/home  /home  nfs  user,auto,dev,exec,suid,soft,tcp  0  0" \
            > /tmp/fstab                                2> /dev/null
        #
        grep -v "/home" /etc/fstab >> /tmp/fstab        2> /dev/null
        #
        cat /tmp/fstab > /etc/fstab                     2> /dev/null
        #
        # Mount: before the mount, unmount if there is something already,
        # like a local USB stick, mounted automatically.
        #
        umount /home 2> /dev/null
        #
        mount -t nfs -o dev,exec,suid,soft,tcp ${AUTO_ROOT_PATH}/home /home
        #
    fi
    #
    # Set the NIS domain name.
    #
    if [ "$AUTO_NIS_DOMAIN" != "" ]
    then
        #
        # Update.
        #
        echo "$AUTO_NIS_DOMAIN" >  /etc/defaultdomain
        domainname "$AUTO_NIS_DOMAIN"
        #
    fi
    #
    # Configure the NIS server.
    #
    if [ "$AUTO_NIS_SERVER" != "" ]
    then
        #
        # Update.
        #
        echo "ypserver $AUTO_NIS_SERVER" > /etc/yp.conf
        #
        # Restart.
        #
        /etc/init.d/nis stop
        /etc/init.d/nis start
        #
    fi
    #
    # Remote printer configuration.
    #
    if [ "$AUTO_LPR_SERVER" != "" ]
    then
        #
        # Update.
        #
        rm -f                                      /etc/printcap
        echo -n ""                               > /etc/printcap
        echo "lp:\\"                            >> /etc/printcap
        echo "        :sd=/var/spool/lpd/lp:\\" >> /etc/printcap
        echo "        :af=/var/log/lp-acct:\\"  >> /etc/printcap
        echo "        :lf=/var/log/lp-errs:\\"  >> /etc/printcap
        echo "        :pl#66:\\"                >> /etc/printcap
        echo "        :pw#80:\\"                >> /etc/printcap
        echo "        :pc#150:\\"               >> /etc/printcap
        echo "        :mx#0:\\"                 >> /etc/printcap
        echo "        :mc#999:\\"               >> /etc/printcap
        echo "        :rp=lp:\\"                >> /etc/printcap
        echo "        :rm=$AUTO_LPR_SERVER:\\"  >> /etc/printcap
        echo "        :sh:"                     >> /etc/printcap
        echo ""                                 >> /etc/printcap
        #
        # Must restart "/etc/init.d/lprng".
        #
        /etc/init.d/lprng restart
        #
    fi
    #
    # Configure the remote log server.
    #
    if [ "$AUTO_LOG_SERVER" != "" ]
    then
        #
        # Update.
        #
        grep -v "\*\.\*.*@.*" /etc/syslog.conf > /tmp/syslog.conf
        echo ""                                >> /tmp/syslog.conf
        echo "*.*    @$AUTO_LOG_SERVER"        >> /tmp/syslog.conf
        #
        rm -f /etc/syslog.conf
        cat /tmp/syslog.conf > /etc/syslog.conf
        #
        # Must reload syslog daemon.
        #
        /etc/init.d/sysklogd reload-or-restart
        #
    fi
    #
    # It is assumed that a remote scanner is available
    # where some other service is..
    #
    if [ -d /etc/sane.d ]
    then
        rm -f                               /etc/sane.d/net.conf
        echo -n ""                       >  /etc/sane.d/net.conf
        echo "# /etc/sane.d/net.conf"   >>  /etc/sane.d/net.conf
        echo "127.0.0.1"                >>  /etc/sane.d/net.conf
        echo "[::1]"                    >>  /etc/sane.d/net.conf
        #
        # Add some nodes as possible remote scanner server.
        #
        if [ "$AUTO_NIS_SERVER" != "" ]
        then
            echo "$AUTO_NIS_SERVER"     >>  /etc/sane.d/net.conf
        fi
        #
        if [ "$AUTO_LPR_SERVER" != "" ]
        then
            echo "$AUTO_LPR_SERVER"     >>  /etc/sane.d/net.conf
        fi
        #
        if [ "$AUTO_LOG_SERVER" != "" ]
        then
            echo "$AUTO_LOG_SERVER"     >>  /etc/sane.d/net.conf
        fi
        #
    fi
}
#
#
#
dhcp_auto_configuration
#

301.4.3   Cliente DHCP alternativo

Nelle distribuzioni GNU/Linux si può trovare il programma dhcpcd (3) che non fa parte dello stesso pacchetto di ISC.

dhcpcd [opzioni] [interfaccia]

Il programma dhcpcd è un demone in grado di compiere il ruolo di cliente DHCP, per ottenere l'indicazione dell'indirizzo IPv4, della maschera di rete relativa, dell'indirizzo del router, del servente DNS oltre ad altre informazioni eventualmente fornite.

Il pregio principale di questo cliente è quello di essere capace di riconfigurare l'interfaccia di rete e di ridefinire l'instradamento in modo autonomo, senza richiedere la predisposizione di script appositi o di qualunque apparato di contorno.

Il limite di questo programma sta nel fatto di poter intervenire su una sola interfaccia di rete, che in modo predefinito è eth0.

Per quanto riguarda l'informazione del DNS, dhcpcd crea un file che riproduce il contenuto di /etc/resolv.conf; si tratta di /etc/dhcpc/resolv.conf. Per le altre informazioni, comprese quelle sull'interfaccia di rete e sull'instradamento, crea un altro file che ha l'aspetto di un pezzo di script di shell, che potrebbe essere utilizzato in qualche tipo di procedura di inizializzazione del sistema. Si tratta di /etc/dhcpc/hostinfo-interfaccia.

Tabella 301.17. Alcune opzioni.

Opzione Descrizione
-k
Invia un segnale SIGTERM al processo dhcpcd in funzione attualmente.
-l n_secondi
Specifica il tempo di lease da richiedere al servente. Il servente può accettarlo o concedere un tempo inferiore, a seconda della sua configurazione.

Segue la descrizione di alcuni esempi.

dhcpcd[Invio]

Avvia dhcpcd in modo normale, come demone, allo scopo di ottenere un indirizzo per l'interfaccia eth0.

dhcpcd eth1[Invio]

Avvia dhcpcd come demone, in modo da ottenere un indirizzo per l'interfaccia eth1.

Se il servente DHCP fornisce le indicazioni sui serventi DNS ed eventualmente anche il dominio di competenza, dhcpcd è in grado di creare il file /etc/dhcpc/resolv.conf, il cui scopo è di sostituirsi a quello omonimo collocato nella directory /etc/.

Se si vuole sfruttare questa opportunità, conviene sostituire il file /etc/resolv.conf con un collegamento simbolico a questo file generato da dhcpcd.

mv /etc/resolv.conf /etc/resolv.conf.orig[Invio]

ln -s /etc/dhcpc/resolv.conf /etc/resolv.conf[Invio]

Il file /etc/dhcpc/hostinfo-interfaccia viene creato da dhcpcd per contenere tutte le informazioni riferite a un'interfaccia particolare. Per esempio, quando si interviene su eth0, si ottiene il file /etc/dhcpc/hostinfo-eth0.

Il contenuto del file è realizzato in modo da essere compatibile con gli script per una shell derivata da quella di Bourne (come Bash, o altre meno sofisticate), per cui è facile inglobare tale file in uno script di una qualche procedura.

301.5   Riferimenti


1) Di solito, il protocollo DHCP si utilizza per IPv4, dal momento che IPv6 risolve già i problemi assegnazione automatica degli indirizzi.

2) DHCP ISC   software libero con licenza speciale

3) DHCPcd   GNU GPL


Appunti di informatica libera 2008 --- Copyright © 2000-2008 Daniele Giacomini -- <appunti2 (ad) gmail·com>


Dovrebbe essere possibile fare riferimento a questa pagina anche con il nome dhcp.htm

[successivo] [precedente] [inizio] [fine] [indice generale] [indice ridotto] [indice analitico] [home]

Valid ISO-HTML!

CSS validator!

Gjlg Metamotore e Web Directory