Close search
Hoa

Hack book de Hoa\Dns

Le DNS, ou Domain Name System, est un système permettant de traduire des noms de domaines en adresses IP. Les noms sont classifiés en plusieurs types selon les services. Hoa\Dns permet de résoudre des noms de domaines en fonction de leurs types.

Table des matières

  1. Introduction
  2. Résoudre ses propres noms de domaines
    1. Spécifier un serveur de résolution
      1. Sous Mac OS X
      2. Sous Linux
    2. Créer son serveur de résolution
  3. Test
  4. En ligne de commande
  5. Conclusion

Introduction

Toutes les machines connectées à un réseau portent une adresse IP (pour Internet Protocol). Il existe plusieurs versions de ce protocole : la version IPv4, standardisée à l'origine dans la RFC791, et la version IPv6, standardisée à l'origine dans la RFC2460. Ces adresses sont numériques et il n'est pas toujours évident de toutes les retenir. C'est pourquoi le DNS permet d'associer des noms à ces adresses. Nous parlons de noms de domaines, et de traduction, de résolution ou encore d'association.

Ce système de noms est hiérarchique et à la forme d'un arbre. Sous la racine de cette arbre, nous trouvons les domaines de premier niveau, aussi appelés TLD pour Top Level Domain ; par exemple : net, org, com etc. En dessous, nous trouvons d'autres domaines, comme hoa-project, wikipedia, php etc. Et encore en dessous, nous trouvons d'autres domaines, comme git pour hoa-project. Nous disons que le domaine hoa-project.net est un sous-domaine de net, tout comme git.hoa-project.net est un sous-domaine de hoa-project.net : la notion de hiérarchie est bien présente.

Mais ce système de noms est également distribué. Quand nous cherchons à résoudre un nom de domaine, nous commençons par trouver le ou les hôtes capables de résoudre son TLD, puis son sous-domaine et ainsi de suite. Chaque machine comporte un programme qui s'appelle un résolveur local de noms de domaines, capable de trouver des hôtes appropriés pour résoudre les noms de domaine. Nous pouvons modifier ces résolveurs pour utiliser nos propres serveurs de résolution. Hoa\Dns permet de créer un tel serveur. Si aucun serveur n'est spécifié, le résolveur local va interroger des services tiers : la notion de distribué est bien présente.

De plus, les noms de domaines sont classifiés selon des types, comme :

La liste complète des types d'enregistrement est maintenue par l'IANA, qui est l'organisme responsable de la gestion de l'espace d'adressage IP et autres protocoles. L'ensemble du protocole DNS est spécifié dans la RFC6195.

Grâce au nom de domaine et à son type, le résolveur pourra trouver l'adresse IP correspondante, ou sinon il cherchera un autre résolveur. Une fois l'adresse IP trouvée, les requêtes pourront être acheminées correctement.

Enfin, le protocole DNS fonctionne en UDP ou TCP sur le port 53, respectivement selon la RFC768 et RFC793.

Résoudre ses propres noms de domaines

Notre objectif va être de résoudre des noms de domaines de la forme *.hoa. Pour cela nous allons commencer par modifier notre résolveur local pour lui ajouter un hôte de résolution que nous ferons avec Hoa\Dns.

Spécifier un serveur de résolution

Il existe plusieurs programmes de résolution selon les systèmes. Notre objectif est de spécifier un serveur de résolution pour les domaines *.hoa. Notre serveur écoutera le port 57005 (i.e. 0xDEAD, pour ne pas devoir exécuter notre serveur avec les droits root) sur l'adresse 127.0.0.1.

Sous Mac OS X

Sous Mac OS X, il suffit de créer un fichier /etc/resolver/tld (attention à avoir les droits root, et le dossier /etc/resolver n'existe pas toujours, il ne faut pas hésiter à le créer). Ainsi, nous allons éditer le fichier /etc/resolver/hoa :

nameserver 127.0.0.1
port 57005

Il ne faut pas hésiter à attendre quelques secondes que le cache du serveur local s'invalide avant de passer à la suite.

Sous Linux

Sous Linux, nous allons utiliser DNSMasq, très souvent installé par défaut. Ensuite, nous allons modifier le fichier /etc/dnsmasq.conf pour lui dire de déléguer la résolution des domaines *.hoa vers notre propre serveur :

server=/hoa/127.0.0.1#57005

Il ne faut pas oublier de redémarrer DNSMasq :

$ sudo /etc/init.d/dnsmasq restart
 * Restarting DNS forwarder and DHCP server dnsmasq                         [OK]

Créer son serveur de résolution

Nous allons créer un serveur qui écoute l'adresse 127.0.0.1:57005 et en UDP. Ce serveur sera donné à Hoa\Dns\Resolver, et le tout sera dans le fichier Resolver.php :

$dns = new Hoa\Dns\Resolver(
    new Hoa\Socket\Server('udp://127.0.0.1:57005')
);

Hoa\Dns\Resolver émet un seul évènement : query, et envoie en donnée un tableau contenant domain (par exemple foo.bar.baz.tld), type (par exemple aaaa) et class (par exemple in). Nous allons associer à tous les domaines *.hoa l'adresse IP 127.0.0.1, nous n'allons pas considérer les sous-domaines de hoa dans le cadre de cet exercice.

$dns->on('query', function (Hoa\Event\Bucket $bucket) {
    $data = $bucket->getData();

    echo
        'Resolving domain ', $data['domain'],
        ' of type ', $data['type'], "\n";

    return '127.0.0.1';
});
$dns->run();

C'est aussi simple que ça ! Notons que nous n'avons pas tenu compte du type du domaine (qui devrait être A ou AAAA).

Test

Pour tester et s'amuser, nous allons créer un fichier /tmp/index.html contenant :

<body>
  yeah \o/
</body>

Pour atteindre ce fichier, nous allons démarrer un serveur HTTP, par exemple Bhoa, sur l'adresse 127.0.0.1:8888. Si ce serveur reçoit une requête depuis un domaine *.hoa c'est que notre serveur de résolution a fonctionné. Le fichier /tmp/index.html n'est présent que pour avoir un exemple complet. Démarrons donc Bhoa :

$ hoa http:bhoa --root /tmp --listen 127.0.0.1:8888

Nous démarrons aussi notre serveur de résolution :

$ php Resolver.php

Enfin, nous pouvons tester l'ensemble, par exemple avec cURL :

$ curl foo.hoa:8888 --verbose
* About to connect() to foo.hoa port 8888 (#0)
*   Trying 127.0.0.1... connected
* Connected to foo.hoa (127.0.0.1) port 8888 (#0)
> GET / HTTP/1.1
> User-Agent: curl/a.b.c (…) libcurl/d.e.f
> OpenSSL/g.h.i zlib/j.k.l
> Host: foo.hoa:8888
> Accept: */*
>
< HTTP/1.1 200 OK
< Date: …
< Server: Hoa+Bhoa/x.y
< Content-Type: text/html
< Content-Length: 8
<
yeah \o/
* Connection #0 to host foo.hoa left intact
* Closing connection #0

Nous voyons que foo.hoa est bien résolu en 127.0.0.1. La requête foo.hoa:8888 est capturée par notre serveur HTTP qui va nous répondre le contenu de /tmp/index.html.

En ligne de commande

Hoa\Dns propose la commande dns:server à partir du script hoa. Cette commande permet de démarrer rapidement un serveur de résolution et de rediriger certains domaines vers des IP. Le filtrage se fait à l'aide d'expressions régulières (voir les PCRE). Ainsi :

$ hoa dns:resolve 'foo.*' to 1.2.3.4 '.*\.bar\..*' to 5.6.7.8
Server is up, on udp://127.0.0.1:57005!

▋

Ainsi, tous les noms commençant par foo seront résolus vers 1.2.3.4 et ceux contenant .bar. seront résolus vers 5.6.7.8. La syntaxe est très simple : regex to ip.

Cette commande est très simple et peut s'avérer utile lors de tests rapides.

Conclusion

La bibliothèque Hoa\Dns permet de créer un serveur de résolution de noms de domaines. Sa facilité d'utilisation permet par exemple de créer rapidement des environnements de développement (avec des domaines *.dev par exemple) ou de mettre en place des services (en filtrant les types) sur des réseaux locaux ou plus larges.

Une erreur ou une suggestion sur la documentation ? Les contributions sont ouvertes !

Comments

menu