Sophie

Sophie

distrib > Mandriva > 9.1 > i586 > by-pkgid > f1098342ec4a2b28475e34123ce17201 > files > 1264

howto-html-it-9.1-0.5mdk.noarch.rpm

<!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 &egrave; 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 &egrave; possibile
scambiare dati su una connessione di rete. C'&egrave; 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 &egrave; 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 &egrave; associato ad un proprio filesystem
virtuale. Tutto ci&ograve; &egrave; trasparente per il programma di rete,
che si comporter&agrave; come se niente fosse successo. Virtuald pu&ograve;
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 &egrave; 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&igrave;:
<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&igrave;: 
<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&ograve; avere o un unico file principale oppure pi&ugrave; file di
configurazione, se si desidera che ad ogni servizio sia associato una lista
diversa di domini. Un tipico file di configurazione appare cos&igrave;: 
<P>
<PRE>
# Questo &egrave; 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 &egrave; il codice sorgente in C del programma virtuald. &Egrave;
necessario compilarlo e installarlo in /usr/local/bin con permessi 0755,
utente root, e gruppo root. L'unica opzione di compilazione &egrave;
VERBOSELOG che attiva/disattiva la registrazione delle connessioni nei
file di log:
<P>
<PRE>
#include &lt;netinet/in.h&gt;
#include &lt;sys/socket.h&gt;
#include &lt;arpa/inet.h&gt;
#include &lt;stdarg.h&gt;
#include &lt;unistd.h&gt;
#include &lt;string.h&gt;
#include &lt;syslog.h&gt;
#include &lt;stdio.h&gt;

#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 *)&amp;virtual_addr,&amp;virtual_len)&lt;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(&amp;ipaddr))
        {
                syslog(LOG_ERR,"getipaddr failed");
                exit(0);
        }
#ifdef VERBOSELOG
        syslog(LOG_ERR,"Incoming ip: %s",ipaddr);
#endif
        if (iptodir(&amp;dir,ipaddr,argv[1]))
        {
                syslog(LOG_ERR,"iptodir failed");
                exit(0);
        }
        if (chroot(dir)&lt;0)
        {
                syslog(LOG_ERR,"chroot failed: %m");
                exit(0);
        }
#ifdef VERBOSELOG
        syslog(LOG_ERR,"Chroot dir: %s",dir);
#endif
        if (chdir("/")&lt;0)
        {
                syslog(LOG_ERR,"chdir failed: %m");
                exit(0);
        }
        if (execvp(argv[2],argv+2)&lt;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>