Catch-all DNS, VirtualHost et on fait mumuse avec les noms de sous-domaines

Salut lecteur,

Un bail que je n’ai rien écrit sur ce blog, la faute à un petit projet perso qui me prend un peu de temps chez moi, semble-t-il.

L’idée

Ceci dit, je voulais laisser une trace de cette manip’ qui consiste à autoriser n’importe quel nom de sous-domaine d’un domaine que vous possédez, exemple le fameux « mon_domaine.com » en ayant la possibilité d’envoyer vers un site ou un autre (au sens, un VirtualHost/DocumentRoot ou un autre) suivant le nom de sous-domaine appelé, la liste de ces sous-domaines étant potentiellement illimitée.

Bon, OK, pour la formulation, c’est pas forcément limpide. Un exemple concret : mon_domaine.com est une société qui propose un service web personnalisé pour ses clients. Le gérant de la chose décide de mettre en place les sous-domaines suivants :

  • www.mon_domaine.com
  • demo.mon_domaine.com ; même mieux : une liste de plusieurs instances de démo : demo1, demo2 etc
  • une série infinie de clientXXX.mon_domaine.com, exemples : http://client.mon_domaine.com, http://autreclient.mon_domaine.com

On voudrait que le « www » renvoie vers le site « commerçant », que les « demoX » renvoient vers le service en mode démo (chacun étant une instance différente, une base de données différente, par exemple) et que chaque « clientXXX » pointe vers le vrai outil, dont le code est commun pour tous les clients, là aussi avec une peut-être une base de donnée différente par client.
Pourquoi ne pas juste passer un paramètre dans l’URL pour indiquer le client ? car dans mon cas, je préférais faire des sous-domaines différents, ça enlève un tas d’épines du pied en ce qui concerne la gestion des sessions, gestion qui est liée au nom complet du domaine, pas à ce qu’il y a après le « .com », comme un http://….com/?client=xxx

On a toujours la possibilité de faire n’importe quelle crassouillerie pour avoir un script d’index[.php] qui dirige vers tel ou tel code/outil suivant l’URL appelée. Pourquoi pas. Mais lorsque l’un des outils est par exemple un outil dont on ne veut pas modifier l’index[.php], ça peut poser problème. Exemple, le « www » est un wordpress, le reste un outil maison. Je ne veux pas avoir à jouer avec le htaccess du WordPress, ce genre de choses. Bref, je scinde les mondes avant et je limite les risques de passage de l’un à l’autre.

Bon, ça y est ? le contexte est clair ?
Voici la solution que je trouve la plus élégante.

Côté DNS : catch-all

Si le gérant de votre nom de domaine le permet, créez d’abord un enregistrement DNS type A ou CNAME nommé « * » et pointant vers votre serveur. Exemple : « *.mon_domaine.com CNAME mon_domaine.com« .
Tous ne le permettent sûrement pas. Je sais au moins que OVH le tolère, il suffit de mettre « * » comme nom de sous-domaine.
Ensuite, on peut tester avec la commande « host/nslookup nimportequoi.mon_domaine.com« .

Côté Apache : identification du sous-domaine demandé

Avec la manip’ DNS, on est sûr que nimportequoi.mon_domaine.com renvoie bien vers le serveur. Reste à trier au niveau Apache (plutôt qu’au niveau code derrière, comme j’ai expliqué plus haut).
Déjà pour être sûr que ça marche, une conf simpliste consiste à créer un unique VirtualHost comme ceci :

        ServerName mon_domaine.com
        ServerAlias *.mon_domaine.com
        ServerAdmin webmaster@mon_domaine.com
        ...
        DocumentRoot /quelque/part/
        ...

Avec ça, vous pouvez appeler http://peu_importe.mon_domaine.com ou http://www.mon_domaine.com et atterrir sur le même VirtualHost/DocumentRoot, le même « site ».

Ensuite, on améliore pour scinder les 3 jeux de sous-domaines. Supprimez le VirtualHost d’avant et mettez :

        ServerName www.mon_domaine.com
        ServerAdmin webmaster@mon_domaine.com
        ...
        DocumentRoot /quelque/part/le/site/www/
        ...


        ServerAlias demo*.mon_domaine.com
        ServerAdmin webmaster@mon_domaine.com
        ...
        DocumentRoot /quelque/part/le/code/des/sites/de/demo/
        ...


        ServerName mon_domaine.com
        ServerAlias *.mon_domaine.com
        ServerAdmin webmaster@mon_domaine.com
        ...
        DocumentRoot /quelque/part/le/code/des/sites/de/production/
        ...

Bah voilà, c’est tout, les 3 répertoires mentionnés dans les DocumentRoot sont indépendants.
Il ne resterait plus que dans l’outil, à récupérer le nom du sous-domaine (exemple à partir de $_SERVER['SERVER_NAME'] en PHP) et faire le traitement adéquat.

En espérant que ça serve à quelqu’un,

A la prochaine !

L’article Catch-all DNS, VirtualHost et on fait mumuse avec les noms de sous-domaines est apparu en premier sur Le blog de Michauko.

Vus : 2564
Publié par Michauko : 64