ISC DHCP est une implémentation Open Source du protocole DHCP (Dynamic Host Configuration Protocol), sous licence ISC License, écrite à l’origine par Ted Lem, sous contrat avec Vixie Labs, et dont le projet fut financé par l’Internet Systems Consortium (ISC).
La version 1 vit le jour en décembre 1997; elle ne comportait que la version serveur.
La version 2, de juin 1999, ajouta la partie cliente et l’agent de relais BOOTP/DHCP.
La version 3, sortie en octobre 2001 et financée par Nominum Inc., comportait de nombreux ajouts : support de la redondance pour la continuité de service, OMAPI, Dynamic DNS, le comportement conditionnel, la division des clients en classes, et bien plus encore…
La version 4, la dernière en date, sortie en décembre 2007, ajoutait enfin le support de l’IPv6 pour les parties cliente et serveur.
Objectif
L’objectif de cet article est l’installation et la configuration d’un serveur DHCP secondaire, ou slave, utilisant l’implémentation ISC DHCP, sur une distribution Linux Debian Jessie 8.4 32bits.
Schéma logique

Pré-requis
Pré-requis avant réalisation
- Un serveur Debian Jessie 8.4 32 bits fonctionnel (installation basique avec utilitaires usuels du système et service SSH) qui hébergera le service DHCP secondaire ou slave
- Un serveur Debian Jessie 8.4 32 bits fonctionnel et configuré comme serveur DHCP primaire ou master
- Packages de base supplémentaires : sudo, resolvconf, aptitude
- Domaine utilisé : opensharing.priv
Rmq : Ici, même si cela ne présente absolument aucun caractère obligatoire, nous utiliserons un serveur DHCP slave hébergeant également un service DNS slave.
Installation et configuration du service NTP
Si un failover est mis en place, pour la redondance du service DHCP, il est fondamental que les deux serveurs (master et slave DHCP) soient synchronisés au niveau de l’heure. Le cas échéant, leur communication sera interrompue si le décalage est trop important.
On peut, par exemple, synchroniser le serveur master avec une source externe de temps, et le serveur slave avec le master.
Installation du service NTP et de l’utilitaire ntpstat :
# aptitude install ntp ntpstat
Configuration du service NTP :
# nano /etc/ntp.conf
[...] server dns1.opensharing.priv server 127.127.0.1 fudge 127.127.0.1 stratum 10 [...] restrict 192.168.1.0 mask 255.255.255.0 nomodify notrap [...]
# timedatectl set-timezone Europe/Paris
# timedatectl set-ntp true
# systemctl enable ntp
# service ntp restart
# ntpq -p
remote refid st t when poll reach delay offset jitter
==============================================================================
*dhcp1.openshari LOCAL(0) 11 u 34 64 17 0.601 -111.08 80.346
# ntpstat
synchronised to NTP server (192.168.1.11) at stratum 12
time correct to within 954 ms
polling server every 64 s
Le service NTP est bien synchronisé avec le serveur dns1-test.opensharing.priv, qui a pour CNAME dns1.opensharing.priv et dhcp1.opensharing.priv, ce dernier étant synchronisé avec son heure locale.
Configuration réseau initiale
Serveur DHCP Slave | |
FQDN | dns2-test.opensharing.priv |
Adresse IP | 192.168.1.12 |
Réseau | 192.168.1.0/24 |
Passerelle | 192.168.1.1 |
dns-nameservers | 192.168.1.11 127.0.0.1 |
dns-search | opensharing.priv |
Contenu initial du fichier /etc/network/interfaces :
auto lo iface lo inet loopback allow-hotplug eth0 iface eth0 inet static address 192.168.1.12 netmask 255.255.255.0 network 192.168.1.0 broadcast 192.168.1.255 gateway 192.168.1.1 dns-search opensharing.priv dns-nameservers 192.168.1.11 127.0.0.1
Contenu initial du fichier /etc/hosts :
127.0.0.1 localhost.localdomain localhost 192.168.1.12 dns2-test.opensharing.priv dns2-test
Rmq : L’adresse 127.0.1.1 doit être retirée sur un serveur à IP fixe et remplacée par cette dernière, tel que l’exemple ci-dessus.
Contenu initial du fichier /etc/host.conf :
order hosts, bind multi on
Contenu initial du fichier /etc/resolv.conf :
# Dynamic resolv.conf(5) file for glibc resolver(3) generated by resolvconf(8) # DO NOT EDIT THIS FILE BY HAND -- YOUR CHANGES WILL BE OVERWRITTEN nameserver 192.168.1.11 nameserver 127.0.0.1 search opensharing.priv
Rmq :
Le fichier /etc/resolv.conf ne doit pas être édité dès lors que le paquet resolvconf a été installé.
Extrait des enregistrements de la zone DNS opensharing.priv sur le DNS slave (lui-même) :
# cat /var/cache/bind/db.opensharing.priv
[...] dns2-test IN A 192.168.1.12 dns2 IN CNAME dns2-test [...]
Réalisation
0. Mise à jour préalable du système et des paquets installés
# aptitude update # aptitude upgrade
1. Installation du serveur DHCP
# apt-get install isc-dhcp-server
L’installation du service ISC DHCP génère son fichier de configuration dhcpd.conf dans le répertoire /etc/dhcp/ :
# tree /etc/dhcp/ /etc/dhcp/ ├── dhclient.conf ├── dhclient-enter-hooks.d │ ├── debug │ └── resolvconf ├── dhclient-exit-hooks.d │ ├── debug │ ├── ntpdate │ └── rfc3442-classless-routes └── dhcpd.conf
Rmq : La commande tree nécessite l’installation du paquet tree.
2. Configuration du serveur DHCP
Fichier dhcpd.conf final modifié
include "/etc/bind/tsig.key"; authoritative; ddns-update-style standard; update-static-leases off; ignore client-updates; default-lease-time 600; max-lease-time 7200; log-facility local7; failover peer "opensharing-failover" { secondary; address 192.168.1.12; port 647; peer address 192.168.1.11; peer port 647; max-response-delay 30; max-unacked-updates 10; load balance max seconds 3; } subnet 192.168.1.0 netmask 255.255.255.0 { option subnet-mask 255.255.255.0; option routers 192.168.1.1; ddns-domainname "opensharing.priv"; ddns-rev-domainname "in-addr.arpa"; option domain-name "opensharing.priv"; option domain-name-servers dns1.opensharing.priv, dns2.opensharing.priv; pool { failover peer "opensharing-failover"; range 192.168.1.100 192.168.1.199; allow unknown-clients; } group { use-host-decl-names true; host printer1 { hardware ethernet 01:23:45:00:00:01; fixed-address 192.168.1.200; } host printer2 { hardware ethernet 01:23:45:00:00:01; fixed-address 192.168.1.201; } } } zone opensharing.priv { primary 192.168.1.11; key "tsig-key"; } zone 1.168.192.in-addr.arpa. { primary 192.168.1.11; key "tsig-key"; }
Fichier /etc/default/isc-dhcp-server modifié
INTERFACES="eth0"
Pour aller plus loin
Les étapes de la mise à jour dynamique du DNS sur le master
Scénario :
- Un PC, nommé xptest (en Workgroup) fait une requête DHCP en broadcast
- Son sous-réseau est composé de 2 serveurs DHCP :
- Un serveur DHCP et DNS master : dns1-test.opensharing.priv (192.168.1.11)
- Un serveur DHCP et DNS slave : dns2-test.opensharing.priv (192.168.1.12)
1. DORA : DHCPDISCOVER – DHCPOFFER – DHCPREQUEST – DHCPACK
1.1. Sur le master
Aug 15 21:05:54 dns1-test dhcpd: DHCPDISCOVER from 00:11:43:a2:d7:aa via eth0: load balance to peer opensharing-failover Aug 15 21:05:55 dns1-test dhcpd: DHCPREQUEST for 192.168.1.100 (192.168.1.12) from 00:11:43:a2:d7:aa via eth0: lease owned by peer
1.2. Sur le slave
Aug 15 21:05:54 dns2-test dhcpd: DHCPDISCOVER from 00:11:43:a2:d7:aa via eth0 Aug 15 21:05:55 dns2-test dhcpd: DHCPOFFER on 192.168.1.100 to 00:11:43:a2:d7:aa (xptest) via eth0 Aug 15 21:05:56 dns2-test dhcpd: DHCPREQUEST for 192.168.1.100 (192.168.1.12) from 00:11:43:a2:d7:aa (xptest) via eth0 Aug 15 21:05:56 dns2-test dhcpd: DHCPACK on 192.168.1.100 to 00:11:43:a2:d7:aa (xptest) via eth0
La requête DHCPDISCOVER est envoyée au 2 serveurs DHCP, le master la confie au load-balacing du failover qui tranche en faveur du slave.
Le slave gérera donc la suite de la requête en attribuant un bail au client xptest.
2. Mise à jour de la zone directe du DNS master
Le slave s’authentifie auprès du DNS master avec la clef TSIG tsig-key qu’ils partagent afin de lui communiquer les nouveaux enregistrements directs dont il dispose sur son nouveau bail.
2.1. Sur le master
Aug 15 21:05:55 dns1-test named[525]: client 192.168.1.12#16131/key tsig-key: view internal: signer "tsig-key" approved
Le master supprime d’éventuels enregistrements A et DHCID existants pour cet hôte dans la zone directe déclarée dans le fichier dhcpd.conf.
Puis il ajoute, dans la foulée et par requête du slave, les enregistrements A et DHCID relatifs à l’hôte xptest en utilisant les paramètres suivants du bail nouvellement créé sur le slave et synchronisé avec le master :
- ddns-fwd-name (concaténation du client-hostname fourni par le client et du ddns-domainname fourni par le serveur)
- ddns-dhcid
- lease (pour l’IP)
Aug 15 21:05:55 dns1-test named[525]: client 192.168.1.11#65141/key tsig-key: view internal: updating zone 'opensharing.priv/IN': deleting rrset at 'xptest.opensharing.priv' A Aug 15 21:05:55 dns1-test named[525]: client 192.168.1.12#16131/key tsig-key: view internal: updating zone 'opensharing.priv/IN': adding an RR at 'xptest.opensharing.priv' A Aug 15 21:05:55 dns1-test named[525]: client 192.168.1.11#65141/key tsig-key: view internal: updating zone 'opensharing.priv/IN': deleting rrset at 'xptest.opensharing.priv' DHCID Aug 15 21:05:55 dns1-test named[525]: client 192.168.1.12#16131/key tsig-key: view internal: updating zone 'opensharing.priv/IN': adding an RR at 'xptest.opensharing.priv' DHCID
Le service DHCP du slave signifie alors qu’il a bien transmis un nouvel enregistrement pour la zone directe.
2.2. Sur le slave
Aug 15 21:05:56 dns2-test dhcpd: Added new forward map from xptest.opensharing.priv to 192.168.1.100
3. Transfert de la zone directe du DNS master vers le slave
Deux nouveaux enregistrements ont été ajoutés à la zone directe sur le DNS master, ils doivent être transmis au DNS slave.
Pour cela, le master signifie une modification de la zone directe au slave en lui envoyant une notification du serial de son SOA tout en s’authentifiant auprès du slave avec la clef TSIG.
3.1. Sur le master
Aug 15 21:05:56 dns1-test named[525]: zone opensharing.priv/IN/internal: sending notifies (serial 2016081467)
Le slave initie alors un transfert de la zone directe.
3.2. Sur le slave
Aug 15 21:05:56 dns2-test named[540]: client 192.168.1.11#23612/key tsig-key: view internal: received notify for zone 'opensharing.priv': TSIG 'tsig-key'
Aug 15 21:05:56 dns2-test named[540]: zone opensharing.priv/IN/internal: Transfer started.
Aug 15 21:05:56 dns2-test named[540]: transfer of 'opensharing.priv/IN/internal' from 192.168.1.11#53: connected using 192.168.1.12#35818
Aug 15 21:05:56 dns2-test named[540]: zone opensharing.priv/IN/internal: transferred serial 2016081467: TSIG 'tsig-key'
Aug 15 21:05:56 dns2-test named[540]: transfer of 'opensharing.priv/IN/internal' from 192.168.1.11#53: Transfer completed: 1 messages, 6 records, 345 bytes, 0.311 secs (1109 bytes/sec)
3.3. Au même moment sur le master
Aug 15 21:05:56 dns1-test named[525]: client 192.168.1.12#35818/key tsig-key (opensharing.priv): view internal: transfer of 'opensharing.priv/IN': IXFR started: TSIG tsig-key
Aug 15 21:05:56 dns1-test named[525]: client 192.168.1.12#35818/key tsig-key (opensharing.priv): view internal: transfer of 'opensharing.priv/IN': IXFR ended
4. Mise à jour de la zone inverse du DNS master
Le slave s’authentifie auprès du DNS master avec la clef TSIG tsig-key qu’ils partagent afin de lui communiquer le nouvel enregistrement inverse dont il dispose sur son nouveau bail.
4.1. Sur le master
Aug 15 21:05:56 dns1-test named[525]: client 192.168.1.12#16131/key tsig-key: view internal: signer "tsig-key" approved
Le master supprime d’éventuels enregistrements PTR existants pour cet hôte dans la zone inverse déclarée dans le fichier dhcpd.conf.
Puis il ajoute, dans la foulée et par requête du slave, l’enregistrement PTR relatif à l’hôte xptest en utilisant les paramètres suivants du bail nouvellement créé sur le slave et synchronisé avec le master :
- ddns-rev-name (concaténation de l’IP inversée du client et du ddns-rev-domainname fourni par le serveur)
- lease (pour l’IP)
Aug 15 21:05:56 dns1-test named[525]: client 192.168.1.12#16131/key tsig-key: view internal: updating zone '1.168.192.in-addr.arpa/IN': deleting rrset at '100.1.168.192.in-addr.arpa' PTR Aug 15 21:05:56 dns1-test named[525]: client 192.168.1.12#16131/key tsig-key: view internal: updating zone '1.168.192.in-addr.arpa/IN': adding an RR at '100.1.168.192.in-addr.arpa' PTR
Le slave signifie alors qu’il a bien transmis un nouvel enregistrement pour la zone inverse.
4.2. Sur le slave
Aug 15 21:05:56 dns2-test dhcpd: Added reverse map from 100.1.168.192.in-addr.arpa to xptest.opensharing.priv
5. Transfert de la zone inverse du DNS master vers le slave
Un nouvel enregistrement a été ajouté à la zone inverse sur le DNS master, il doit être transmis au DNS slave.
Pour cela, le master signifie une modification de la zone inverse au slave en lui envoyant une notification du serial de son SOA tout en s’authentifiant auprès du slave avec la clef TSIG.
5.1. Sur le master
Aug 15 21:05:56 dns1-test named[525]: zone 1.168.192.in-addr.arpa/IN/internal: sending notifies (serial 2016081448)
Le slave initie alors un transfert de la zone inverse.
5.2. Sur slave
Aug 15 21:05:56 dns2-test named[540]: client 192.168.1.11#10899/key tsig-key: view internal: received notify for zone '1.168.192.in-addr.arpa': TSIG 'tsig-key'
Aug 15 21:05:56 dns2-test named[540]: zone 1.168.192.in-addr.arpa/IN/internal: Transfer started.
Aug 15 21:05:56 dns2-test named[540]: transfer of '1.168.192.in-addr.arpa/IN/internal' from 192.168.1.11#53: connected using 192.168.1.12#36029
Aug 15 21:05:57 dns2-test named[540]: zone 1.168.192.in-addr.arpa/IN/internal: transferred serial 2016081448: TSIG 'tsig-key'
Aug 15 21:05:57 dns2-test named[540]: transfer of '1.168.192.in-addr.arpa/IN/internal' from 192.168.1.11#53: Transfer completed: 1 messages, 5 records, 322 bytes, 0.151 secs (2132 bytes/sec)
5.3. Au même moment sur le master
Aug 15 21:05:56 dns1-test named[525]: client 192.168.1.12#36029/key tsig-key (1.168.192.in-addr.arpa): view internal: transfer of '1.168.192.in-addr.arpa/IN': IXFR started: TSIG tsig-key Aug 15 21:05:56 dns1-test named[525]: client 192.168.1.12#36029/key tsig-key (1.168.192.in-addr.arpa): view internal: transfer of '1.168.192.in-addr.arpa/IN': IXFR ended
Rmq : L’enregistrement de type DHCID (propre à la zone directe) correspond à des informations uniques propres au client envoyées par celui-ci, concaténées, puis hashées par un algorithme de type SHA256. Il a pour but d’éviter les doublons dans les enregistrements directs du DNS et ressemble à cela :
xptest.opensharing.priv. 240 IN DHCID AAEBXwtkUp+5xiKwiFAjBepXdr7D3zFaCOJ5cn2GydHDomo=
Le FQDN pointe sur une valeur en base 64 que l’on peut décoder avec Python :
>>> import base64 >>> base64.b64decode("AAEBXwtkUp+5xiKwiFAjBepXdr7D3zFaCOJ5cn2GydHDomo=") '\x00\x01\x01_\x0bdR\x9f\xb9\xc6"\xb0\x88P#\x05\xeaWv\xbe\xc3\xdf1Z\x08\xe2yr}\x86\xc9\xd1\xc3\xa2j'
Le résultat est une chaine en base 16 (hexadécimal).
Elle correspond à la chaine relative au paramètre ddns-dhcid généré pour le bail, mais en base 8 (octal) :
set ddns-dhcid = "\000\001\001_\013dR\237\271\306\"\260\210P#\005\352Wv\276\303\3371Z\010\342yr}\206\311\321\303\242j";
5.4. Pour résumer
Informations d’identification reçues et données au client
-> hashage (SHA256)
-> conversion base 8 (ddns-dhcid)
-> conversion base 16
-> conversion base 64 (enregistrement DNS DHCID)
Analyse du failover
Imaginons que le serveur DHCP slave présente une défaillance, voici les phases que nous observerons sur les 2 serveurs :
- Slave : Défaillance
Master : communications-interruptedAug 14 22:41:06 dns1-test dhcpd: failover peer opensharing-failover: I move from normal to communications-interrupted
- Slave : Reprise du service : recover (reçoit la mise à jour de la base de données des baux du master : synchronisation)
Aug 14 22:41:08 dns2-test dhcpd: failover peer opensharing-failover: I move from startup to recover Aug 14 22:41:08 dns2-test dhcpd: Sent update request all message to opensharing-failover Aug 14 22:41:23 dns2-test dhcpd: failover peer opensharing-failover: peer update completed
Master : partner-down (partenaire inopérationnel temporairement, le master devra assurer le service seul)
Aug 14 22:41:07 dns1-test dhcpd: failover peer opensharing-failover: I move from communications-interrupted to partner-down Aug 14 22:41:08 dns1-test dhcpd: Update request all from opensharing-failover: sending update Aug 14 22:41:23 dns1-test dhcpd: Sent update done message to opensharing-failover
- Slave : recover-wait (restera dans cet état le temps défini par le paramètre mclt : phase de basculement)
Aug 14 22:41:23 dns2-test dhcpd: failover peer opensharing-failover: I move from recover to recover-wait
Master : partner-down
- Slave : recover-done (phase très courte, annonce la fin de sa convalescence à son partenaire)
Aug 14 22:49:06 dns2-test dhcpd: failover peer opensharing-failover: I move from recover-wait to recover-done
Rmq : Ici, le mclt a été défini, pour les tests, à 8 min (480 sec)
Master : partner-down - Slave : normal
Aug 14 22:49:07 dns2-test dhcpd: failover peer opensharing-failover: I move from recover-done to normal Aug 14 22:49:07 dns2-test dhcpd: failover peer opensharing-failover: Both servers normal
Master : normal
Aug 14 22:49:07 dns1-test dhcpd: failover peer opensharing-failover: I move from partner-down to normal
Les phases seraient les mêmes si le master présentait une défaillance.
Ces différentes étapes sont reportées chronologiquement dans le fichier des baux : /var/lib/dhcp/dhcpd.leases
Rmq : Si un client fait une requête DHCP pour obtenir une IP, on observera sur le serveur défaillant pendant la phase de besculement :
Aug 14 20:13:14 dns2-test dhcpd: DHCPDISCOVER from 00:11:43:a2:d7:aa via eth0: not responding (recover wait)
L’importance de la synchronisation de l’heure dans le failover
Si les deux serveurs DHCP ne sont pas synchronisés temporellement, ils n’arriveront pas à joindre le failover et aucun ne pourra servir les clients DHCP :
Aug 17 01:19:59 dns2-test dhcpd: Failover CONNECT from opensharing-failover: time offset too large Aug 17 01:19:59 dns2-test dhcpd: failover: disconnect: time offset too large Aug 17 01:19:59 dns2-test dhcpd: failover: link startup timeout
Aug 17 01:16:58 dns1-test dhcpd: Failover CONNECT to opensharing-failover rejected: Connection rejected, time mismatch too great.
Ici, les deux serveurs DHCP possèdent 3 minutes de décalage, ce dernier étant trop important pour se connecter au failover, que ce soit le master ou le slave.
Et lorsque les deux serveurs se resynchronisent, la jonction au failover se fait :
Aug 17 01:20:14 dns1-test dhcpd: failover peer opensharing-failover: peer moves from communications-interrupted to normal Aug 17 01:20:14 dns1-test dhcpd: failover peer opensharing-failover: Both servers normal
Analyse du load-balancing
Le client fait une requête DHCP sur le failover (les 2 serveurs la reçoivent)
Sur le master :
Aug 15 11:41:20 dns1-test dhcpd: DHCPDISCOVER from 08:00:27:a8:cc:30 via eth0: load balance to peer opensharing-failover Aug 15 11:41:21 dns1-test dhcpd: DHCPREQUEST for 192.168.1.102 (192.168.1.12) from 08:00:27:a8:cc:30 via eth0: lease owned by peer
Sur le slave :
Aug 15 11:41:20 dns2-test dhcpd: DHCPDISCOVER from 08:00:27:a8:cc:30 via eth0 Aug 15 11:41:21 dns2-test dhcpd: DHCPOFFER on 192.168.1.102 to 08:00:27:a8:cc:30 (debianmysql) via eth0 Aug 15 11:41:21 dns2-test dhcpd: DHCPREQUEST for 192.168.1.102 (192.168.1.12) from 08:00:27:a8:cc:30 (debianmysql) via eth0 Aug 15 11:41:21 dns2-test dhcpd: DHCPACK on 192.168.1.102 to 08:00:27:a8:cc:30 (debianmysql) via eth0
On voit ici que c’est le slave qui a la charge de l’attribution de la configuration réseau du client.
Le failover détermine quel serveur gérera ce nouveau client. Lors de l’initialisation du failover, la plage d’IP a été scindée en 2 (split 128).
En consultant le fichier des baux, /var/lib/dhcp/dhcpd.leases, on remarque deux types de baux potentiels :
Les adresses free, affectables par le serveur master :
lease 192.168.1.161 { binding state free; } lease 192.168.1.162 { binding state free; }
Les adresses backup, affectables par le serveur slave :
lease 192.168.1.147 { starts epoch 1471262212; # Mon Aug 15 13:56:52 2016 tstp epoch 1471262212; # Mon Aug 15 13:56:52 2016 tsfp epoch 1471262212; # Mon Aug 15 13:56:52 2016 atsfp epoch 1471262212; # Mon Aug 15 13:56:52 2016 binding state backup; } lease 192.168.1.148 { starts epoch 1471262212; # Mon Aug 15 13:56:52 2016 tstp epoch 1471262212; # Mon Aug 15 13:56:52 2016 tsfp epoch 1471262212; # Mon Aug 15 13:56:52 2016 atsfp epoch 1471262212; # Mon Aug 15 13:56:52 2016 binding state backup; }
Ici, le failover a divisé le pool 192.168.1.100-192.168.1.199 en 2 :
- 192.168.1.100-192.168.1.149 : 50 adresses utilisables par le slave
- 192.168.1.150-192.168.1.199 : 50 adresses utilisables par le master
Ce que confirment les logs sur les deux serveurs :
Aug 15 12:05:45 dns1-test dhcpd: balancing pool b7cac390 192.168.1.0/24 total 100 free 50 backup 50 lts 0 max-own (+/-)10 Aug 15 12:05:45 dns1-test dhcpd: balanced pool b7cac390 192.168.1.0/24 total 100 free 50 backup 50 lts 0 max-misbal 15
Aug 15 12:05:14 dns2-test dhcpd: balancing pool b7bb2350 192.168.1.0/24 total 100 free 50 backup 50 lts 0 max-own (+/-)10 Aug 15 12:05:14 dns2-test dhcpd: balanced pool b7bb2350 192.168.1.0/24 total 100 free 50 backup 50 lts 0 max-misbal 15
Aller encore plus loin
Pour continuer à explorer la configuration de ISC DHCP, voir les articles suivants :
Annexes
PAPLxx : fait référence à un sujet développé dans la section Pour aller plus loin
Références
- dhcpd.conf(5) – Linux man page
- dhcp-options(5) – Linux man page
- dhcpd-eval(5) – Linux man page
- dhcpd.leases(5) – Linux man page
- IETF – RFC2131 – Dynamic Host Configuration Protocol
- Internet Systems Consortium – ISC DCHP Homepage
- RHEL 7 – Networking Guide – Chapter 10 DHCP Servers
- Zytrax – DDNS with DHCPv4
- NLUG – NTPQ Command
- O’Reilly TCP/IP Network Administration – D.3. The dhcpd.conf Configuration File
- Command Center – HOWTO Design a fault-tolerant DHCP + DNS solution
- IT-Connect – Redondance de serveurs DHCP sous Linux
- Wiki Debian – DDNS