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, getsockname
, qui retourne l'adresse IP de la socket locale. Virtuald utilise 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 chroot
sur ce r�pertoire et prendre en compte la connexion au service. 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 devienne inaccessible pour le programme. Ainsi, chaque adresse IP se voit assign� un syst�me virtuel 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.
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 l'envoie au programme sp�cifi�. Cela �vite de faire tourner des serveurs pour rien lorsqu'il n'y a aucune demande pour eux
Un fichier /etc/inetd.conf
standard ressemble � ceci :
ftp stream tcp nowait root /usr/sbin/tcpd \ wu.ftpd -l -a pop-3 stream tcp nowait root /usr/sbin/tcpd \ in.qpop -s
Un fichier /etc/inetd.conf
virtualis� ressemble � ceci :
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
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�rents. Un fichier de configuration ressemble � ceci :
# C'est un commentaire, comme le sont les lignes blanches # Format IP "ESPACE" dir "PAS D'ESPACES" 10.10.10.129 /virtual/foo.bar.com 10.10.10.130 /virtual/bar.foo.com 10.10.10.157 /virtual/boo.la.com
Ceci est un code source en C du programme virtuald. Compilez-le et installez-le dans /usr/local/bin avec les permissions 0755, l'utilisateur root, et le groupe root. La seule option de compilation est VERBOSELOG qui active ou d�sactive l'option de log.
#include <netinet/in.h> #include <sys/socket.h> #include <arpa/inet.h> #include <stdarg.h> #include <unistd.h> #include <string.h> #include <syslog.h> #include <stdio.h> #define BUFSIZE 8192 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) { syslog(LOG_ERR,"getipaddr: getsockname failed: %m"); return -1; } if (!(ipptr=inet_ntoa(virtual_addr.sin_addr))) { syslog(LOG_ERR,"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"))) { syslog(LOG_ERR,"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,' '))) { syslog(LOG_ERR,"iptodir: strchr failed"); return -1; } *bufptr++=0; if (!strcmp(buffer,ipaddr)) { strncpy(dirbuf,bufptr,sizeof(dirbuf)-1); *dir=dirbuf; break; } if (!strcmp(buffer,"default")) { strncpy(dirbuf,bufptr,sizeof(dirbuf)-1); *dir=dirbuf; break; } } if (fclose(fp)==EOF) { syslog(LOG_ERR,"iptodir: fclose failed: %m"); return -1; } if (!*dir) { syslog(LOG_ERR,"iptodir: ip not found in conf file"); return -1; } return 0; } int main(int argc,char **argv) { char *ipaddr,*dir; openlog("virtuald",LOG_PID,LOG_DAEMON); #ifdef VERBOSELOG syslog(LOG_ERR,"Virtuald Starting: $Revision: 1.1.1.1 $"); #endif if (!argv[1]) { syslog(LOG_ERR,"invalid arguments: no conf file"); exit(0); } if (!argv[2]) { syslog(LOG_ERR,"invalid arguments: no program to run"); exit(0); } if (getipaddr(&ipaddr)) { syslog(LOG_ERR,"getipaddr failed"); exit(0); } #ifdef VERBOSELOG syslog(LOG_ERR,"Incoming ip: %s",ipaddr); #endif if (iptodir(&dir,ipaddr,argv[1])) { syslog(LOG_ERR,"iptodir failed"); exit(0); } if (chroot(dir)<0) { syslog(LOG_ERR,"chroot failed: %m"); exit(0); } #ifdef VERBOSELOG syslog(LOG_ERR,"Chroot dir: %s",dir); #endif if (chdir("/")<0) { syslog(LOG_ERR,"chdir failed: %m"); exit(0); } if (execvp(argv[2],argv+2)<0) { syslog(LOG_ERR,"execvp failed: %m"); exit(0); } closelog(); exit(0); }
Hosting by: Hurra Communications GmbH
Generated: 2007-01-26 18:01:22