Il tuo server Nginx è esposto su internet. Ogni giorno arrivano scan, tentativi di brute force, bot che cercano vulnerabilità. Se non hai header di sicurezza, un minimo WAF e una protezione DDoS, non stai difendendo nulla. Lo vediamo quotidianamente nei progetti che ci arrivano: Nginx nudo, senza un singolo header di sicurezza, con limiti di richiesta disabilitati e nessuna regola per filtrare gli attacchi. Non serve un firewall enterprise: con Nginx e poche righe di config blocchi la maggior parte delle minacce comuni.
Noi, di Meteora Web, gestiamo server da anni. Veniamo dalla contabilità e dall'ERP, ma la sicurezza delle PMI italiane è sistematicamente sottovalutata. Abbiamo visto aziende perdere dati per un attacco che poteva essere bloccato con tre header. In questa guida ti mostriamo come impostare Nginx per difenderti senza spendere in hardware costoso.
Perché gli header di sicurezza Nginx sono la prima linea di difesa?
Gli header HTTP sono la risposta che il server invia al browser. Se non li configuri, il browser accetta qualsiasi comportamento, aprendo la porta a XSS, clickjacking, MIME sniffing e altre vulnerabilità. I principali header di sicurezza che devi impostare su Nginx sono:
Sponsored Protocol
- X-Content-Type-Options: nosniff — impedisce al browser di interpretare file MIME in modo diverso da quello dichiarato.
- X-Frame-Options: DENY — blocca il caricamento del sito in iframe, prevenendo clickjacking.
- X-XSS-Protection: 1; mode=block — attiva il filtro XSS integrato nei browser (obsoleto ma ancora utile).
- Referrer-Policy: strict-origin-when-cross-origin — limita le informazioni inviate nei referrer.
- Permissions-Policy — disabilita API del browser non necessarie (geolocalizzazione, fotocamera, etc.).
- Content-Security-Policy (CSP) — il più potente: controlla quali risorse possono essere caricate (script, style, immagini).
- Strict-Transport-Security (HSTS) — forza HTTPS.
Errore comune: configurare solo HSTS e CSP senza gli altri. Oppure copiare CSP da un template senza personalizzarlo, bloccando di fatto il funzionamento del sito.
Sponsored Protocol
Come configurare gli header di sicurezza su Nginx
Aggiungi queste direttive nel blocco http di nginx.conf o in un file separato incluso (security-headers.conf):
# Sicurezza header di base
add_header X-Content-Type-Options "nosniff" always;
add_header X-Frame-Options "DENY" always;
add_header X-XSS-Protection "1; mode=block" always;
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
# HSTS — solo se tutto il traffico è HTTPS
add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload" always;
# Permissions-Policy — disabilita tutto tranne ciò che serve
add_header Permissions-Policy "camera=(), microphone=(), geolocation=()" always;
# Content-Security-Policy — personalizzala per il tuo sito
add_header Content-Security-Policy "default-src 'self'; script-src 'self' https://analytics.example.com; style-src 'self' 'unsafe-inline'; img-src 'self' data:; font-src 'self'; connect-src 'self'" always;
Nota: always garantisce che l'header venga inviato anche per risposte di errore (4xx/5xx). Testa la configurazione con nginx -t e ricarica.
Sponsored Protocol
Puoi verificare gli header con curl:
curl -I https://iltuosito.it
Come impostare un WAF base con Nginx senza moduli costosi?
Il Web Application Firewall (WAF) filtra il traffico malevolo a livello applicativo. Non hai bisogno di un appliance da migliaia di euro: Nginx con il modulo ngx_http_rewrite_module e un set di regole Lua (con OpenResty) o le regole OWASP ModSecurity Core Rule Set ti danno una protezione solida.
Per un WAF base senza ModSecurity (che richiede compilazione da sorgente), puoi usare le direttive di Nginx per bloccare pattern comuni:
Bloccare SQL injection e XSS con mappe
Definisci una mappa nel blocco http:
# Mappa per bloccare query string sospette
map $query_string $block_injection {
default 0;
"~*(union.*select|insert.*into|drop.*table|
Attenzione: l'uso di if in location può essere problematico. In Nginx, if è spesso sconsigliato per logiche complesse, ma per semplici blocchi è accettabile. Alternativa: usare location ~ con regex sul request URI.
Per bloccare lo scanning di percorsi sensibili:
location ~* \.(env|git|svn|htaccess|bak|old)$ {
deny all;
return 403;
}
location ~* /(wp-admin|admin|phpmyadmin)/* {
# Se non hai bisogno di queste aree, blocca
deny all;
return 403;
}
Esempio reale: abbiamo un cliente che aveva il file .env accessibile pubblicamente. Con questa regola abbiamo bloccato l'accesso in 5 minuti.
Limitare metodi HTTP non necessari
Blocca PUT, DELETE, TRACE, CONNECT se non li usi:
if ($request_method !~ ^(GET|HEAD|POST)$) {
return 405;
}
Come limitare le richieste per mitigare attacchi DDoS su Nginx?
Il rate limiting di Nginx (modulo ngx_http_limit_req_module) è la tua arma più semplice contro DDoS di livello applicativo e brute force. Permette di limitare il numero di richieste al secondo per IP o sessione.
Configurare il rate limiting
Nel blocco http, definisci una zona di memoria:
# Zona per limitare le richieste (10 MB = circa 160.000 IP)
limit_req_zone $binary_remote_addr zone=ddos:10m rate=30r/s;
# Server block
server {
...
location / {
limit_req zone=ddos burst=50 nodelay;
...
}
}
- rate=30r/s: massimo 30 richieste al secondo per IP.
- burst=50: consente un picco di 50 richieste extra se arriva un breve scoppio.
- nodelay: non ritarda le richieste burst, le processa subito (aumenta il rischio di overflow).
Se un IP supera i limiti, Nginx risponde con 503 Service Unavailable. Puoi personalizzare la risposta:
limit_req_status 429; # Too Many Requests
Consiglio: per login e API (es. WooCommerce checkout) usa zone separate con rate più bassi (5-10 r/s).
Limitare connessioni simultanee
Il modulo limit_conn limita il numero di connessioni simultanee per IP:
limit_conn_zone $binary_remote_addr zone=conn:10m;
server {
location / {
limit_conn conn 10;
}
}
Utile per mitigare attacchi slowloris (che tengono aperte molte connessioni lentamente).
Proteggere il traffico UDP/HTTP2 con limiti più stringenti
Se usi HTTP/2, i client possono multiplexare molte richieste su una singola connessione. Nginx ha parametri specifici:
http2_max_concurrent_streams 128; # default 128
http2_recv_timeout 5s;
Per HTTP/1.1, abbassa i timeout di keepalive:
keepalive_timeout 15;
keepalive_requests 100;
Come testare e monitorare le configurazioni di sicurezza?
Non basta configurare: devi verificare che gli header siano effettivamente inviati e che il rate limiting funzioni. Ecco come fare.
Test con curl e strumenti online
- curl -I per vedere gli header.
- securityheaders.com (Scott Helme) — analisi degli header di sicurezza.
- Observatory di Mozilla — test completo di sicurezza web.
Simula un attacco DDoS con ab (Apache Bench) o wrk:
ab -n 1000 -c 100 https://iltuosito.it/
Se il rate limiting è attivo, dovresti vedere risposte 429/503 dopo le prime richieste.
Monitoraggio con i log di Nginx
Abilita il log delle richieste limitate:
log_format blocked '$remote_addr - $remote_user [$time_local] '
'"$request" $status $body_bytes_sent '
'"$http_referer" "$http_user_agent"';
server {
access_log /var/log/nginx/access.log;
# Log separato per richieste limitate
access_log /var/log/nginx/limited.log blocked if=$limit_req_status;
}
Analizza i log con grep per trovare pattern sospetti: grep ' 503 ' /var/log/nginx/access.log.
Domande frequenti sulla sicurezza Nginx
Devo usare ModSecurity o va bene solo Nginx nativo?
Nginx nativo con header, rate limiting e blocchi URI è sufficiente per la maggior parte delle PMI. Se hai esigenze di compliance (PCI-DSS) o gestisci dati sensibili, ModSecurity con le OWASP CRS è consigliato. Noi lo abbiamo integrato per clienti nel settore sanitario e finanziario.
Cosa fare se una regola WAF blocca il traffico legittimo?
Usa log dettagliati. In ModSecurity, abilita SecRuleEngine DetectionOnly per testare senza bloccare. Per Nginx nativo, sposta il blocco in una location specifica o usa geo per whitelistare IP fidati.
Cosa fare adesso
- Aggiungi gli header di sicurezza a
nginx.confricarica connginx -s reload. - Configura rate limiting per le route critiche (login, API, checkout).
- Blocca i percorsi sensibili (.env, admin, backup).
- Testa con curl e securityheaders.com.
- Monitora i log per identificare attacchi in corso.
Se vuoi una configurazione personalizzata per il tuo progetto, contattaci. Noi lo facciamo ogni giorno. Ricorda: un server Nginx senza protezione è come un negozio con la porta aperta.
Per approfondire la configurazione di Nginx in produzione, consulta la nostra guida pillar su Nginx e Web Server Configuration.