Hardening Debian Linux LAMP Servers

30/06/2006 by - Apache, Linux, Mysql, Php

Hardening Debian Linux Web PHP Servers

L’aspetto più rilevante nella configurazione di un web server è senza dubbio la completa collaborazione fra sviluppatori di codice e sistemisti (gli sviluppatori grafici non hanno voce in questione 😛 )

Inutile preparare una macchina dalla configurazione hardware ottimale con RAID 5 o 10 su 4 dischi SCSI e un firewall di 3000 righe per scoprire di lunedì mattina che il DB è vuoto. Motivo? Account di amministratore settato con USER: “Admin” e Password indovinate un po’… 😐 … “Admin” ovvio!

Sprecare quel paio d’ore in più a chiacchierare con lo sviluppatore non è male, ma cosa buona e giusta! Prendetevi tutto il tempo per rendere stabili e congruenti le modifiche e non abbiate nè fretta nè timore di far osservare qualche policy di sicurezza in più al vostro collega cresciuto su manuali che danno per scontato il non effettuare input sanitazing.

Per la preparazione del kernel (personalmente pendo dalla parte degli amanti di conf monolitiche con le giuste patch applicate vedi grsecurity) penso di scrivere qualcosina più avanti.

Security is a process, not a result (sia chiaro in partenza…)

Security a livello di sistema

Questo è il compito del sistemista … effettivamente c’è bisogno di parecchio tempo per raffinare la tecnica e centralizzare le politiche in un layer di controllo non troppo invasivo.

Prima di iniziare a stilare qualche linea di codice e iniziare a riconfigurare mezza /etc è un consiglio confrontarsi con lo sviluppatore. Bisogna tener conto delle effettive esigenze del developer: upload (accesso ftp per lo spostamento di file) , directory con permessi di scrittura lato utenza apache (chmod www-data dir ), parametri dimensionali (massimo tempo di esecuzione script), necessità di reloadare servizi (accesso ssh), accettare traffico da e verso determinati ip e porte.

Il bello della configurazione di un server è che ogni volta che ne andrete a creare uno nuovo vi verrà sempre più naturale orientarlo verso sicurezza e performance, ovviamente se avete voglia di imparare e tenervi aggiornati!

Stilata la lista delle necessità dello sviluppatore iniziamo a modificare le configurazioni più “critiche”.

Dividiamo in due rami il nostro compito: network security e file system security, iniziamo a leggere le specifiche e trarre le conclusioni. Il server web ospiterà un cms php/mysql, dovrà essere permesso l’invio di mail, il webmaster dovrà modificare i file della htdocs, e restartare o stoppare apache e mysql. Installiamo una LAMP e phpmyadmin per l’amministrazione del DB, qmail per l’invio delle mail, il demone ssh per permettere “ftp” over SSH (quindi niente proftpd o simili) e la gestione dei demoni (via sudo darete la possibilità all’utente webmaster di compiere quelle determinate operazioni…)

Network security

#netstat -l -n -p -t -u -w
Active Internet connections (only servers)
Proto  Local Address         PID/Program name
tcp    127.0.0.1:3306        31920/mysqld
tcp    192.168.168.168:80    15695/apache
tcp    192.168.168.168:22    26850/sshd
tcp    127.0.0.1:25          15809/tcpserver

L’elenco delle porte in ascolto sul server, comprende i vari protocolli ma esclude i socket unix (canali di comunicazione fra ad esempio apache e mysql) e qualche colonna poco utile a fini didattici.

#nmap -sS 192.168.168.168

PORT   STATE SERVICE
22/tcp open  ssh
80/tcp open  http

Nmap finished: 1 IP address (1 host up) scanned in 0.578 seconds

Perfetto (siamo ancora sprovvisti di firewall) vengono riconosciute da nmap le porte dei servizi che saranno contattabili dal segmento pubblico e nn solo da localhost: apache sulla 80 e ssh sulla 22

Come fare a disabilitare i servizi di default? Semplicemente commentate le entry relative nei file di configurazione sotto /etc e sotto /etc/init.d per i file di configurazione come quello di qmail. E’ inutile lasciare servizi che non dovranno essere raggiungibili dal mondo esterno in ascolto. Meglio bindarli su localhost. Su Debian date uno sguardo /etc/inetd.conf /etc/init.d/* e /etc/default

IPTABLES

Per completare la nostra configurazione di rete non rimane che scrivere un piccolo firewall da mettere sulla macchina, che rimarrà cmq. in dmz dietro a un altro firewall un po’ più corposo. La politica che preferisco è quella del DROP, check del set di regole e in caso di pacchetto non contemplato loggo e droppo. Loggo cmq. tutti i tentativi di accesso verso ssh, molti cambiano porta per l’accesso ssh ( sempre molta fantasia.. 220,2200,222,2222), tuttavia non sento questa necessità perchè permetto l’accesso solo da determinati IP o classi se dinamici.

#policy in drop
/sbin/iptables -t filter -P INPUT DROP

#loggo tentativi ssh
/sbin/iptables -t filter -A INPUT -p tcp -m state –state NEW –dport 22 -j LOG –log-prefix ***SSH*** –log-level ERR

#permetto in input connessioni già “fidate”
/sbin/iptables -t filter -A INPUT -m state –state ESTABLISHED,RELATED -j ACCEPT

#permetto http da tutti
/sbin/iptables -t filter -A INPUT -p tcp –dport 80 -j ACCEPT

#permetto ssh da client fidati
/sbin/iptables -t filter -A INPUT -s 192.168.168.169 -p tcp –dport 22 -j ACCEPT
/sbin/iptables -t filter -A INPUT -s 45.98.45.98 -p tcp –dport 22 -j ACCEPT

#loggo input con dest non ok
/sbin/iptables -t filter -A INPUT -j LOG –log-level ERR –log-prefix “input: ”

#e droppo
/sbin/iptables -t filter -A INPUT -j DROP

Il firewall da mettere direttamente sul server è abbastanza completo, megli lavorare più massicciamente sul firewall con eth con ip esterno, anche per effettuare analisi sulla rete senza dover disattivarlo ogni volta.
Per salvare le nostre regole

#iptables-save > /root/fw
#chmod 600 /root/fw

ed eventuale restore

iptables-restore < /root/fw oppure crearsi uno script bash iniziando con #!/bin/sh Per quanto riguarda SSH modificate le seguenti entries nelfile /etc/ssh/sshd_config

Port 22
ListenAddress 192.168.168.168
Protocol 2
PermitRootLogin no
AllowUsers texilee webmaster

e reload

/etc/init.d/ssh restart

File System
E’ cosa buona non creare una sola partizione / ma suddividere in base alle esigenze il FS in diverse partizioni e montarle in maniera diversa. Le più critiche sono la /tmp e la /var, se nella prima è di moda parcheggiarci rootkit nella seconda il problema può essere causa di DOS per log “impazziti” che nel giro di poco tempo riempiono il filesystem. Appurato che non lanceremo nulla dalla /tmp poichè i nostri script e binari risiedono da tutt’altra parte possiamo impedire a livello di filesystem l’esecuzione di codice dall’interno di tmp modificando il file /etc/fstab in questa maniera

/dev/hda2 /tmp ext3 nodev,nosuid, noexec 0 0

Può capitare (tipico esempio uno dei centinaia bachi di tipo “esecuzione di codice arbitrario” di prodotti php open source) che un attaccante ti sfondi la macchina e parcheggi nella /tmp il suo simpatico rootkit, ti hanno appena modificato ls e netstat e non te ne puoi accorgere se non facendo delle analisi da un’altra macchina messa in eth promiscous mode… tornano utili un paio di tools: samhain chkrootkit

Samhain crea un database con “firme” di file di sistema presenti al momento della esecuzione del tool, record contenenti valori quali data dimensione inode. Il demone controlla periodicamente l’integrità dei file sul FS con le informazioni contenute nel suo DB ed in caso di incongruenza si occupa di mandare una mail all’indirizzo specificato nel file di configurazione. Su Debian apt-get install samhain chkrootkit , i file di configurazione come al solito sotto /etc.

Per concludere trovo estremamente interessante costruire qualche script bash per tracciare quelle situazioni di gravità (disco pieno, troppe connessioni dallo stesso ip, carico di lavoro troppo elevato… argomento di prossimi post ) e l’utilizzo di atsar (apt-get install atsar) per avere uno storico del carico di lavoro e poter rintracciare con facilità nei log i motivi di “sbalzi” particolarmente elevati di carico.



Lascia un commento

Questo sito usa Akismet per ridurre lo spam. Scopri come i tuoi dati vengono elaborati.