20.5. Sicurezza come interazione con il sistema operativo ospitante

Squid è un server di tipo "demone" che viene eseguito in ambito LAN o WAN e, in quanto tale, naturalmente può essere potenzialmente soggetto a connessioni anche da parte di utenti malintenzionati. E' quindi buona prassi fare una corretta configurazione del sistema ospitante al fine di evitare eventuali problematiche di sicurezza.

20.5.1. Sistemi UNIX®, cloni e BSD

Nei sistemi UNIX® la prima semplice ed immediata procedura per proteggere il sistema è una corretta gestione dei permessi; a riguardo la user guide di Squid è alquanto chiara (cfr. http://squid-docs.sourceforge.net/latest/html/c911.html#AEN913), noi ci limiteremo a riportare solo le voci principali. Prima di tutto puntualizziamo sul fatto che Squid accede alla cache utilizzando un utente che fa parte un gruppo ben definito, vale la pena quindi creare un utente e un gruppo che abbiano le credenziali necessarie che garantiscano la sicurezza del corretto funzionamento, i TAG da indicare nel file di configurazione squid.conf sono i seguenti

cache_effective_user squid 
cache_effective_group squidadm 
   

Impostato l'utente ed il gruppo, sarà necessario propagare le credenziali a tutta la struttura di directory in cui squid "vive", tale pratica è necessaria per il corretto funzionamento del sistema. Nell'esempio che vi sottoponiamo abbiamo creato un gruppo "squidadm", l'utente che fa parte di questo gruppo è "squid", il proxy server Squid è stato installato nel prefix /usr/squid/, quindi dovremo necessariamente impostare i seguenti permessi

% chown squid:squidadm /usr/squid 
% chmod 755 /usr/squid 
% chown squid:squidadm /usr/squid/bin/. 
% chown squid:squidadm /usr/squid/bin/* 
% chmod 755 /usr/squid/bin/. 
% chmod 755 /usr/squid/bin/* 
% chmod 2775 /usr/squid/etc/. 
% chown squid:squidadm /usr/squid/etc/* 
% chown squid:squidadm /usr/squid/etc/. 
% chown squid:squidadm /usr/squid/var/logs/ 
% chmod 770 /usr/squid/var/logs/ 
% chown squid:squidadm /usr/squid/var/cache 
% chmod 770 /usr/squid/var/cache 
   

Una volta impostati i permessi, facciamo partire squid ricordandosi di generare le sottodirectory di gestione della cache (comando squid -z per il dettaglio cfr. capitolo sull'avvio di Squid) utilizzando un utente non privilegiato (non utilizziamo l'utente root per capirci) eseguendo il comando

% /usr/local/bin/setuidgid squid /usr/squid/sbin/squid -D -N -d 10 
   

Nota: setuidgid è una applicazione inclusa nel pacchetto daemontools realizzato da d.j. Bernstein.

Nell'esempio abbiamo deciso di far partire Squid con utente non privilegiato poichè ogni demone di rete che gira come root rappresenta comunque una problematica per la sicurezza, l'operazione è stata eseguita nonostante il server Squid abbia una struttura per la quale il processo child, che usa comunque un utente non privilegiato (squid), si occuperà di servire le richieste.

20.5.2. La modalità chroot() nei sistemi UNIX® cloni o BSD

Analizziamo ora un'altra possibilità che ci viene offerta dai sistemi UNIX® per corazzare il servizio Squid. Tale possibilità viene offerta dalla funzione chroot()[1]. Questa funzione consente a un comando (nel nostro caso proprio Squid) di essere confinato in un environment (o gabbia) per l'occasione da noi predisposto all'interno del sistema stesso.

Nel malaugurato caso in cui un malintenzionato riesca ad ottenere una "shell" sul sistema, sfruttando un improbabile bug di Squid, grazie alla funzione chroot(), lo stesso rimarrà chiuso nella gabbia da noi preparata, grazie alla gabbia il malintenzionato non potrà effettuare danni.

E' necessario rammentare che esistono alcuni metodi per irrompere fuori dalla gabbia di chroot() (cfr. http://www.bpfh.net/simes/computing/chroot-break.html) ma se stiamo un pò attenti, possiamo rendere anche questo raggiro molto difficile.

Sinceramente l'autore di questo paragrafo, pensa che non sia strettamente necessario porre Squid in un ambiente chrootato, ma visto che la sicurezza non è mai troppa e la paranoia regna sovrana porremo il nostro Squid in una gabbia blindata.

Nota: la sicurezza paranoica è un temine che è stato coniato dall'autore del libro nel momento in cui si teorizzava sull'inserimento di questo paragrafo.

Passando alla parte operativa prima di tutto dobbiamo creare il nostro sistema "gabbia" dove andremo a chiudere il processo Squid, quindi avremo bisogno di creare una directory per metterci dentro tutto quello che serve a Squid per funzionare

% mkdir /chroot 
% cd /chroot 
   

creazione delle directory di sistema

% mkdir -p usr/bin usr/lib lib squidhome etc 
% ln -s usr/bin/ bin 
   

copiamo le librerie necessarie nell'environment (la questione è variabile a secondo dei Sistemi utilizzati)

% cp -pi /lib/lib/libtermcap* /lib/ld-linux.so.2 /lib/libc.so.6 lib/ 
% cp -pi /lib/libnss* lib/ 
   

mettiamoci dentro un pò di binaries necessari

% cp -pi /bin/cat /bin/sh bin/ 
   

proviamo la nostra chroot()

% chroot /chroot /bin/cat --help 
   

Creiamo adesso un utente ed un gruppo che esisteranno solo all'interno del nostro ambiente

% cd /chroot 
% touch etc/passwd etc/shadow etc/group 
% chmod 400 etc/shadow 
% echo 'squidadm:x:888:' > etc/group 
% echo 'squid:*:10882:-1:99999:-1:-1:-1:134537804' > etc/shadow 
% echo 'squid:x:888:888:Web Account:/squidhome:/usr/bin/False' > etc/passwd 
   

creiamo una shell fittizia

% echo 'int main(int argc, char *argv[]) {return(1);}' \
> /tmp/False.c && gcc -O3 /tmp/False.c -o /chroot/usr/bin/False 
   

Facciamo in modo che i binaries siano SOLO eseguibili

% chmod 111 usr/bin/* 
   

Creiamo i file per le risoluzioni (N.B. se usiamo l'auth winbindd conviene inserire anche nss_winbind)

----/chroot/etc/nsswitch.conf ---------------- 
passwd: files 
shadow: files 
group: files 
hosts: files dns 
---------------------------------------------- 
----/chroot/etc/resolv.conf ------------------ 
domain mydomain.com 
nameserver dnsaddress 
---------------------------------------------- 
----/chroot/etc/hosts ------------------------ 
127.0.0.1 localhost loopback my.add.re.ss nomemio hostname.mydomain.com 
---------------------------------------------- 
   

Compiliamo ed installiamo Squid

% mkdir /chroot/squid 
% ln -s /chroot/squid /squid 
% ./configure --prefix=/squid --enable-storeio="diskd ufs" \
--enable-snmp --enable-underscores
% gmake all && gmake install && ldconfig && sync 
   

Una volta fatto questo dovremo essere quasi pronti per far funzionare squid, ci dobbiamo soltanto armare delle utility strace ed ldd per vedere COSA serve a squid per funzionare correttamente, quindi

% ldd /squid/bin/squid 
        libcrypt.so.1 => /lib/libcrypt.so.1 (0x00136000) 
        libpthread.so.0 => /lib/libpthread.so.0 (0x00163000) 
        libm.so.6 => /lib/libm.so.6 (0x00179000) 
        libresolv.so.2 => /lib/libresolv.so.2 (0x0019b000) 
        libnsl.so.1 => /lib/libnsl.so.1 (0x001ac000) 
        libc.so.6 => /lib/libc.so.6 (0x001c1000) 
        /lib/ld-linux.so.2 => /lib/ld-linux.so.2 (0x00110000)
% ldd /squid/bin/client 
        libm.so.6 => /lib/libm.so.6 (0x00136000) 
        libresolv.so.2 => /lib/libresolv.so.2 (0x00158000) 
        libnsl.so.1 => /lib/libnsl.so.1 (0x00169000) 
        libc.so.6 => /lib/libc.so.6 (0x0017e000) 
        /lib/ld-linux.so.2 => /lib/ld-linux.so.2 (0x00110000) 
% ldd /squid/libexec/squid/diskd 
        libm.so.6 => /lib/libm.so.6 (0x00136000) 
        libc.so.6 => /lib/libc.so.6 (0x00158000) 
        /lib/ld-linux.so.2 => /lib/ld-linux.so.2 (0x00110000) 
% ldd /squid/libexec/squid/unlinkd 
        libc.so.6 => /lib/libc.so.6 (0x00136000) 
        /lib/ld-linux.so.2 => /lib/ld-linux.so.2 (0x00110000) 
   

questo output ci mostra dove Squid (ed altri programmi vitali) cercheranno le librerie (shared objects) necessarie. A questo punto noi dobbiamo ricreare lo stesso path nel nostro ambiente e copiarvi la libreria. Un esempio semplice

libpthread.so.0 => /lib/libpthread.so.0 
   

questo vuol dire che Squid proverà a linkare libpthread.so.0 cercandola dentro /lib. Quindi, noi abbiamo chrootato dentro /chroot, non dovremo far altro che copiare la libreria dove Squid la cercherà

/chroot/lib/libpthread.so.0 
% cp -pi /lib/libpthread.so.0 /chroot/lib/ 
   

continuamo così per tutto il resto dell'output degli ldd. Ora, se abbiamo configurato tutto correttamente permessi directory etc. (cfr. l'inizio del paragrafo) tutto dovrebbe funzionare, possiamo far partire Squid con il comando

% /usr/local/bin/setuidgid squid '/usr/sbin/chroot/chroot /squid/bin/squid -D -d 1' 
   

se dovessero venir fuori problemi o errori provare prima a far partire Squid normalmente senza chroot(). Poi ricontrollare tutto con ldd, al massimo utilizzare l'utility "strace" per un miglior debugging.

Note

[1]

Il termine chrooting definisce un processo con il quale viene confinata una applicazione in una parte speciale del filesystem che prende il nome di jail (gabbia). Quando viene eseguita una chiamata chroot() l'applicazione non può più accedere ai files che si trovano al difuori della gabbia. Solo l'utente root può scappare dalla gabbia, infatti una parte vitale del processo di chroot() è proprio quella di non concedere i permessi dell'utente root