====== dhcp(d) ====== ===== serveur ===== Installons : # apt-get install dhcp3-server Ajoutons l'interface qu'on va ecouter pour repondre au requete **dhcp** # vi /etc/default/dhcp Et avoir par exemple: # On what interfaces should the DHCP server (dhcpd) serve DHCP requests? # Separate multiple interfaces with spaces, e.g. "eth0 eth1". INTERFACES="eth0" Adaptons la configuration du **dhcpd**: # vi /etc/dhcp3/dhcpd.conf Et par exemple: option domain-name "microsoft.com"; option domain-name-servers 10.20.0.6, 212.27.33.1, 212.27.33.3; option subnet-mask 255.255.255.0; default-lease-time 86400; max-lease-time 172800; subnet 192.168.0.0 netmask 255.255.255.0 { range 192.168.0.1 192.168.0.50; default-lease-time 600; max-lease-time 7200; option subnet-mask 255.255.255.0; option broadcast-address 192.168.0.255; option routers 192.168.0.254; option domain-name-servers 212.27.39.2,212.27.32.5; option domain-name "microsoft.com"; } Et si on veut qu'une IP soit fixe pour une MAC: host kubulap { hardware ethernet 00:0b:cd:a7:0b:0c; fixed-address 192.168.0.200; default-lease-time 600; max-lease-time 7200; option subnet-mask 255.255.255.0; option broadcast-address 192.168.0.255; option routers 192.168.0.254; option domain-name-servers 212.27.39.2,212.27.32.5; } Relancer **dhcpd**: # /etc/init.d/dhcpd3 restart Voir ce qui ce passe: # tail -f /var/log/syslog La base des IP liberes et utilisé est dans: **/var/lib/dhcp3/dhcpd.leases** cd ==== status ==== Pour savoir l'etat des attributions, il faut regarder dans le fichier "dhcpd.leases"... Scripte en Perl pour aider a la lecture: http://dhcpstatus.sourceforge.net/ Suivre la procedure d'installation: # cd /usr/local/src # wget http://prdownloads.sourceforge.net/dhcpstatus/dhcpstatus_0.60.tar.gz # tar xvzf dhcpstatus_0.60.tar.gz # mkdir /usr/local/dhcpstatus # cd /usr/local/dhcpstatus # tar -xvf /usr/local/src/dhcpstatus_0.60/libraries.tar Et la doc dit: So, there should now be a directory: /usr/local/dhcpstatus with library modules: /usr/local/dhcpstatus/dhcpstatus/*.pm and a .ini file: /usr/local/dhcpstatus/dhcpstatus.ini Ok. Donc, on adapte **''dhcpstatus.ini''** pour avoir (a adapté selon le cas) : title=DHCP Subnet Information conf_file=/etc/dhcp/dhcpd.conf leases_file=/var/lib/dhcp/dhcpd.leases show_whole_subnet=0 screen_width=80 Et enfin: # ln -s /usr/local/src/dhcpstatus_0.60/scripts/dhcpstatus /usr/local/bin Et enfin: $ dhcpstatus bash: /usr/local/bin/dhcpstatus : /usr/local/bin/perl : mauvais interpréteur: Aucun fichier ou dossier de ce type Ah non ! editer le script "dhcpstatus" et changer pour avoir en 1er ligne: #!/usr/bin/perl -w Et voila: $ dhcpstatus ===== dhcp relay ===== Lien: http://www.linux-france.org/prj/edu/archinet/systeme/ch29s03.html Le but: servir du dhcp a un reseau dont on ne peut recevoir la couche 2 ... enfin, les adresses MAC. Etat du reseau: Reseau "underworld.local" <==> eth1 :: PC/Routeur :: eth0 <==> le grand reseau local <==> server-dhcp 10.22.0.0/24 10.22.0.1 | 192.168.0.53 192.168.0.2 gateway:10.22.0.1 | gateway: 192.168.0.254 Evidement, le "PC/Routeur" contient quelques regles IPTABLES pour permettre au reseau "underworld.local" de voyager sur le Net: ca ne sera pas le sujet ici. ==== Package ==== # aptitude update # aptitude install dhcp3-relay ==== dhcp relay ==== L'installation est interactive, et au final, on peut avoir comme config: # cat /etc/default/dhcp3-relay | grep -v "^#" | grep -v "^\s*$" SERVERS="192.168.0.2" INTERFACES="eth0 eth1" OPTIONS="" On peut aussi demarrer le "dhcp-relay" a partir du shell: # dhcrelay3 -d -i eth1 -i eth0 192.168.0.2 ==== dhcp server ==== Sur le "veritable" serveur dhcp, un client n'aura toujours pas d'IP puisque les logs disent: ... dhcpd: DHCPDISCOVER from aa:bb:cc:dd:ee:ff via 10.22.0.1: unknown network segment Normal. Declarons le segment (exemple): subnet 10.22.0.0 netmask 255.255.255.0 { server-identifier 10.22.0.1; option domain-name-servers 192.168.0.2, 212.27.40.240, 212.27.40.241; option routers 10.22.0.1; option broadcast-address 10.22.0.255; option domain-name "underworld.local"; range 10.22.0.128 10.22.0.254; default-lease-time 10800; max-lease-time 43200; } Ajoutons la route: # route add -net 10.22.0.1 netmask 255.255.255.255 gw 192.168.0.53 Où "192.168.0.53" a la machine qui fait relay. ==== test ==== Sur le client final: # dhclient Et voila. ==== Le problème ==== Et ça, c'est du poulet ? : http://www.jusouschi.org/?do=howtos/dhcp J'en vois au moins 1, et un beau: J'aurai souhaité que le "dhcp-relay" n'ecoute qu'une interface pour **ses** clients, et recherche les reponses du "dhcp-server" sur une autre...\\ **Ce n'est pas possible !!!!** \\ Le "dhcp-relay" doit ecouter toutes les interfaces pour fonctionner, et donc, il va aussi repondre a des clients qui sont sur un autre reseau !!! Arg! === la solution === Utiliser **"dhcp-helper"** ==== dhcp-helper ==== **"dhcp3-relay"** etant mal conçu, j'essaye "dhcp-helper".\\ (Aprés avoir virer "dhcp3-relay") # aptitude update # aptitude install dhcp-helper Et puis editer le fichier **''/etc/default/dhcp-helper''** afin d'avoir: #DHCPHELPER_OPTS="-b eth0" DHCPHELPER_OPTS="-s 192.168.0.2 -i eth1" Et ca marche ! ===== DHCP et DNS ===== Liens: *http://www.randombugs.com/linux/linux-isc-dhcp-server-dynamic-dns-updates-debian-ubuntu.html *http://www.semicomplete.com/articles/dynamic-dns-with-dhcp/ *http://www.debianadmin.com/howto-setup-dhcp-server-and-dynamic-dns-with-bind-in-debian.html *http://www.ops.ietf.org/dns/dynupd/secure-ddns-howto.html *http://www.mail-archive.com/debian-user-french@lists.debian.org/msg131533.html *http://www.ops.ietf.org/dns/dynupd/secure-ddns-howto.html Le problème: les clients DHCP doivent automatiquement être enregistré dans le DNS... comment faire ? On va creer un zone "local.tjaouen.fr" ... Ce qui pose 2 problèmes: *c'est un sous-zone local ("local..."). *le ".fr" est dans la zone "public". C'est ainsi a cause d'un vieux problème d'installation de mon domaine Windows LOCAL avec pour domain "thierry-jaouen.fr". ==== secret ==== le DHCP et le DNS doivent partagé une clé secrete pour communiquer. # cd /etc/bind # mkdir keys # chmod o-rx keys # cd keys # dnssec-keygen -a hmac-md5 -b 128 -n USER dhcpupdate-local-tjaouen-fr Kdhcpupdate-local-tjaouen-fr.+xxx+xxxxx | :!: ''-n USER'' ou ''-n HOST'' ? | On a donc 2 fichiers: -rw------- 1 root bind 92 déc 36 12:03 Kdhcpupdate-local-tjaouen-fr.+xxx+xxxxx.private -rw------- 1 root bind 69 déc 36 12:03 Kdhcpupdate-local-tjaouen-fr.+xxx+xxxxx.key Le seul fichier qui nous interesse est le ".key" , qui contient: dhcpupdate-local-tjaouen-fr. IN KEY 0 3 xxx N8HxxxxxxxxxxxxA== C'est la partie "N8HxxxxxxxxxxxA==" qu'on va utiliser par la suite: les fichiers ".private" et ".key" ne nous serons pas utile pour la suite! ==== named.conf.local ==== On prépare l'usage de la clé : key dhcpupdate-local-thierry-jaouen-fr { algorithm hmac-md5; secret "N8HxxxxxxxxxxxxA=="; }; On créé les zones "dynamique": zone "local.thierry-jaouen.fr" { type master; file "/etc/bind/UPDATE-LOCAL/db.local.thierry-jaouen.fr"; allow-update { key dhcpupdate-local-thierry-jaouen-fr; }; }; zone "8.168.192.in-addr.arpa" { type master; file "/etc/bind/UPDATE-LOCAL/db.192.168.8"; allow-update { key dhcpupdate-local-thierry-jaouen-fr; }; }; Pour les zones ci-dessus, on ajoutera, bien sur le "allow-query" qui va bien. Mais aussi, si, il y a des problèmes avec des noms de machine qui contiennent des "_" : check-names ignore; ==== Zones ==== Il faut aussi créer les fichiers "zone", qu'on va mettre dans notre "LOCAL": Le fichier **''..../UPDATE-LOCAL/db.local.thierry-jaouen.fr''** : ; ; zone local.thierry-jaouen.fr ; $TTL 3600 @ IN SOA ns.thierry-jaouen.fr. root.thierry-jaouen.fr. ( 2010122600 ; serial number 6h ; refresh 1h ; retry 1w ; expire 1h ; minimum TTL ) ; ---------------------------------------------------------------- @ NS ns.thierry-jaouen.local. ; ---------------------------------------------------------------- ; EOF le fichier **''..../LOCAL/db.192.168.8''** : ; ; reverse ; $TTL 3600 @ IN SOA ns.thierry-jaouen.fr. root.thierry-jaouen.fr. ( 2010122600 ; serial number 6h ; refresh 1h ; retry 2w ; expire 1h ; minimum TTL ) ; ---------------------------------------------------------------- @ NS ns.thierry-jaouen.local. ; ---------------------------------------------------------------- ; EOF Sans oublier de mettre les *bons droits* : # chown bind: /etc/bind/UPDATE-LOCAL/db.local.thierry-jaouen.fr # chown bind: /etc/bind/UPDATE-LOCAL/db.192.168.8 # chmod g+ws /etc/bind/UPDATE-LOCAL # chown root:bind /etc/bind/UPDATE-LOCAL Donc: "bind" peut a la fois modifier "db.local.thierry-jaouen.fr" et "db.192.168.8", ainsi que créer des nouveaux fichiers... C'est fini pour "bind" aprés ça: # rndc reload (ou pire: ''/etc/init.d/bind reload'' ) ==== dhcpd.conf ==== Configurer le dhcp serveur. Dans la partie "global": ddns-update-style interim; #update-static-leases on; update-static-leases off; update-conflict-detection false; ignore client-updates; #ddns-updates on; option domain-name "thierry-jaouen.fr"; Dans la section qui fournit les IP/range: (A adapter) subnet 192.168.8.0 netmask 255.255.255.0 { pool { allow members of "dyn-titi"; option domain-name "thierry-jaouen.fr"; option domain-name-servers 8.8.8.8, 8.8.4.4; option routers 192.168.8.1; ddns-domainname "local.thierry-jaouen.fr"; allow unknown-clients; range 192.168.8.192 192.168.8.223; } key dhcpupdate-local-thierry-jaouen-fr { algorithm hmac-md5; secret N8HxxxxxxxxxxxxA==; }; zone local.thierry-jaouen.fr. { primary 127.0.0.1; # DNS serveur key dhcpupdate-local-thierry-jaouen-fr; } zone 8.168.192.in-addr.arpa. { primary 127.0.0.1; key dhcpupdate-local-thierry-jaouen-fr; } *"primary" est l'adresse du DNS. *"secret" sans "" ==== test ==== Ensuite, lorsqu'un windows va recuperer une IP, le dhcp va essayer d'enregistrer son nom sous la forme: .local.thierry-jaouen.fr Ainsi que son IP en reverse. On a alors le répertoire "LOCAL" avec de nouveaux fichiers comme: db.local.thierry-jaouen.fr.jnl db.192.168.8.jnl ==== Mise a jour de SubZone ==== Je vais maintenant me placer dans un cas plus courant. Une classe d'IP est trés souvent diviser en 2 parties: -des IP fixes -des IP dynamiques Pour notre cas: *ensemble du reseau local 192.168.8.0/24 *Ip dynamique dans 192.168.8.192/27 Donc, IP dynamique de 192.168.8.192 a 192.168.8.223 . Il n'est pas nécessaire que la plage d'IP dynamique respecte le format "a.b.c.d/X" : mais ca peut aider pour les "delegation de zone". === named.conf.local === Dans "named.conf.local" (ou équivalent), on créé les zones qui vont mise à jour: zone "dyn.thierry-jaouen.local" { type master; file "/etc/bind/UPDATE-LOCAL/db.dyn.thierry-jaouen.local"; allow-update { key dhcpupdate-local-thierry-jaouen-fr; }; check-names ignore; allow-query { mylan; }; }; zone "8.168.192.dyn-rev" { type master; file "/etc/bind/UPDATE-LOCAL/db.192.168.8.dyn-rev"; allow-update { key dhcpupdate-local-thierry-jaouen-fr; }; check-names ignore; allow-query { mylan; }; }; Pour la zone "reverse" on remplace le classique "in-addr.arpa" par autre chose, soit: "dyn-rev". | :!: Pour que la zone puisse être créé sous Windows, ajouter toujours "in-addr.arpa" a la fin.\\ Exemple: ''dyn-rev.in-addr.arpa'' | Il n'est pas nécessaire de faire un truc comme cela: **''zone "192/27.8.168.192.in-addr.arpa" ... ''** ... simplement parce que la conf du serveur dhcp (voir plus loin) ne pourra exprimer la sous-zone de la sorte. (sauf erreur de ma part !) === Fichiers Zones === Créer les fichier "db.dyn.thierry-jaouen.local" et "db.192.168.8.dyn-rev" comme vu plus haut. Pour mémoire: # cd /etc/bind # mkdir UPDATE-LOCAL # chmod g+w UPDATE-LOCAL Le fichier **''/etc/bind/UPDATE-LOCAL/db.dyn.thierry-jaouen.local''** : $TTL 3600 ; 1 hour @ IN SOA ns.thierry-jaouen.local. root.thierry-jaouen.local. ( 2011022500 ; serial 21600 ; refresh (6 hours) 3600 ; retry (1 hour) 604800 ; expire (1 week) 3600 ; minimum (1 hour) ) @ NS ns.thierry-jaouen.local. Le fichier **''/etc/bind/UPDATE-LOCAL/db.192.168.8.dyn-rev''** : $TTL 3600 ; 1 hour @ IN SOA ns.thierry-jaouen.local. root.thierry-jaouen.local. ( 2011022500 ; serial 21600 ; refresh (6 hours) 3600 ; retry (1 hour) 604800 ; expire (1 week) 3600 ; minimum (1 hour) ) @ NS ns.thierry-jaouen.local. === dhcpd.conf === Comme vu plus haut, ou presque: subnet 192.168.8.0 netmask 255.255.255.0 { pool { allow members of "dyn-titi"; #option domain-name "local.thierry-jaouen.local"; option domain-name-servers 8.8.8.8, 8.8.4.4; option routers 192.168.8.1; ddns-domainname "dyn.thierry-jaouen.local"; ddns-rev-domainname "dyn-rev"; allow unknown-clients; range 192.168.8.192 192.168.8.223; } key dhcpupdate-local-thierry-jaouen-fr { algorithm hmac-md5; secret N8HxxxxxxxxxxxxA==; }; zone dyn.thierry-jaouen.local. { primary 127.0.0.1; key dhcpupdate-local-thierry-jaouen-fr; } zone 6.168.192.dyn-rev. { primary 127.0.0.1; key dhcpupdate-local-thierry-jaouen-fr; } C'est **''ddns-domainname''** et **''ddns-rev-domainname''** qui vont correctement definir les zones a modifier dans "bind". | :!: A ce stade, la mise a jour fonctionne : mais pas le "reverse" de la resolution DNS | === resolution inverse === Retour dans la configuration de "bind", parce que la resolution inverse des IP dynamiques ne fonctionne pas encore ! Il faut ajouter dans le fichier "reverse" de la classe "192.168.8" , ceci: ; ------------- ; 192.168.6.192 .. 223 ; DYNAMIQUE IP ; --------------------------------------------------------------- $GENERATE 192-223 $ CNAME $.8.168.192.dyn-rev. ; --------------------------------------------------------------- Ce qui créé (virtuellement) des lignes comme cela: 192 CNAME 192.8.168.192.dyn-rev. 193 CNAME 193.8.168.192.dyn-rev. ... etc ... 223 CNAME 223.8.168.192.dyn-rev. Ce qui va forcer la resolution inverse dans la zone qu'on a précédement créée. ===== nsupdate ===== Liens: *http://docstore.mik.ua/orelly/networking_2ndEd/dns/ch10_02.htm *http://www.semicomplete.com/articles/dynamic-dns-with-dhcp/ On peut faire les mises a jour grâce à : **''nsupdate''** ==== usages en pratique ==== Exemple: $ nsupdate > update add leak.thierry-jaouen.fr. 3600 A 123.123.123.123 > update failed: REFUSED Mais pour ce faire, **''nsupdate''** va déterminer le maitre et lui soumettre la mise à jour. | :!: Bien sur, ça ne peut fonctionner que si la configuration de la zone autorise la mise à jour ! | Pour faire la mise à jour localement, si on est déjà sur le serveur maitre: $ nsupdate > server 127.0.0.1 > update add leak.thierry-jaouen.fr. 3600 A 123.123.123.123 > update failed: REFUSED Mais là encore: ... named[599]: client 127.0.0.1#14264: update 'thierry-jaouen.fr/IN' denied A suivre ... Mais même en autorisant ce genre de mise à jour en ajoutant: ... allow-update { 127.0.0.1; }; ... On a une erreur de d'ecriture, normale : ... named[599]: /etc/bind/MASTER/db.thierry-jaouen.fr.jnl: create: permission denied | :!: problème de droits corrigés, tout les utilisateurs qui ont localement accès a nsupdate pourront mettre a jour des entrées !!!! | On va créer une sous-zone dans laquelle on pourra faire nos mises à jour. | :!: les fichiers "*.jnl" sont polluant... separer les zones statiques des zones dynamiques! | ==== installation ==== Donc: - mise en place d'une sous-zone sacrifiés pour être dynamique - test - sécuriser Donc, on a : * une zone "thierry-jaouen.fr" * un DNS en "ns.thierry-jaouen.fr" On va créer une sous-zone: * leak.thierry-jaouen.fr. C'est dans cette sous-zone qu'on pourra ajouter des entrées DNS via "nsupdate". === sous-zone ==== Modifier la zone "thierry-jaouen.fr" en ajoutant la sous-zone : ; ----------------------------- leak IN A leak NS leak "" est l'IP de notre DNS ( donc, la même que **''ns.thierry-jaouen.fr''** ! ) Et aussi: test CNAME test.leak.thierry-jaouen.fr. Ainsi, on pourra utiliser le nom "test.thierry-jaouen.fr." comme alias vers le nom dynamique. Maintenant la sous-zone. Si nécessaire, préparer un nouveau répertoire: # cd /etc/bind # mkdir UPDATE-MASTER # chmod g+w UPDATE-MASTER Créer le nouveau fichier de zone: # cd UPDATE-MASTER # touch db.leak.thierry-jaouen.fr # chown bind: db.leak.thierry-jaouen.fr Car le fichier doit être "writable" pour bind. Son petit frère "db.leak.thierry-jaouen.fr.jnl" sera créé ultérieurement et automatiquement par **''bind''**. Editer le contenu de db.leak.thierry-jaouen.fr $TTL 3600 @ IN SOA thierry-jaouen.fr. root.thierry-jaouen.fr. ( 2012041800 ; serial number 24h ; refresh 1h ; retry 2w ; expire 1h ; minimum TTL ) ; ---------------------------------------------------------- NS leak.thierry-jaouen.fr. A ; ---------------------------------------------------------- test A 1.2.3.4 ; ------------ ; EOF Remplacer '''' par l'IP du père de la zone. (glue) Et enfin, dans la conf de **''named.conf.local''** ajouter la sous-zone: zone "leak.thierry-jaouen.fr" { type master; file "/etc/bind/UPDATE-MASTER/db.leak.thierry-jaouen.fr"; allow-query { any; }; # mise a jour via nsupdate ... NON SECURISE ! allow-update { 127.0.0.1; }; }; Activer: # rndc reload Tester en l'etat: $ host test.leak.thierry-jaouen.fr test.leak.thierry-jaouen.fr has address 1.2.3.4 Et ça marche aussi avec : **''test.thierry-jaouen.fr''** , grâce a l'alias. === tester === La mise a jour devrait maintenant fonctionner comme cela: # nsupdate > server 127.0.0.1 > update delete test.leak.thierry-jaouen.fr. A > update add test.leak.thierry-jaouen.fr. 3600 A 123.123.123.123 > > quit Et voila. Un fichier "''.jnl''" est apparu: Il faudra vivre avec :-) Dorénavant, la zone dynamique sera mise à jour dans son coin, dans la sous-zone "leak.thierry-jaouen.fr.". Pour les autres zones "statiques", on pourra continué d'éditer les fichiers avec son éditeur favori. === sécurité === Si nécessaire: # cd /etc/bind # mkdir keys # chown root:bind keys # chmod o-rwx g-r keys Générer la clé: # cd keys # dnssec-keygen -a HMAC-MD5 -b 128 -n HOST leak.thierry-jaouen.fr. Kleak.thierry-jaouen.fr.+157+39541 Créer un fichier de conf, dans **''/etc/bind/keys''** , par exemple: ''leak.thierry-jaouen.fr.conf'' : key "leak.thierry-jaouen.fr." { algorithm hmac-md5; secret ""; }; **''''** est a extraire de la ligne "Key" dans le fichier ".private" créé. Puis dans **''named.conf.local'' ** : ... include "/etc/bind/keys/leak.thierry-jaouen.fr.conf"; ... Et dans la déclaration de la zone "leak.thierry-jaouen.fr" , remplacer la ligne "allow-update" par: ... allow-update { key "leak.thierry-jaouen.fr."; }; ... Activer: # rndc reload Maintenant, si on test sans clé est rejeté: ... named[599]: client 127.0.0.1#1470: update 'leak.thierry-jaouen.fr/IN' denied Il faut préciser la clé ainsi, et procéder: # nsupdate -k Kleak.thierry-jaouen.fr.+157+39541.key > server 127.0.0.1 > update add toto.leak.thierry-jaouen.fr. 600 A 1.2.3.4 > send Et voila. A ce stade, sauf problème de configuration réseau, on n'a plus besoin de préciser où est le serveur.\\ La resolution DNS fait sont travail. Exemple: $ echo -n -e "update delete toto.leak.thierry-jaouen.fr. A\nsend\n" | nsupdate -k Kleak.thierry-jaouen.fr.+157+39541.key === Tips === == dump == Pour avoir un "dump" des evolutions de cette zone dynamique, on peut utiliser: # rndc dumpdb -zones == update == FIXME : c'est sur ? Par la suite, tout les enregistrements de la zone devront être fait via "nsupdate". Je n'ai pas compris s'il etait possible (et normal) d'éditer les fichiers a la main... (je ne parle pas du ".jnl" )