Server Debian e Ubuntu per applicativi PHP: perché l'hardening è cruciale per la sicurezza dei software gestionali e e-commerce delle PMI
In un progetto per un'azienda del settore servizi digitali, l'e-commerce Laravel serviva centinaia di ordini al giorno su un VPS Debian 11 con configurazione di default: PHP-FPM girava come www-data con tutti i pool che condividevano lo stesso utente, open_basedir non era configurato, disable_functions era vuoto, Nginx esponeva la versione del server negli header di risposta, e nessun security header HTTP era impostato. Un attaccante che avesse sfruttato una qualsiasi vulnerabilità applicativa avrebbe ottenuto accesso a tutti i file del server, non solo a quelli dell'applicativo. Dopo l'hardening - pool PHP-FPM isolati, open_basedir restrittivo, funzioni pericolose disabilitate, security headers completi, permessi filesystem corretti - la superficie di attacco si è ridotta drasticamente. L'hardening a livello di sistema operativo (SSH, kernel, firewall, aggiornamenti automatici) è il prerequisito; questo articolo si concentra sullo strato applicativo specifico per PHP.
Quali sono le aree critiche di hardening per un server che ospita applicativi PHP?
Un server Debian o Ubuntu che ospita applicativi PHP presenta una superficie di attacco su tre livelli: il sistema operativo, lo stack web (Nginx/Apache + PHP-FPM) e l'applicativo stesso. L'hardening del sistema operativo - accesso SSH con chiavi Ed25519, firewall UFW/nftables, parametri kernel restrittivi, aggiornamenti automatici con unattended-upgrades - è trattato nella guida all'hardening dei server. Lo strato specifico per PHP riguarda la configurazione di PHP-FPM, il web server, i permessi del filesystem, e gli header HTTP di sicurezza - aree che spesso vengono ignorate perché "l'applicativo funziona" con la configurazione di default.
Il Verizon DBIR 2025 conferma che il 20% delle violazioni sfrutta vulnerabilità note in componenti non aggiornati o mal configurati. Per una PMI, un server con PHP-FPM in configurazione di default che ospita un gestionale con dati di clienti e fatturazione rappresenta un rischio concreto: una vulnerabilità in una dipendenza Composer, o un file di upload non validato, può dare all'attaccante accesso non solo all'applicativo, ma all'intero server.
PHP-FPM: isolamento dei pool e restrizioni di sicurezza
La configurazione di PHP-FPM è il punto di intervento con il maggiore impatto sulla sicurezza dello stack PHP. Le impostazioni critiche nel file pool del sito (tipicamente /etc/php/8.3/fpm/pool.d/site.conf):
[site]
user = site_user ; utente dedicato per ogni applicativo
group = site_group
listen = /run/php/php8.3-fpm-site.sock
listen.owner = www-data
listen.group = www-data
listen.mode = 0660
pm = dynamic
pm.max_children = 20
pm.start_servers = 5
pm.min_spare_servers = 3
pm.max_spare_servers = 10
php_admin_value[open_basedir] = /var/www/site/:/tmp/:/var/lib/php/sessions/
php_admin_value[disable_functions] = exec,passthru,shell_exec,system,proc_open,popen,curl_multi_exec,parse_ini_file,show_source,pcntl_exec
php_admin_value[upload_max_filesize] = 10M
php_admin_value[post_max_size] = 12M
php_admin_flag[expose_php] = off
security.limit_extensions = .phpI punti chiave: ogni applicativo ha un utente di sistema dedicato (non www-data condiviso), open_basedir limita l'accesso al filesystem alla sola directory dell'applicativo, disable_functions rimuove le funzioni che permettono esecuzione di comandi di sistema (adattare la lista in base alle reali necessità dell'applicativo - Laravel non usa exec per default, ma alcune dipendenze potrebbero), expose_php = off nasconde la versione PHP negli header, e security.limit_extensions impedisce l'esecuzione di file con estensioni diverse da .php.
Web server e security headers HTTP
Il web server (Nginx o Apache) è il componente direttamente esposto a Internet. La configurazione di sicurezza minima per Nginx include la rimozione dell'header di versione e l'implementazione dei security headers raccomandati da OWASP:
server {
listen 443 ssl http2;
server_name example.com;
server_tokens off; ; nasconde versione Nginx
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
add_header X-Frame-Options "SAMEORIGIN" always; ; previene clickjacking
add_header X-Content-Type-Options "nosniff" always; ; previene MIME sniffing
add_header X-XSS-Protection "0" always; ; disabilita filtro XSS legacy
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload" always;
add_header Permissions-Policy "camera=(), microphone=(), geolocation=()" always;
location ~ \.php$ {
fastcgi_pass unix:/run/php/php8.3-fpm-site.sock;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
fastcgi_hide_header X-Powered-By; ; nasconde header PHP
}
location ~ /\. { deny all; } ; blocca accesso a dotfiles
location ~ /vendor/ { deny all; } ; blocca accesso a vendor/
location ~ /storage/logs/ { deny all; } ; blocca accesso ai log Laravel
}Il Mozilla SSL Configuration Generator genera configurazioni TLS ottimali per Nginx e Apache in base al profilo di compatibilità scelto (Modern, Intermediate, Old). L'Observatory di Mozilla verifica la completezza dei security headers di un sito in produzione.
Per i permessi del filesystem, la regola base è: il web server legge, l'applicativo scrive solo dove necessario. I file dell'applicativo devono appartenere all'utente del pool PHP-FPM con permessi 644 per i file e 755 per le directory. La directory storage/ e bootstrap/cache/ (in Laravel) devono essere scrivibili dall'utente del pool ma non dal web server direttamente.
Audit di sicurezza e manutenzione continua
Verificare l'efficacia dell'hardening richiede strumenti specifici. Lynis analizza la configurazione del sistema e produce un indice di hardening con suggerimenti operativi - un server appena installato restituisce tipicamente un punteggio tra 50 e 60 su 100, dopo un hardening completo il target è superare 85. I CIS Benchmarks per Debian e Ubuntu definiscono centinaia di controlli specifici con livelli di priorità.
L'hardening non è un'operazione una tantum. Nuove vulnerabilità vengono scoperte, nuovi servizi vengono installati, configurazioni vengono modificate per debugging e non ripristinate. Un audit Lynis trimestrale è il minimo per mantenere lo stato di hardening nel tempo. L'osservabilità minima per applicazioni PHP legacy - logging strutturato, metriche operative e alert - è il complemento che trasforma l'hardening da difesa statica a difesa attiva. L'integrazione con il checklist di hardening NIS2 per Laravel e Symfony copre anche gli aspetti di compliance normativa.
L'hardening dello stack PHP è un investimento a rendimento asimmetrico: poche ore di configurazione prevengono incidenti che costano giorni di downtime e danni reputazionali. La sicurezza applicativa delle API REST del gestionale e l'hardening del server su cui gira sono due facce della stessa medaglia - nessuna delle due è sufficiente da sola. Per conoscere il mio approccio alla sicurezza dei sistemi Linux e degli applicativi PHP, visita la mia pagina professionale. Se i tuoi server non sono mai stati sottoposti a un audit di sicurezza specifico per lo stack PHP, contattami per una consulenza dedicata - partiamo dall'analisi della configurazione attuale.