Virtual Services Howto <author>Brian Ackerman, <tt/brian@nycrc.net/ &nl; Adaptation française Etienne BERNARD <tt/bernard@isia.cma.fr/ <date>v1.2, 4 Novembre 1997 <abstract> Ce document a été écrit pour répondre au nombre grandissant de questions sur la manière de rendre un service virtuel. </abstract> <!-- Table of contents --> <toc> <!-- Beginning --> <sect> Introduction <sect1> Pré-requis <p> Créer une machine pour des services virtuels n'est pas du tout difficile. Cependant, des connaissances basiques ne sont pas suffisantes. De plus, ce document n'est pas destiné à vous expliquer comment configurer une machine sous Linux. <p> Afin que vous puissiez comprendre cet HOWTO, nous supposerons que les documents suivants vous sont tout à fait familiers : <itemize> <item> Compiler un noyau Linux et ajouter le support de l'IP aliasing <htmlurl url="http://sunsite.unc.edu/mdw/HOWTO/mini/IP-Alias" name="IP alias mini-HOWTO"> <item> Installer et configurer des périphériques réseaux <htmlurl url="http://sunsite.unc.edu/mdw/HOWTO/NET-3-HOWTO.html" name="NET-3 HOWTO"> <item> Installer inetd <htmlurl url="http://sunsite.unc.edu/mdw/HOWTO/NET-3-HOWTO.html" name="NET-3 HOWTO"> <item> Compiler et installer divers paquetages de logiciels en réseau comme <htmlurl url="http://www.sendmail.org" name="Le site de Sendmail"> <htmlurl url="http://www.apache.org" name="Le site d'Apache"> <htmlurl url="http://www.cetis.hvu.nl/~koos/wu-ftpd-faq.html" name="La FAQ de Wu-Ftpd"> <item> Mettre en place le DNS <htmlurl url="http://sunsite.unc.edu/mdw/HOWTO/DNS-HOWTO.html" name="DNS HOWTO"> </itemize> Si vous n'êtes pas certain de la marche à suivre pour effectuer une des actions précédents, il est FORTEMENT recommandé que vous suiviez les liens proposés pour vous familiariser avec tous ces paquetages. Je ne répondrai à AUCUN mail concernant les points précédents. Veuillez s'il vous plaît rediriger toute question à l'auteur du HOWTO approprié. <sect1> But <p> Le but des services virtuels est de permettre à une seule machine de reconnaître de multiples adresses IP sans avoir de multiples cartes réseau. L'IP aliasing est une option du noyau qui vous permet d'assigner plus d'une adresse IP à chaque périphérique réseau. Le noyau multiplexe (les échange très rapidement) en tâche de fond et l'utilisateur a l'impression d'avoir plusieurs cartes réseau dans sa machine. <p> Ce multiplexage permet à de multiples domaines (www.domaine1.com, www.domaine2.com, etc.) d'être logés sur la même machine pour le même coût que pour un seul domaine. Malheureusement, la plupart des services (ftp, web, courrier électronique) n'ont pas été conçus pour gérer de multiples domaines. Afin de les faire fonctionner correctement, vous devrez modifier à la fois les fichiers de configuration et le code source. Ce document décrit comment réaliser ces modifications pour la mise en place d'une machine virtuelle. <p> Un démon est également nécessaire afin de faire fonctionner les services virtuels. Le code source de ce démon (virtuald) est fourni plus loin dans ce document. <sect1> Commentaires <p> Ce document va grossir au fur et à mesure que les paquetages seront mis à jour et que le code source ou que les modifications proposées changeront. Si quelque partie de ce document n'est pas claire, envoyez moi vous questions ou suggestions. Afin que je n'ai pas à chercher dans le HOWTO en entier, assurez vous s'il vous plaît que les commentaires sont aussi spécifiques que possible et incluent la section où se trouve le point discutable. Il est important que tout mail ait un champ Subject: contenant VIRTSERVICES HOWTO. Tout autre mail sera considéré comme du mail personnel, et tous mes amis savent que je ne lis pas tout le temps mon mail personnel et il risque donc d'être effacé avec le leur. <p> Veuillez également noter que mes exemples ne sont pas autre chose que des exemples, et ne doivent pas être recopiés tels quels. Il se peut que vous ayez à insérer vos propres valeurs. Si vous rencontrez des problèmes, envoyez moi un mail, contenant tous les fichiers de configuration pertinents et les messages d'erreur que vous avez obtenu lors de l'installation. Je vous renverrai mes suggestion. <sect1> Histoire des changements <p> V1.0 Document initial. <p> V1.1 Correction d'une erreur dans la section sur le web virtuel. <p> V1.2 Correction de la date. <sect1> Copyright/Distribution <p> Ce document est Copyright (c) 1997 par The Computer Resource Center Inc. <p> Une copie de ce document peut être reproduite ou distribuée sur n'importe quel support physique ou électronique sans la permission de l'auteur. De la même façon, les traductions sont autorisées sans permission expresse si elle incluent un mot disant qui l'a traduit (NdT: voir le début du document pour mes coordonnées). Une redistribution commerciale est autorisé et encouragée. Dans ce cas cependant, faites en part à <htmlurl url="mailto:brian@nycrc.net" name="Computer Resource Center">. <p> Vous pouvez utiliser des extraits de ce document sans accord de l'auteur, à condition que l'oeuvre dérivée contienne une copie de ce document ou un pointeur vers une copie de ce document. <p> Vous avez la permission d'effectuer des copies ainsi que de les distribuer à condition que le paragraphe sur le copyright ainsi que cette note soient préservés sur toutes les copies. <p> En bref, nous désirons promouvoir la dissémination de cette information par quelque moyen que ce soit. Cependant, je désire conserver le copyright sur ce document, et aimerait être tenu au courant de tous les plans de redistributions de ce HOWTO. <sect> IP aliasing <p> L'IP aliasing est une option du noyau qui doit être mise en place afin de pouvoir faire tourner des services virtuels sur une machine. Il existe déjà un mini-HOWTO expliquant l' <htmlurl url="http://sunsite.unc.edu/mdw/HOWTO/mini/IP-Alias" name="IP aliasing">. Référez vous à ce document pour toute question concernant la mise en place de cette option. <sect> Virtuald <sect1> Comment ça marche <p> Toute connexion réseau est composée de deux paires adresse IP/port. L'API (Applications Program Interface, ou Interface de Programmation d'Applications) pour la programmation réseau est nommée l'API Sockets. La socket agit comme un fichier ouvert, et vous pouvez envoyer ou recevoir des données à travers une connexion réseau en lisant ou en écrivant dans la socket. Il existe une fonction, <tt/getsockname/, qui retourne l'adresse IP de la socket locale. Virtuald utilise <tt/getsockname/ pour déterminer sur quel adresse IP de la machine locale la connexion a été faite. Virtuald lit un fichier de configuration pour récupérer le répertoire associé à cette adresse IP. Il va utiliser <tt/chroot/ sur ce répertoire et prendre en compte la connexion au service. <tt/Chroot/ change le répertoire / (le répertoire root) vers un nouveau point, de sorte que tout ce qui est au dessus de ce répertoire devient inaccessible pour le programme. Ainsi, chaque adresse IP se voit assigné un système vi! ! ! rtuel de fichiers. Pour le programme réseau, ceci est transparent, et le programme va se comporter comme si de rien n'était. Virtuald, en conjonction avec un programme comme inetd, peut être utilisé pour virtualiser n'importe quel service. <sect1> inetd <p> Inetd est un super serveur réseau qui écoute sur de multiples ports et, lorsqu'il reçoit une demande de connexion (par exemple, une requête POP), inetd réalise la connexion et la passe au programme spécifié. Cela évite de faire tourner des serveurs pour rien lorsqu'il n'y a aucune demande pour eux. <p> Un fichier <tt>/etc/inetd.conf</tt> standard ressemble à ceci : <verb> ftp stream tcp nowait root /usr/sbin/tcpd wu.ftpd -l -a pop-3 stream tcp nowait root /usr/sbin/tcpd in.qpop -s </verb> Un <tt>/etc/inetd.conf</tt> virtuel ressemble à cela : <verb> ftp stream tcp nowait root /usr/bin/virtuald virtuald /virtual/conf.ftp wu.ftpd -l -a pop-3 stream tcp nowait root /usr/bin/virtuald virtuald /virtual/conf.pop in.qpop -s </verb> <sect1> virtual.conf <p> Chaque service se voit attribué un fichier de configuration qui contrôlera quelles IPs et quels répertoires sont autorisés pour ce service. Vous pouvez avoir un fichier de configuration principal ou de nombreux fichiers de configuration si vous désirez que chaque service se voit attribuer une liste de domaines différente. Un fichier <tt/virtual.conf/ ressemble à ceci : <verb> # C'est un commentaire, comme le sont les lignes blanches # Format IP <SPACE> dir <NOSPACES> 10.10.10.129 /virtual/foo.bar.com 10.10.10.130 /virtual/bar.foo.com 10.10.10.157 /virtual/boo.la.com </verb> <sect1> Le code source de virtuald <p> <verb> #include <netinet/in.h> #include <sys/socket.h> #include <arpa/inet.h> #include <stdarg.h> #include <string.h> #include <syslog.h> #include <stdio.h> #define BUFSIZE 8192 main(int argc,char **argv) { char buffer[BUFSIZE]; char *ipaddr,*dir; logit("Virtuald Starting: $Revision: 1.19 $"); if (!argv[1]) { logit("invalid arguments: no conf file"); quitting_virtuald(0); } if (!argv[2]) { logit("invalid arguments: no program to run"); quitting_virtuald(0); } if (getipaddr(&ipaddr)) { logit("getipaddr failed"); quitting_virtuald(0); } sprintf(buffer,"Incoming ip: %s",ipaddr); logit(buffer); if (iptodir(&dir,ipaddr,argv[1])) { logit("iptodir failed"); quitting_virtuald(0); } if (chroot(dir)<0) { logit("chroot failed: %m"); quitting_virtuald(0); } sprintf(buffer,"Chroot dir: %s",dir); logit(buffer); if (chdir("/")<0) { logit("chdir failed: %m"); quitting_virtuald(0); } if (execvp(argv[2],argv+2)<0) { logit("execvp failed: %m"); quitting_virtuald(0); } } int logit(char *buf) { openlog("virtuald",LOG_PID,LOG_DAEMON); syslog(LOG_ERR,buf); closelog(); return 0; } int quitting_virtuald(int retval) { exit(retval); return 0; } int getipaddr(char **ipaddr) { struct sockaddr_in virtual_addr; static char ipaddrbuf[BUFSIZE]; int virtual_len; char *ipptr; virtual_len=sizeof(virtual_addr); if (getsockname(0,(struct sockaddr *)&virtual_addr,&virtual_len)<0) { logit("getipaddr: getsockname failed: %m"); return -1; } if (!(ipptr=inet_ntoa(virtual_addr.sin_addr))) { logit("getipaddr: inet_ntoa failed: %m"); return -1; } strncpy(ipaddrbuf,ipptr,sizeof(ipaddrbuf)-1); *ipaddr=ipaddrbuf; return 0; } int iptodir(char **dir,char *ipaddr,char *filename) { char buffer[BUFSIZE],*bufptr; static char dirbuf[BUFSIZE]; FILE *fp; if (!(fp=fopen(filename,"r"))) { logit("iptodir: fopen failed: %m"); return -1; } *dir=NULL; while(fgets(buffer,BUFSIZE,fp)) { buffer[strlen(buffer)-1]=0; if (*buffer=='#' || *buffer==0) continue; if (!(bufptr=strchr(buffer,' '))) { logit("iptodir: strchr failed"); return -1; } *bufptr++=0; if (!strcmp(buffer,ipaddr)) { strncpy(dirbuf,bufptr,sizeof(dirbuf)-1); *dir=dirbuf; break; } } if (fclose(fp)==EOF) { logit("iptodir: fclose failed: %m"); return -1; } if (!*dir) { logit("iptodir: ip not found in conf file"); return -1; } return 0; } </verb> <sect> Scripts utiles <sect1> virtfs <p> Chaque domaine doit avoir une arborescence de répertoires. Puisque vous utilisez <tt/chroot/, vous aurez besoin de copies multiples des librairies, binaires, fichiers de configuration, etc... partagés. J'utilise le répertoire <tt>/virtual/domaine.com</tt> pour chaque domaine que je crée. Je comprends bien que cela représente du gaspillage d'espace disque, mais l'espace disque est meilleur marché qu'une nouvelle machine ou que des cartes réseau. Si vous désirez réellement sauver de l'espace disque, vous pouvez lier les fichiers entre eux, afin qu'une seule copie de chaque binaire soit présente. <p> Voici un fichier virtfs d'exemple : <verb> #!/bin/bash echo '$Revision: 1.19 $' echo -n "Saisissez le nom de domaine : " read domain if [ "$domain" = "" ] then echo Vous n'avez rien saisi : on arrête là exit 0 fi leadingdir=/virtual echo -n "Saisissez le nom du répertoire contenant les domaines (défaut: $default): " read ans if [ "$ans" != "" ] then leadingdir=$ans fi newdir=$leadingdir/$domain if [ -d "$newdir" ] then echo Le répertoire $newdir existe déjà exit 0 else echo Nouveau répertoire : $newdir fi echo Creation de $newdir mkdir -p $newdir echo Creation de bin cp -pdR /bin $newdir echo Creation de dev cp -pdR /dev $newdir echo Creation de dev/log ln -f /virtual/log $newdir/dev/log echo Creation d'etc mkdir -p $newdir/etc for i in /etc/* do if [ -d "$i" ] then continue fi cp -pd $i $newdir/etc done echo Creation de etc/skel mkdir -p $newdir/etc/skel echo Creation de home for i in a b c d e f g h i j k l m n o p q r s t u v w x y z do mkdir -p $newdir/home/$i done echo Creation de home/c/crc mkdir -p $newdir/home/c/crc chown crc.users $newdir/home/c/crc echo Creation de lib mkdir -p $newdir/lib for i in /lib/* do if [ -d "$i" ] then continue fi cp -pd $i $newdir/lib done echo Creation de proc mkdir -p $newdir/proc echo Creation de sbin cp -pdR /sbin $newdir echo Creation de tmp mkdir -p -m 0777 $newdir/tmp chmod +t $newdir/tmp echo Creation de usr mkdir -p $newdir/usr echo Creation de usr/bin cp -pdR /usr/bin $newdir/usr echo Creation de usr/lib mkdir -p $newdir/usr/lib echo Creation de usr/lib/locale cp -pdR /usr/lib/locale $newdir/usr/lib echo Creation de usr/lib/terminfo cp -pdR /usr/lib/terminfo $newdir/usr/lib echo Creation de usr/lib/zoneinfo cp -pdR /usr/lib/zoneinfo $newdir/usr/lib echo Creation de usr/lib/\*.so\* cp -pdR /usr/lib/*.so* $newdir/usr/lib echo Creation de usr/sbin cp -pdR /usr/sbin $newdir/usr echo Lien de usr/tmp vers /tmp ln -s /tmp $newdir/usr/tmp echo Creation de var mkdir -p $newdir/var echo Creation de var/lock cp -pdR /var/lock $newdir/var echo Creation de var/log mkdir -p $newdir/var/log echo Creation de var/log/wtmp cp /dev/null $newdir/var/log/wtmp echo Creation de var/run cp -pdR /var/run $newdir/var echo Creation de var/run/utmp cp /dev/null $newdir/var/run/utmp echo Creation de var/spool cp -pdR /var/spool $newdir/var echo Lien de var/tmp vers /tmp ln -s /tmp $newdir/var/tmp echo Creation de var/www/html mkdir -p $newdir/var/www/html chown webmast.www $newdir/var/www/html chmod g+s $newdir/var/www/html echo Creation de var/www/master mkdir -p $newdir/var/www/master chown webmast.www $newdir/var/www/master echo Creation de var/www/server mkdir -p $newdir/var/www/server chown webmast.www $newdir/var/www/server exit 0 </verb> <sect1> virtexec <p> Afin d'exécuter des commandes dans un environnement virtuel, vous devez utilise <tt/chroot/ sur ce répertoire puis lancer la commande. J'ai écris un script shell nommé virtexec se chargeant de ces opérations, pour n'importe quelle commande : <verb> #!/bin/sh echo '$Revision: 1.19 $' BNAME=`basename $0` FIRST4CHAR=`echo $BNAME | cut -c1-4` REALBNAME=`echo $BNAME | cut -c5-` if [ "$BNAME" = "virtexec" ] then echo Vous ne pouvez pas lancer virtexec directement. Il FAUT un lien symbolique exit 0 fi if [ "$FIRST4CHAR" != "virt" ] then echo Le lien ne pointe pas sur une fonction virtuelle exit 0 fi list="" num=1 for i in /virtual/* do if [ ! -d "$i" ] then continue fi if [ "$i" = "/virtual/lost+found" ] then continue fi list="$list $i $num" num=`expr $num + 1` done if [ "$list" = "" ] then echo Je ne trouve pas d'environnement virtuel exit 0 fi dialog --clear --title 'Virtexec' --menu Pick 20 70 12 $list 2> /tmp/menu.$$ if [ "$?" = "0" ] then newdir=`cat /tmp/menu.$$` else newdir="" fi tput clear rm -f /tmp/menu.$$ echo '$Revision: 1.19 $' if [ ! -d "$newdir" ] then echo Le nouveau repertoire $newdir N'EXISTE PAS exit 0 else echo Nouveau repertoire : $newdir fi echo bname: $BNAME echo realbname: $REALBNAME if [ "$*" = "" ] then echo argumentss: aucun else echo args: $* fi echo Changement de repertoire vers $newdir cd $newdir echo Lancement de $REALBNAME chroot $newdir $REALBNAME $* exit 0 </verb> Veuillez noter que vous devez disposer du programme <tt/dialog/ sur votre système pour que ce script fonctionne. Pour utiliser virtexec, créez un lien symbolique d'un programme vers celui-ci. Par exemple : <verb> ln -s /usr/bin/virtexec /usr/bin/virtpasswd ln -s /usr/bin/virtexec /usr/bin/virtvi ln -s /usr/bin/virtexec /usr/bin/virtpico ln -s /usr/bin/virtexec /usr/bin/virtemacs ln -s /usr/bin/virtexec /usr/bin/virtmailq </verb> A présent, si vous tapez <tt/virtvi/ ou <tt/virtpasswd/ ou encore <tt/virtmailq/, cela vous permettra d'éditer un fichier, changer le mot de passe d'un utilisateur, ou vérifier la queue de mail sur votre système virtuel. Vous pouvez créer autant de liens vers virtexec que vous désirez. Cependant, notez bien que si votre programme nécessite une librairie partagée, celle-ci doit se trouver sur le système de fichiers virtuel. Le binaire doit exister sur le système de fichiers virtuel également. <sect1> Notes à propos de virtfs et virtexec <p> J'installe tous les scripts dans <tt>/usr/bin</tt>. Tout ce que je ne désire pas mettre sur un système de fichier virtuel, je le place dans <tt>/usr/local</tt>. Le script ne touche à rien dans ce répertoire lors de la copie. Les fichiers ne devant pas chevaucher plusieurs systèmes de fichiers virtuels doivent être supprimés. Par exemple, <tt/ssh/ est installé sur mon système, et je n'ai pas voulu que les clefs privées soient disponibles sur tous les systèmes de fichier. J'ai donc supprimé le fichier des systèmes de fichiers virtuels après avoir lancé <tt/virtfs/. Je change également le <tt/resolv.conf/ et supprime tout ce qui contient le nom d'un autre domaine, pour des raisons légales. Par exemple, les fichiers <tt>/etc/hosts</tt> et <tt>/etc/HOSTNAME</tt>. <p> Les programmes pour lesquels je fais un lien symbolique vers virtexec sont : <itemize> <item> virtpasswd -- changer le mot de passe d'un utilisateur <item> virtadduser -- ajouter un utilisateur <item> virtdeluser -- supprimer un utilisateur <item> virtsmbstatus -- consulter l'état de samba <item> virtvi -- éditer un fichier <item> virtmailq -- vérifier la mailq <item> virtnewaliases -- reconstruire la table des alias mail </itemize> <sect> DNS <p> Vous pouvez configurer le DNS normalement. Ce qui est bien avec ce système, c'est que tous les services se comportement normalement, comme s'ils se trouvaient sur des machines physiques différentes. Vous pouvez consulter le HOWTO sur le <htmlurl url="http://sunsite.unc.edu/mdw/HOWTO/DNS-HOWTO.html" name="DNS">. <sect> Syslog <sect1> Problème <p> Syslog est l'outil de <em/logging/ couramment utilisé sur les système UNIX. Syslog est un démon qui ouvre un fichier spécial appelé FIFO. Une FIFO est un fichier spécial, se comportant comme une file d'attente. Tout ce qui y est écrit "ressortira" en lecture. Le démon syslog attend les données en lecture. Il existe des fonctions C pour écrire dans les FIFO. Si vous utilisez ces fonctions C dans vos programmes. Souvenez vous que vous avez utilisé <tt/chroot/ et que la FIFO <tt>/dev/log</tt> ne se trouve pas dans l'environnement virtuel. Cela implique que aucun des environnements virtuels ne pourra utiliser <tt/syslog/. Nous ne pouvons pas tout simplement copier le fichier, puisque les programmes utilisent <tt>/dev/log</tt> au lieu du nouveau que nous aurions créé. <p> Attention, certaines version de <tt/syslog/ utilisent une socket udp au lieu d'une FIFO. Cependant, ce n'est généralement pas le cas. <sect1> Solution <p> Syslog peut scruter d'autres FIFO si vous lui dites en ligne de commande. Lancer donc syslog avec l'argument : <verb> syslog -p /virtual/log </verb> Faites alors un lien de <tt>/dev/log</tt> vers <tt>/virtual/log</tt> (un lien symbolique) : <verb> ln -sf /virtual/log /dev/log </verb> Puis liez toutes les copies de <tt>/dev/log</tt> vers ce fichier avec la commande (attention, c'est un lien NON symbolique) : <verb> ln /virtual/log /virtual/domain.com/dev/log </verb> Le script virtfs ci-dessus le fait pour vous. Puisque <tt>/virtual</tt> est un disque entier, et que les <tt>/dev/log</tt> sont liés, ils ont le même numéro d'inode et pointent vers les mêmes données. Le <tt/chroot/ ne peut pas empêcher cela, et donc tous vos <tt>/dev/log</tt> virtuels vont à présent fonctionner. Notez également que tous les messages de toutes les machines virtuelles seront écrits dans un même fichier. Cependant, vous pouvez écrire des programmes pour filtrer les données. Si vous ne désirez pas écrire un programme et que vous avez néanmoins besoin de fichiers de log séparé, vous pouvez lancer des programmes syslog différents pour chaque système de fichiers virtuel avec la commande : <verb> syslog -p /virtual/domain1.com/dev/log syslog -p /virtual/domain2.com/dev/log </verb> Cependant, cela gaspille des processus et je ne le recommande pas. Cette version du fichier <tt/syslog.init/ refait les liens vers les <tt>/dev/log</tt> à chaque fois que vous le lancez, au cas ou la configuration ait été endommagée. Voici un <tt/syslog.init/ modifié : <verb> #!/bin/sh # Source function library. . /etc/rc.d/init.d/functions case "$1" in start) echo -n "Starting dev log: " ln -sf /virtual/log /dev/log echo done echo -n "Starting system loggers: " daemon syslogd -p /virtual/log daemon klogd echo echo -n "Starting virtual dev log: " for i in /virtual/* do if [ ! -d "$i" ] then continue fi if [ "$i" = "/virtual/lost+found" ] then continue fi ln -f /virtual/log $i/dev/log echo -n "." done echo " done" touch /var/lock/subsys/syslog ;; stop) echo -n "Shutting down system loggers: " killproc syslogd killproc klogd echo rm -f /var/lock/subsys/syslog ;; *) echo "Usage: syslog {start|stop}" exit 1 esac exit 0 </verb> Notez que vous n'avez pas à mettre tous les systèmes virtuels de fichiers sur un seul disque. Cependant, vous devrez lancer un syslog différent pour chaque partition qui contient un système virtuel de fichiers.. <sect> FTP virtuel <p> Wu-ftpd intégre en standard le support des domaines virtuels. Cependant, vous ne pouvez pas utiliser des fichiers de mot de passe différents pour chaque domaine. Par exemple, si <tt/bob@domaine1.com/ et <tt/bob@domaine2.com/ désirent tous les deux un compte, vous devrez donner à l'un des deux le nom <tt/bob2/ ou demander à un des utilisateurs de choisir un autre nom de login. Puisque vous disposez à présent de systèmes de fichiers différents pour chaque domaine, vous disposez de fichiers de mot de passe différents et ce problème disparaît. Vous n'avez qu'à créer un script <tt/virtnewuser/ et <tt/virtpasswd/ de la façon qui est expliquée ci-dessus, et tout fonctionnera. Vous pouvez également disposer d'un ftp <em/anonymous/ dans chaque environnement virtuel, puisque ce n'est pas affecté par le système de fichiers. <p> Les entrées pour wu-ftp dans <tt/inetd.conf/ sont : <verb> ftp stream tcp nowait root /usr/bin/virtuald virtuald /virtual/conf.ftp wu.ftpd -l -a </verb> <sect> Web virtuel <p> Apache supporte en standard la gestion des domaines virtuels. C'est d'ailleurs le seul programme pour lequel je recommande d'utiliser le système de gestion des domaines virtuels fourni avec. Lorsque vous lancez un programme par l'intermédiaire d'inetd, il y a un coût supplémentaire, puisque le programme doit démarrer à chaque fois qu'il y a une demande de connexion, et vous obtenez des temps de réponse beaucoup plus longs, inacceptables pour le web. Apache intégre également un mécanisme pour stopper les connexions lorsqu'elles sont trop nombreuses. <p> Si vous désirez quand même utiliser inetd pour lancer apache, ajoutez la ligne suivante dans votre fichier <tt/inetd.conf/ : <verb> www stream tcp nowait www /usr/sbin/virtuald virtuald /virtual/conf.www httpd -f /var/www/conf/httpd.conf </verb> Dans le fichier <tt>/var/www/conf/httpd.conf</tt> vous devrez spécifier : <verb> ServerType inetd </verb> Puis configurez chaque serveur Apache comme pour un seul domaine. <p> A l'heure où j'écris ces lignes, il n'existe pas de HOWTO sur le web virtuel. Cependant, je crois qu'il ne va pas tarder à être écrit. Dans ce cas, je mettrai une référence à ce HOWTO. Si ce document tarde à paraître, et que j'ai assez de demandes, j'écrirai une petite partie sur la configuration d'Apache pour les domaines virtuels. <sect> Mail virtuel avec Pop <sect1> Avis aux utilisateurs de QMail <p> Cette section d'applique uniquement a sendmail. Une section pour qmail sera ajoutée dans la prochaine version de ce document. <sect1> Problème <p> Le support du mail virtuel est une demande toujours grandissante. Sendmail affirme qu'il supporte le mail virtuel. En fait, il se contente d'être à l'écoute de mail pour différents domaines. Vous pouvez alors demander à faire suivre le mail quelque part. Cependant, si vous le faites suivre sur la machine locale et que vous avez du mail pour bob@domaine1.com et bob@domaine2.com, ils vont atteindre la même boîte. C'est un problème puisque les bob sont deux personnes différentes, avec du courrier électronique différent. <sect1> Une mauvaise solution <p> Vous pouvez vous assurer que chaque nom d'utilisateur est unique en utilisant une numérotation des noms d'utilisateurs :bob1, bob2, etc... Vous pourriez également hacker le mail et le pop pour que ces conversions soient invisibles, mais cela peut devenir désordonné. Le mail sortant a pour domaine domaineprincipal.com et vous désirez que chaque mail envoyé dans chaque sous-domaine ait une adresse From: différente. <sect1> Une bonne solution <p> Chaque système de fichiers virtuel fourni à chaque domaine un fichier <tt>/etc/passwd</tt>. Cela signifie que bob@domaine1.com et bob@domaine2.com sont des utilisateurs différents dans des fichiers <tt>/etc/passwd</tt> différents, donc le mail ne constituera aucun problème. Ils possèdent également chacun un spool de mail, donc les boîtes aux lettres seront des fichiers différents sur des système de fichiers virtuels différents. <p> Cependant, sendmail nécessite un changement mineur de son code source. Sendmail a un fichier nommé <tt>/etc/sendmail.cw</tt> qui contient tous les noms de machine pour lequel il délivrera le mail localement au lieu de le faire suivre à une autre machine. Sendmail fait une vérification interne de toutes les interfaces réseau de la machine pour initialiser cette liste avec les adresses IP locales. Cela présente un problème si vous envoyez de mails entre deux domaines virtuels de la même machine. Sendmail pensera que l'autre domaine virtuel est une adresse locale et il delivrera le mail localement. Par exemple, bob@domaine1.com envoie un mail à fred@domaine2.com. Puisque le sendmail de domaine1.com pense que domaine2.com est une adresse locale, il va envoyer ce mail à domaine1.com et ne l'enverra jamais à domaine2.com. Vous avez à modifier sendmail (ce que j'ai fait sans problème sur la version 8.8.5) : <verb> vi v8.8.5/src/main.c # Environ à la ligne 494 Vous devriez remplacer la ligne : load_if_names(); Par : /* load_if_names(); Commenté puisque cela casse les domaines virtuels */ </verb> Notez que cette modification n'est nécessaire que si vous désirez envoyer du mail entre des domaines virtuels, ce qui est probable, je pense. <p> Cela corrigera le problème. Cependant, l'adaptateur réseau principal eth0 n'est pas supprimé. Ainsi, si vous envoyez un mail depuis une adresse IP virtuelle vers une adresse sur eth0 de la même machine, il sera délivré localement. Pour cela, j'utilise une adresse IP bidon virtuel1.domaine.com (10.10.10.157). Je n'envoie jamais de mail à cet hôte, les domaines virtuels non plus. C'est aussi l'adresse IP que j'utiliserai pour me connecter sur la machine via ssh, pour vérifier si le système fonctionne. Éditez <tt>/etc/sendmail.cw</tt> et mettez-y les domaines locaux. <verb> vi /etc/sendmail.cw mail.domaine1.com domaine1.com domaine1 localhost </verb> Créez <tt>/etc/sendmail.cf</tt> comme vous le feriez normalement avec m4. J'utilise : <verb> divert(0)dnl VERSIONID(`@(#)tcpproto.mc 8.5 (Berkeley) 3/23/96') OSTYPE(linux) FEATURE(redirect) FEATURE(always_add_domain) FEATURE(use_cw_file) FEATURE(local_procmail) MAILER(local) MAILER(smtp) </verb> Editez <tt>/etc/sendmail.cf</tt> pour répondre sur voter domaine virtuel : <verb> vi /etc/sendmail.cf # Vers la ligne 86 Vous devriez avoir : #Dj$w.Foo.COM Remplacez cette ligne par : Djdomaine1.com </verb> Sendmail ne peut pas être lancé tel quel, vous allez devoir le lancer à travers inetd. C'est un moyen inefficace qui implique un temps de réponse plus long, mais si vous avez un site si occupé pour que la différence soit importante, alors vous devriez utiliser une machine dédiée à ce site. Notez que vous de devez PAS utiliser l'option <tt/-bd/. Notez également que vous devez lancer <tt/sendmail -q/ pour chaque domaine que vous gérez. Le nouveau fichier <tt/sendmail.init/ est le suivant : <verb> #!/bin/sh # Source function library. . /etc/rc.d/init.d/functions case "$1" in start) echo -n "Starting sendmail: " daemon sendmail -q1h echo echo -n "Starting virtual sendmail: " for i in /virtual/* do if [ ! -d "$i" ] then continue fi if [ "$i" = "/virtual/lost+found" ] then continue fi chroot $i sendmail -q1h echo -n "." done echo " done" touch /var/lock/subsys/sendmail ;; stop) echo -n "Stopping sendmail: " killproc sendmail echo rm -f /var/lock/subsys/sendmail ;; *) echo "Usage: sendmail {start|stop}" exit 1 esac exit 0 </verb> Pop devrait s'installer normalement, sans effort supplémentaire. Vous n'avez qu'à modifier l'entrée pour pop dans le fichier <tt/inetd.conf/ pour utiliser le démon virtuald. Pour sendmail et pop, cela donne : <verb> pop-3 stream tcp nowait root /usr/bin/virtuald virtuald /virtual/conf.pop in.qpop -s smtp stream tcp nowait root /usr/bin/virtuald virtuald /virtual/conf.mail sendmail -bs </verb> <sect> Le reste <p> Tout autre service devrait suivre une procédure similaire : <itemize> <item> Ajouter le binaire et les librairies au système virtuel de fichiers. <item> L'ajouter dans <tt>/etc/inetd.conf</tt> <item> Créer un fichier <tt>/virtual/conf.service</tt>. <item> Créer tout script virtuel manquant. </itemize> J'ai fait des essais avec samba et j'ai changé un mot de passe pop virtuel à travers Eudora. Chacun fonctionne sans aucun problème. Si j'ai suffisamment de demandes, j'écrirai une section sur l'installation d'un samba virtuel. <sect> Conclusion <p> Voici tout ce dont vous avez besoin. J'espère que cet article répond à vos attentes. Vous pouvez utiliser l'email à <htmlurl url="mailto:brian@nycrc.net" name="Computer Resource Center"> pour tout commentaire (NdT: en anglais bien sûr). Si vous avez une question, ou si vous me proposez une mise à jour, faîtes le moi savoir et je l'ajouterai. <sect> FAQ <p> Q1. Pourquoi n'y a-t-il aucun question dans cette FAQ ? R1. Parce que personne n'en a encore posé. <!-- Ending --> </article>