Creazione di un ambiente chroottato al quale accedervi tramite SSH
Inviata da
blackout
Chroot ('ch' da 'change', quindi 'change root') permette di impostare la radice del filesystem visibile da un utente in modo che sia diversa da quella che il kernel usa realmente (ovvero /). Questo tutorial ha lo scopo di spiegare come e' possibile 'chroottare' un utente che accede ad una macchina tramite SSH 'rinchiudendolo' in una cartella nella quale ci sara' lo stretto indispensabile allo svolgimento del suo compito. Lo scopo del tutorial non e' solo spiegare come fare cio, ma far capire come funziona il tutto, quindi spesso mi soffermero' a spiegare a fondo alcuni punti.
Innanzitutto occorre decidere cosa, l'utente chroottato, debba essere in grado di fare scegliendo una lista di programmi. Non conviene aggiungere roba se non ce ne sia l'effettivo bisogno, perche' piu' programmi e librerie vengono inseriti, maggiore e' la probabilita' che vengano usati fuori dal nostro controllo. Supponiamo di voler installare i seguenti programmi base: bash, cat, cp, ldconfig, ls, mkdir, mv, pwd, rm, uname, id, pwd, vi.
Ora passiamo alla creazione dell'ambiente. Creiamo una directory per il chroot:
Quindi pensiamo alle librerie. Per sapere di quali librerie hanno bisogno i nostri programmi possiamo usare il comando ldd. Per conoscere le dipendenze di ls ad esempio basta fare:
Se abbiamo scelto un bel po di programmi questo procedimento manuale risulta piuttosto lento, per cui converrebbe usare uno scriptino bash del tipo:
PROGRAMMI="/bin/bash /bin/ls /bin/mv /bin/cp /bin/cat /bin/mkdir /bin/pwd /bin/rm /usr/bin/id /usr/bin/pwd /usr/bin/vi /sbin/ldconfig" for prog in ${PROGRAMMI}; do cp ${prog} ./${prog} for lib in `ldd ${prog} 2>/dev/null|awk '{ print $3 }'`; do mkdir -p ./`dirname ${lib}` || die "errore nella creazione della directory" if [ -e ${lib} ]; then cp ${lib} ./${lib} || die "errore nella copia del file" fi done done
Copiati i programmi e le librerie, passiamo ad alcuni files necessari. Creiamo /etc/ld.so.conf e inseriamo i path delle nostre librerie:
Creiamo alcuni devices di cui molto spesso abbiamo bisogno e impostiamogli i permessi:
# mkdir dev/pts # test -b dev/null && mknod dev/null c 1 3 # test -b dev/zero && mknod dev/zero c 1 5 # test -b dev/tty && mknod dev/tty c 5 0 # test -b dev/pts/0 && mknod dev/pts/0 c 136 0 # test -b dev/pts/1 && mknod dev/pts/1 c 136 1 # chmod 666 dev/null dev/zero dev/tty dev/pts/*
Ora creiamo il nostro utente con useradd, supponiamo si chiami 'pluto'. Nella creazione quando andremo ad impostare la directory dell'utente dovremmo inserire una cosa del tipo "/home/chrooted/./home/pluto". Questo perche' quando l'utente si colleghera' usando ssh il nostro server openSSH avra' bisogno di sapere se l'utente va chroottato o meno da qualche parte. Trovando /./ capira' che deve chroottarlo li dentro. Ovviamente OpenSSH da solo non effettua il chroot, qualche riga piu' giu' vedremo come farglielo fare con una semplice patch.
Creato l'utente e' importante anche creare i files /etc/passwd e /etc/group, altrimenti il nostro ambiente non funzionera', inserendo all'interno solo la parte che ci interessa:
E' arrivato il momento di configurare OpenSSH per fargli fare il chroot quando pluto si colleghera' al nostro serverino. Per fare cio' e' stata creata un'apposita patch, non dovete fare altro che scaricare i sorgenti di openSSH, scaricare la patch per la corrispondente versione all'indirizzo http://chrootssh.sourceforge.net/download/, applicarla, e compilare OpenSSH:
# tar zxvf openssh-versione.tar.gz # cd openssh-versione # patch -p0 < /path_patch # ./configure --with-md5-passwords # make # make install
Il funzionamento della patch e' piuttosto semplice.. andando a vedere il .diff possiamo vedere quello che viene fatto quando un utente cerca di loggarsi.
Nel path della home dell utente viene cercato il famoso "/./"
Una volta ricompilato OpenSSH con la patch si puo' avviare sshd e testare se tutto e' andato nel verso giusto.
Innanzitutto testiamo l'ambiente con un chroot da locale:
# chroot /home/chrooted blackout@mastrogentoo / $ ls bin dev etc home lib sbin usr blackout@mastrogentoo / $ su -bash: su: command not found
Ok.. sembra funzionare a dovere
Ora prima di testare chroot con ssh facciamo alcuni aggiustamenti. Possiamo ad esempio creare il file /etc/profile e impostare la variabile PS1 per rendere la bash piu amichevole (altrimenti all'utente loggato uscira' un prompt del tipo "-bash-3.1$"). Oppure, cosa molto carina, possiamo ridefinirci il comando uname per far comparire quello che vogliamo noi quando verra' richiamato. Scriviamo il nostro uname facendogli accettare i parametri -a, -n e -r :
#include < stdio.h > int main(int argc, char **argv) { int c; if (argc==1) printf("SapientinOS\n"); else { while ((c=getopt(argc,argv,"ahnr")) != -1) { switch ( c ) { case 'a': printf("SapientinOS v.1.0\n"); break; case 'h': printf("Usage: uname [-a -h -n -r]\n"); printf("-a: print all information\n"); printf("-n: print the network node hostname\n"); printf("-r: print the kernel release\n"); break; case 'n': printf("chrooted\n"); break; case 'r': printf("v.1.0\n"); } } } }
Compiliamolo:
# gcc uname.c -o uname # ./uname SapientinOS # ./uname -a SapientinOS v.1.0 $ ./uname -n chrooted $ ./uname -r v.1.0 $ ./uname -h Usage: uname [-a -h -n -r] -a: print all information -n: print the network node hostname -r: print the kernel release