
Le dritte per tenere al sicuro un server
Dalle regole di base per la configurazione ottimale, alla verifica dell'integrità del sistema con Tripwire. Ecco dove intervenire per dormire sempre sonni tranquilli
(pagina 1 di 4)
Prima di passare a parlare di sicurezza, vorremmo spendere
due parole per sfatare quello che sembra essere un pensiero
comune, secondo il quale, “Un sistema sicuro è quello
dotato di un software di protezione, opportunamente
configurato, in modo da riconoscere ed impedire ogni intrusione”.
In realtà, un tale software non esiste, né in ambiente GNU/Linux
né tanto meno su altri sistemi operativi. In teoria, la macchina inattaccabile
non esiste, come non esistono sistemi la cui probabilità
di violarne l'integrità è molto bassa e che perciò è possibile definire
sicuri. La sicurezza di un sistema, più che altro, può essere definita,
come il lavoro volto a valutare i rischi
di violazione della sua integrità, al fine di
adottare tutte le misure necessarie atte a
minimizzarli, senza rinunciare a quelle funzionalità
per le quali esso stesso è necessario.
Funzionalità di un sistema e sicurezza
sono infatti in antitesi.
 |
La struttura del file /etc/fstab per stabilire le opzioni di mount |
Faccio un esempio
estremo: stacchiamo il nostro server dalla
rete, spegniamolo e chiudiamolo in una cassaforte,
l'abbiamo reso inattaccabile, ma ne
abbiamo anche “spento” ogni funzionalità. Altro approccio comunemente
sbagliato è pensare solamente a proteggerci da Internet,
tralasciando, a volte del tutto, la sicurezza locale. A conferma di
ciò, supponiamo che una vulnerabilità nota di un applicativo possa
essere sfruttata per un attacco al sistema; se potessimo usare tale
vulnerabilità da remoto, la potremmo utilizzare, sicuramente,
anche da locale; tuttavia, il viceversa non è sempre vero, ad esempio:
un firewall potrebbe impedirci l'accesso al sistema e non potremmo
sfruttarne la vulnerabilità che resterebbe, comunque, raggiungibile
da console o dalla rete locale. In molti casi, infatti, gli attacchi
da remoto sfruttano compiacenti o negligenti manomissioni locali
al sistema di sicurezza. In questo articolo vogliamo evidenziare
le misure basilari per aumentare la sicurezza di un server che, in
generale, sono:
messa in sicurezza di tutti i servizi, soprattutto quelli di rete, in modo
da minimizzare i rischi di intrusione o di attacchi DoS (Denial of
Services);
- accorgimenti per aumentare la sicurezza intrinseca del sistema;
- verifica dell'integrità del sistema;
- recupero dei disastri;
- rintracciabilità degli accessi.
Tralasciamo il primo punto, in quanto dipende dalla corretta configurazione
delle applicazioni che forniscono i servizi (DNS, posta elettronica,
web server, ecc.) e concentriamoci sugli altri.
Aumentare la sicurezza intrinseca del server
I primi accorgimenti per aumentare la sicurezza intrinseca di un server
GNU/Linux possiamo deciderli già durante l'installazione. La prima
cosa che possiamo sfruttare è il partizionamento multiplo, in modo da
distribuire il file system su più porzioni (le partizioni appunto) del disco.
Questa strategia offre almeno quattro vantaggi:
- caricamento più veloce;
- backup selettivo;
- protezione contro la saturazione del file system;
- possibilità di controllare il modo in cui il file system viene montato.
Gli ultimi due punti sono quelli più importanti per la sicurezza. Cominciamo
ad analizzare il terzo. Consideriamo, ad esempio, le directory
/var, quella predefinita per contenere tutti i dati rapidamente variabili
(database, spooling, cache, log, ecc.). Se la sicurezza di una delle applicazioni
che gestisce questi dati venisse meno, potrebbe compromettere
il servizio da essa gestito, facendo, ad esempio, crescere i dati fino
a saturare l'intero file system che li contiene. Addirittura, se /var si trovasse
all'interno del file system radice (/), la sua saturazione comprometterebbe
la funzionalità dell'intero sistema; è consigliabile, dunque, montare
/var in una partizione separata dalla radice. Per ragioni analoghe
è preferibile montare su partizioni separate, anche le directory /tmp e
/home. Veniamo al punto due e consideriamo la directory /boot, quella
che contiene l'immagine del kernel e i file di configurazione del boot
loader Grub (LiLo ha il file di configurazione in /etc). Una volta installato
il sistema, a meno di una ricompilazione del kernel o di una riconfigurazione
di Grub, in nessun altro caso è necessaria una modifica ai file
in essa contenuti. Si può allora pensare di montare questa directory
con il file system in sola lettura la quale ci garantisce che i dati in essa contenuti
non possono essere modificati, neanche dall'utente root. Per ragioni
analoghe, possiamo montare in sola lettura anche il file system di
/usr, in quanto, esso contiene, applicativi, documentazione, i file include
del kernel e librerie statiche che raramente necessitano di modifiche
successive; comunque, qualora fosse necessario, come utente root,
si possono sempre smontare tali file system e rimontarli anche in modalità
scrivibile.
 |
Report generato da Tripwire dopo un controllo |
Questa operazione riduce leggermente la sicurezza,
ma lascia, in ogni caso, tracce nei log di sistema. Al file system di /usr/local,
in realtà applichiamo sempre le impostazioni di default (rw, suid, dev,
exec, auto, nouser, async), infatti, è solo necessario “staccarlo” dal file
system di /usr. La directory /usr/local ha, infatti, la stessa struttura di /usr
e può essere utilizzata al suo posto per l'installazione di nuove applicazioni.
Un altro vantaggio nell’utilizzare opzioni di mount selettivo è la
protezione dai programmi SUID. Per trovare tutti i programmi SUID
su un sistema GNU/Linux eseguiamo il comando seguente:
find / -perm +4000
Un’eventuale vulnerabilità di un programma SUID potrebbe facilmente
essere utilizzata per acquisire i privilegi di root. Le strategie per difendersi
da tali minacce sono essenzialmente riconducibili ai seguenti
accorgimenti:
cambiate i permessi SUID ai programmi che non ne hanno strettamente
bisogno;
disinstallate i programmi SUID che su un server sono inutili (ad
esempio i giochi);
montate le directory scrivibili dagli utenti con l'opzione nosuid (ad
esempio /tmp, /home).
Per concretizzare questi accorgimenti dobbiamo scriverli in /etc/fstab. Nella prima immagine di questo articolo abbiamo un esempio di questo file tutti gli accorgimenti
analizzati finora.
 |
Tripwire scopre che il file/etc/rc.d/rc.sysinit è stato modificato |
Finita l'installazione e configurata la struttura del file
system, proseguiamo il lavoro di messa in sicurezza del nostro server:
disabilitiamo, nel BIOS, il boot da tutti i dispositivi tranne, ovviamente,
quello necessario ad avviare il nostro sistema operativo e proteggiamone
le impostazioni con la password di setup; quindi, impediamo
agli utenti normali di effettuare lo shutdown del sistema e di arrestare
i servizi. Per impedire agli utenti il fermo macchina è sufficiente cambiare
i permessi all’eseguibile /sbin/halt: chmod o-x halt. Questo, però,
non è sufficiente per impedirne anche il riavvio; in tal caso occorre disabilitare
(o modificare) la funzione della combinazione dei tasti
Alt+Ctrl+Canc nel file /etc/inittab. Per farlo, apriamo questo file e
commentiamo (simbolo # all'inizio della stringa) la riga seguente:
ca:12345:ctrlaltdel:/sbin/shutdown -t1 -a -r now
Per impedire, invece, agli utenti di arrestare i servizi (cosa che è possibile
fare su molte distribuzioni), nei sistemi basati sullo standard System V (quasi tutte), basta portarsi nella directory /etc/rc.d ed eseguire
quanto segue:
chmod o-x rc.local rc.sysinit
cd init.d
chmod o-x *
Nei sistemi tipo BSD (Slackware e derivati) basta eseguire il comando
riportato nell'ultima riga, nella directory /etc/rc.d. Prima di concludere
questa parte suggeriamo due accorgimenti, legati essenzialmente al
buon senso: quando si installa un software controlliamone sempre
l'integrità e installiamo solo i pacchetti che effettivamente ci occorrono.
Il fatto che un software sia Open Source non ci assicura che non vi siano
sorgenti manomessi (cosa spesso data per scontato). Quando ci occorrono
i sorgenti di un pacchetto visitiamo sempre il sito ufficiale del
gruppo di sviluppo; troveremo sempre un riferimento ai mirror ufficiali
e soprattutto le firme digitali (spesso nella forma di checksum md5)
per poter controllare l'integrità del software. Per quanto riguarda il secondo
punto e su come questo è legato alla sicurezza, possiamo sintetizzarlo
con una battuta di Henry Ford che riferendosi alla semplicità con
cui era fabbricata la Ford T, disse: “Quello che non c'è non si rompe”.
Cosa sono Suid e Sgid?
Permessi speciali da usare con cautela
Tra i permessi che si possono attribuire ad un file, ne esistono
due speciali: SUID che definisce l'ID dell'utente
(chmod u+s file) e SGID quello del gruppo (chmod g+s file). I
programmi che hanno permessi SUID o SGID sono speciali
perché i permessi del loro proprietario, o del gruppo, sono
mantenuti anche quando altri utenti li eseguono; perciò, un
programma settato sulla root come SUID funzionerà sempre
come root, chiunque lo usi.
Verifica dell'integrità del sistema
 |
• L'oggetto rc.sysinit conservato nel database di Tripwire |
L'uso di file system non scrivibili ha lo scopo di impedire
l'introduzione
di codice e programmi pericolosi. Immaginate, ad esempio, che qualcuno
sostituisca il comando /bin/login con una versione modificata che oltre
a svolgere l'operazione di login scriva le password in un file
nascosto.
Su un file system non scrivibile tali operazioni non sono possibili.
Tuttavia
non possiamo montare tutto il file system in sola lettura e non
sempre possiamo impedire agli utenti di accedere in scrittura a
determinate
directory, semplicemente per non ridurre troppo le funzionalità
del sistema. Per questo e per altri motivi è necessaria una procedura
che ci consenta di verificare l'integrità del sistema, periodicamente o
in situazioni di sospettata manomissione. Questa procedura si basa su
un passaggio fondamentale: “fotografare” il sistema subito dopo
l'installazione ed ogni volta che apportiamo delle modifiche ad esso.
Il
metodo più affidabile per scoprire programmi manomessi, o più in
generale codice non autorizzato, è quello della “riconciliazione degli
oggetti”:
un processo per mezzo del quale gli oggetti (tutto quello che è
presente
nel sistema: file, directory, device o altro) vengono confrontati
con una loro copia, sicuramente “integra”, creata in precedenza. In
questo ci può aiutare un applicativo appositamente creato che svolge in
modo egregio tale compito: Tripwire, un IDS (Intrusion Detection
System) che utilizza il metodo appena descritto per controllare lo
stato
del sistema, o parte di esso, rispetto ad uno stato di partenza (o
baseline). Esistono due versioni di Tripwire, una commerciale ed
un'altra
Open Source.
 |
• Aggiornamento del database di Tripwire |
Dopo averlo installato e configurato, per poterlo
utilizzare,
è necessario creare il database dove saranno introdotte tutte
le voci riguardanti gli oggetti da controllare, secondo le indicazioni
contenute nel file tw.pol. Il comando da utilizzare è tripwire --
init. A questo punto, Tripwire ci chiederà di inserire la passphrase(
frase di accesso) locale e successivamente procederà alla creazione
del database, al termine della quale otterremo un'istantanea” del
file system da poter utilizzare tutte le volte che vogliamo effettuare
verifiche di integrità del sistema. Quando occorre verificare se sono
state effettuate modifiche, aggiunte o cancellazioni di oggetti, il
comando
da utilizzare è tripwire --check. Dopo il controllo il programma
mostra tutte le informazioni raccolte, allo stesso tempo
tempo
le registra in un report crittografato all'interno della directory
specificata nel file di configurazione tw.cfg. Inoltre, Tripwire, è in
grado di inviare una mail ad uno o più indirizzi specificati nel file
di configurazione
tw.pol.
Vediamo un esempio: supponiamo di sospettare che lo script di sistema
/etc/rc.d/rc.sysinit sia stato modificato. A tal proposito eseguiamo
tripwire --check /etc/rc.d/rc.sysinit
l’output prodotto ci informa che rc.sysinit è stato, effettivamente, modificato da qualcuno. Per esaminare successivamente il report possiamo usare il comando seguente:
twprint -m r --twrfile
/usr/local//lib/tripwire/report/nome_del_report.twr
Le opzioni -m ed r indicano a Tripwire di decrittografare il report,
mentre
l'opzione --twrfile indica il report da visualizzare. Per visualizzare
un oggetto nel database, ad esempio rc.sysinit, è possibile usare il
comando
seguente:
twprint -m d /etc/rc.d/rc.sysinit
Quando eseguiamo una
verifica dell'integrità del sistema, può accadere che vengano segnalate
violazioni imputabili ad operazioni legittime a noi note. In questi
casi occorre
aggiornare semplicemente il database di Tripwire in modo che
non vengano più riproposte; per farlo dobbiamo estrapolare le
“violazioni
consentite” dal report con il comando seguente:
tripwire -m u --twrfile
/usr/local/lib/tripwire/report/nome_del_report.twr
Il comando precedente aprirà il resoconto prodotto da Tripwire con
l'editor specificato nel file tw.cfg. Tutti gli aggiornamenti proposti
per
il database di Tripwire sono contrassegnati con una [x] che precede il
nome dell'oggetto. È importante aggiornare solo le
violazioni
autorizzate; per escluderne una dall'aggiornamento è sufficiente
rimuovere la x. Salviamo il report, inseriamo la local keyfile
passphrase
e l’aggiornamento è completo. È evidente che questo strumento è
fondamentale per la sicurezza di un server. Tuttavia, affinché diventi
veramente efficace, bisogna proteggere il database delle impronte
digitali.
Una buona strategia potrebbe essere quella di trasferirne una copia
su supporti non riscrivibili (come ad esempio alcuni tipi di CD e
DVD) opportunamente custoditi in luoghi sicuri. Altro aspetto
fondamentale,
è una buona politica dei backup. Qualunque strategia volessimo
usare a riguardo, è fondamentale includere sempre backup completi
del sistema da archiviare in luoghi sicuri, da effettuare ogni volta
e prima di installazioni o di interventi sulla configurazione del
server, in
modo da avere sempre a portata di mano un archivio delle configurazioni
precedenti. Non solo i backup ci proteggono da disastri di qualunque
natura, ma in caso di violazione impropria di alcuni oggetti del
sistema, l'unico modo per rimediare ai danni subiti è ripristinare una
copia precedente di essi. Quando operiamo su grandi sistemi e non
vogliamo
(o non possiamo) spendere grandi somme di denaro per archiviare
tutte le copie complete, allora, prima di effettuare il backup facciamo
una verifica dell'integrità del sistema, in modo da essere certi di
non sovrascrivere una copia integra con una che contiene oggetti
compromessi.
Inoltre, attrezziamoci, comunque, per conservare almeno
due copie integrali del sistema, non fidiamoci mai di una sola, in
quanto,
se all'atto del ripristino, dovesse risultare danneggiata ci
ritroveremo
senza una sorgente di oggetti integri e le uniche soluzioni sarebbero
reinstallare i pacchetti contenenti gli oggetti compromessi o l'intero
sistema. A questo punto non ci resta che schedulare l'esecuzione del
controllo d’integrità, in modo che vengano effettuate automaticamente
verifiche periodiche.