Avanti Indietro Indice

4. Gli script di shell

4.1 Virtfs

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

4.2 Virtexec

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.

4.3 Note

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:


Avanti Indietro Indice