Ciascun dominio dovrebbe avere una propria struttura di directory.
Dal momento che si sta usando chroot
bisognerà inserirvi
un duplicato di tutti i file necessari, come librerie condivise, file
binari, file di configurazione eccetera. Io utilizzo /virtual/domain1.com
per ciascun dominio che creo.
Tutto ciò occupa dello spazio su disco, ma è comunque meno costoso di una nuova macchina con tanto di schede di rete. Se è veramente necessario risparmiare spazio su disco, si possono collegare insieme tutte le copie dei file con degli hard link, in modo che esista effettivamente solo una copia di ogni file binario. Il filesystem che utilizzo io occupa poco più di 2Mbyte. Comunque lo script che segue tenta di copiare tutti i file dal filesystem principale in modo da essere il più generico possibile.
Ecco un esempio di semplice script virtfs:
#!/bin/sh echo '$Revision: 1.49 $' echo -n "Inserisci il nome di dominio: " read domain if [ "$domain" = "" ] then echo Non è stato inserito niente: esecuzione interrotta exit 0 fi leadingdir=/virtual echo -n "Inserire la directory principale: (Scelta predefinita: $leadingdir): " read ans if [ "$ans" != "" ] then leadingdir=$ans fi newdir=$leadingdir/$domain if [ -d "$newdir" ] then echo La nuova directory: $newdir: è già esistente exit 0 else echo La nuova directory è: $newdir fi echo Crea $newdir mkdir -p $newdir echo Crea bin cp -pdR /bin $newdir echo Crea dev cp -pdR /dev $newdir echo Crea dev/log ln -f /virtual/log $newdir/dev/log echo Crea etc mkdir -p $newdir/etc for i in /etc/* do if [ -d "$i" ] then continue fi cp -pd $i $newdir/etc done echo Crea etc/skel mkdir -p $newdir/etc/skel echo Crea 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 Crea home/c/crc mkdir -p $newdir/home/c/crc chown crc.users $newdir/home/c/crc echo Crea lib mkdir -p $newdir/lib for i in /lib/* do if [ -d "$i" ] then continue fi cp -pd $i $newdir/lib done echo Crea proc mkdir -p $newdir/proc echo Crea sbin cp -pdR /sbin $newdir echo Crea tmp mkdir -p -m 0777 $newdir/tmp chmod +t $newdir/tmp echo Crea usr mkdir -p $newdir/usr echo Crea usr/bin cp -pdR /usr/bin $newdir/usr echo Crea usr/lib mkdir -p $newdir/usr/lib echo Crea usr/lib/locale cp -pdR /usr/lib/locale $newdir/usr/lib echo Crea usr/lib/terminfo cp -pdR /usr/lib/terminfo $newdir/usr/lib echo Crea usr/lib/zoneinfo cp -pdR /usr/lib/zoneinfo $newdir/usr/lib echo Crea usr/lib/\*.so\* cp -pdR /usr/lib/*.so* $newdir/usr/lib echo Crea usr/sbin cp -pdR /usr/sbin $newdir/usr echo Fa un link a usr/tmp ln -s /tmp $newdir/usr/tmp echo Crea var mkdir -p $newdir/var echo Crea var/lock cp -pdR /var/lock $newdir/var echo Crea var/log mkdir -p $newdir/var/log echo Crea var/log/wtmp cp /dev/null $newdir/var/log/wtmp echo Crea var/run cp -pdR /var/run $newdir/var echo Crea var/run/utmp cp /dev/null $newdir/var/run/utmp echo Crea var/spool cp -pdR /var/spool $newdir/var echo Fa un link a var/tmp ln -s /tmp $newdir/var/tmp echo Crea var/www/html mkdir -p $newdir/var/www/html chown webmast.www $newdir/var/www/html chmod g+s $newdir/var/www/html echo Crea var/www/master mkdir -p $newdir/var/www/master chown webmast.www $newdir/var/www/master echo Crea var/www/server mkdir -p $newdir/var/www/server chown webmast.www $newdir/var/www/server exit 0
Per poter eseguire dei comandi in un ambiente virtuale bisogna prima fare
chroot
nella directory prefissata e poi eseguire il comando.
Ho scritto un apposito script di shell chiamato virtexec che fa questo per
un qualsiasi comando:
#!/bin/sh echo '$Revision: 1.49 $' BNAME=`basename $0` FIRST4CHAR=`echo $BNAME | cut -c1-4` REALBNAME=`echo $BNAME | cut -c5-` if [ "$BNAME" = "virtexec" ] then echo Non si può eseguire direttamente virtexec: è NECESSARIO un link simbolico exit 0 fi if [ "$FIRST4CHAR" != "virt" ] then echo Il link simbolico non è a una funzione virt 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 Non esistono ambienti virtuali 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.49 $' if [ ! -d "$newdir" ] then echo La nuova directory: $newdir: NON ESISTE exit 0 else echo Nuova directory: $newdir fi echo bname: $BNAME echo realbname: $REALBNAME if [ "$*" = "" ] then echo args: none else echo args: $* fi echo Spostamento in $newdir cd $newdir echo Esecuzione del programma $REALBNAME chroot $newdir $REALBNAME $* exit 0
Si prega di notare che lo script funziona solo se si ha installato sul
proprio sistema il programma dialog
. Per usare virtexec basta
collegare con un link simbolico un programma a virtexec. Ad esempio:
ln -s /usr/local/bin/virtexec /usr/local/bin/virtpasswd ln -s /usr/local/bin/virtexec /usr/local/bin/virtvi ln -s /usr/local/bin/virtexec /usr/local/bin/virtpico ln -s /usr/local/bin/virtexec /usr/local/bin/virtemacs ln -s /usr/local/bin/virtexec /usr/local/bin/virtmailq
In questo modo quando si digiterà virtvi o virtpasswd o virtmailq si potrà editare un file con vi, cambiare la password di un utente o controllare la coda di posta sul proprio sistema virtuale. Si possono creare tanti link simbolici a virtexec quanti occorrono. Da notare che, se il programma richiede una libreria condivisa, essa deve trovarsi nel filesystem virtuale, così come il file binario stesso.
Di solito io installo tutti gli script in /usr/local/bin. Tutto ciò che non voglio compaia nel filesystem virtuale lo metto in /usr/local. Lo script non copia alcun file di /usr/local nel filesystem virtuale. È importante che ogni file che non deve trovarsi in tutti i filesystem virtuali venga rimosso. Ad esempio, sul mio sistema è installato ssh ed io non voglio che la chiave privata per il server sia disponibile su tutti i filesystem virtuali, così lo cancello da ciascun filesystem virtuale dopo aver lanciato virtfs. Oltre a questo, cambio anche resolv.conf e rimuovo per ragioni legali tutto ciò che contiene un riferimento ad un altro dominio. Ad esempio, /etc/hosts /etc/HOSTNAME.
Questi sono i programmi che ho collegato con un link simbolico a virtexec: