<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN"> <HTML> <HEAD> <TITLE>Virtual Services Howto: Virtuald </TITLE> <LINK HREF="Virtual-Services-HOWTO-4.html" REL=next> <LINK HREF="Virtual-Services-HOWTO-2.html" REL=previous> <LINK HREF="Virtual-Services-HOWTO.html#toc3" REL=contents> </HEAD> <BODY> <A HREF="Virtual-Services-HOWTO-4.html">Avanti</A> <A HREF="Virtual-Services-HOWTO-2.html">Indietro</A> <A HREF="Virtual-Services-HOWTO.html#toc3">Indice</A> <HR> <H2><A NAME="s3">3. Virtuald </A></H2> <H2><A NAME="ss3.1">3.1 Introduzione</A> </H2> <P>Ogni connessione di rete è basata su due coppie di indirizzi IP e porte. L'`API' (Applications Program Interface) per la programmazione di rete viene chiamata `Socket API'. Un `socket' si comporta come un file aperto, con operazioni di lettura/scrittura su di esso è possibile scambiare dati su una connessione di rete. C'è una funzione chiamata <CODE>getsockname</CODE> che restituisce l'indirizzo IP del socket locale. Virtuald in primo luogo utilizza <CODE>getsockname</CODE> per determinare a quale indirizzo IP della macchina locale si vuole accedere. Quindi legge da un file di configurazione quale directory è associata a tale indirizzo IP. Virtuald fa <CODE>chroot</CODE> a quella directory e passa la connessione al servizio. <CODE>Chroot</CODE> reimposta `/', la directory radice, in un nuovo punto dell'albero delle directory, in modo tale che il programma in esecuzione non possa accedere a nulla fuori da questo ramo. Quindi ogni indirizzo IP è associato ad un proprio filesystem virtuale. Tutto ciò è trasparente per il programma di rete, che si comporterà come se niente fosse successo. Virtuald può quindi essere utilizzato insieme con un programma come inetd per rendere virtuale un servizio. <P> <H2><A NAME="ss3.2">3.2 Inetd </A> </H2> <P>Inetd è un super server di rete che sta in ascolto su varie porte e, quando riceve una connessione (ad esempio, una richiesta pop in entrata), effettua la fase di negoziazione e passa la connessione ad un programma che gestisce lo specifico servizio. Questo per evitare che vengano eseguiti dei servizi che restano inattivi quando inutilizzati. <P> <P>Un file /etc/inetd.conf standard appare così: <P> <PRE> ftp stream tcp nowait root /usr/sbin/tcpd \ wu.ftpd -l -a pop-3 stream tcp nowait root /usr/sbin/tcpd \ in.qpop -s </PRE> <P>Il file /etc/inetd.conf di un sistema in cui si utilizza virtuald appare così: <P> <PRE> ftp stream tcp nowait root /usr/local/bin/virtuald \ virtuald /virtual/conf.ftp wu.ftpd -l -a pop-3 stream tcp nowait root /usr/local/bin/virtuald \ virtuald /virtual/conf.pop in.qpop -s </PRE> <P> <H2><A NAME="ss3.3">3.3 File di configurazione</A> </H2> <P>Ciascun servizio ha un file di configurazione che controlla quali indirizzi IP e directory sono autorizzati per quel servizio. Si può avere o un unico file principale oppure più file di configurazione, se si desidera che ad ogni servizio sia associato una lista diversa di domini. Un tipico file di configurazione appare così: <P> <PRE> # Questo è un commento e allo stesso modo vengono trattate le linee vuote # Formato: IndirizzoIP [spazio] directory [nessun spazio] 10.10.10.129 /virtual/domain1.com 10.10.10.130 /virtual/domain2.com 10.10.10.157 /virtual/domain3.com # Opzione predefinita per tutti gli altri indirizzi IP default / </PRE> <P> <H2><A NAME="ss3.4">3.4 Codice sorgente</A> </H2> <P>Questo è il codice sorgente in C del programma virtuald. È necessario compilarlo e installarlo in /usr/local/bin con permessi 0755, utente root, e gruppo root. L'unica opzione di compilazione è VERBOSELOG che attiva/disattiva la registrazione delle connessioni nei file di log: <P> <PRE> #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> #undef VERBOSELOG #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)<0) { 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.49 $"); #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); } </PRE> <P> <HR> <A HREF="Virtual-Services-HOWTO-4.html">Avanti</A> <A HREF="Virtual-Services-HOWTO-2.html">Indietro</A> <A HREF="Virtual-Services-HOWTO.html#toc3">Indice</A> </BODY> </HTML>