La guida definitiva per proteggere, rafforzare e migliorare le prestazioni del server Web Nginx
Sulla base delle cose meravigliose che hai sentito su Nginx, forse hai deciso di provarlo. Potrebbe esserti piaciuto così tanto che stai pensando di sostituire le tue installazioni Apache con Nginx dopo aver letto alcuni degli articoli sull'argomento che abbiamo pubblicato su questo sito.
Se è così, sono sicuro che accoglierai questa guida a braccia aperte poiché tratteremo 12 suggerimenti per aumentare la sicurezza dei tuoi server Nginx (che vanno dal mantenere Nginx aggiornato fino a utilizzando TLS e reindirizzando HTTP a HTTPS) e noterai che alcuni di essi sono molto simili a ciò che faresti con Apache.
Da non perdere:
13 Suggerimenti per la sicurezza e il rafforzamento del server Web Apache
25 trucchi Apache Htaccess per proteggere il server Web Apache
Ambiente di test Nginx
Utilizzeremo il seguente ambiente in questa guida:
- Debian GNU/Linux 8.1 (jessie).
-
Indirizzo IP: 192.168.0.25 (tecmintlovesnginx.com) e 192.168.0.26 (nginxmeanspower.com), come descritto nella sezione virtuale basata su IP sezione host in
- "Come configurare host virtuali basati su nome e IP (blocchi server) con Nginx"
Con questo in mente, cominciamo.
CONSIGLIO N.1: mantieni Nginx aggiornato
Al momento in cui scrivo, le ultime versioni di Nginx nei repository CentOS (in EPEL) e Debian sono 1.6.3 e 1.6.2-5 forte>, rispettivamente.
Da non perdere: installa l'ultima versione stabile di Nginx da repository e sorgente
Sebbene installare il software dai repository sia più semplice che compilare il programma dal codice sorgente, quest'ultima opzione presenta due vantaggi: 1) ti consente di creare moduli aggiuntivi in Nginx (come mod_security) e 2) fornirà sempre una versione più recente rispetto ai repository (1.9.9 ad oggi). Le note di rilascio sono sempre disponibili nel sito web di Nginx.
Da non perdere:
Proteggi Apache dagli attacchi di forza bruta e DDoS utilizzando Mod_Security e Mod_Evasive
CONSIGLIO N.2: rimuovi i moduli non necessari in Nginx
Per rimuovere esplicitamente i moduli da Nginx durante l'installazione dal sorgente, esegui:
./configure --without-module1 --without-module2 --without-module3
Per esempio:
./configure --without-http_dav_module --withouthttp_spdy_module
Come probabilmente indovinerai, la rimozione dei moduli da una precedente installazione di Nginx dal sorgente richiede l'esecuzione di una nuova compilazione.
Un avvertimento: le direttive di configurazione sono fornite dai moduli. Assicurati di non disabilitare un modulo che contiene una direttiva di cui avrai bisogno in futuro! Dovresti controllare i documenti nginx per l'elenco delle direttive disponibili in ciascun modulo prima di prendere una decisione sulla disabilitazione dei moduli.
SUGGERIMENTO n.3: disabilita la direttiva server_tokens in Nginx
La direttiva server_tokens
dice a Nginx di visualizzare la sua versione corrente nelle pagine di errore. Ciò non è auspicabile poiché non vuoi condividere tali informazioni con il mondo per prevenire attacchi al tuo server web causati da vulnerabilità note in quella specifica versione.
Per disabilitare la direttiva server_tokens
, impostala su off all'interno di un blocco server:
server {
listen 192.168.0.25:80;
server_tokens off;
server_name tecmintlovesnginx.com www.tecmintlovesnginx.com;
access_log /var/www/logs/tecmintlovesnginx.access.log;
error_log /var/www/logs/tecmintlovesnginx.error.log error;
root /var/www/tecmintlovesnginx.com/public_html;
index index.html index.htm;
}
Riavvia nginx e verifica le modifiche:
CONSIGLIO N.4: negare gli agenti utente HTTP in Nginx
Un agente utente HTTP è un software utilizzato per la negoziazione del contenuto su un server web. Ciò include anche bot e crawler malware che potrebbero compromettere le prestazioni del tuo server web sprecando risorse di sistema.
Per mantenere più facilmente l'elenco degli user agent indesiderati, creare un file (/etc/nginx/blockuseragents.rules
ad esempio) con il seguente contenuto:
map $http_user_agent $blockedagent {
default 0;
~*malicious 1;
~*bot 1;
~*backdoor 1;
~*crawler 1;
~*bandit 1;
}
Successivamente, inserisci la seguente riga prima della definizione del blocco del server:
include /etc/nginx/blockuseragents.rules;
E un'istruzione if per restituire una risposta 403 se la stringa dell'agente utente è nella lista nera definita sopra:
Riavvia nginx e a tutti gli user agent la cui stringa corrisponde a quanto sopra verrà bloccato l'accesso al tuo server web. Sostituisci 192.168.0.25 con l'IP del tuo server e sentiti libero di scegliere una stringa diversa per lo switch --user-agent
di wget:
wget http://192.168.0.25/index.html
wget --user-agent "I am a bandit haha" http://192.168.0.25/index.html
CONSIGLIO N.5: disabilita i metodi HTTP indesiderati in Nginx
Noti anche come verbi, i metodi HTTP indicano l'azione desiderata da intraprendere su una risorsa servita da Nginx. Per i siti Web e le applicazioni comuni, dovresti consentire solo GET, POST e HEAD e disabilitare tutti gli altri.
Per fare ciò, inserisci le seguenti righe all'interno di un blocco server. Una risposta HTTP 444 indica una risposta vuota e viene spesso utilizzata in Nginx per ingannare gli attacchi malware:
if ($request_method !~ ^(GET|HEAD|POST)$) {
return 444;
}
Per testare, utilizza curl per inviare una richiesta DELETE e confronta l'output con quello di quando invii un normale GET:
curl -X DELETE http://192.168.0.25/index.html
curl -X POST http://192.168.0.25/index.html
CONSIGLIO N.6: imposta i limiti della dimensione del buffer in Nginx
Per prevenire attacchi di buffer overflow contro il tuo server web Nginx, imposta le seguenti direttive in un file separato (crea un nuovo file denominato /etc/nginx/conf.d/buffer.conf
, ad esempio):
client_body_buffer_size 1k;
client_header_buffer_size 1k;
client_max_body_size 1k;
large_client_header_buffers 2 1k;
Le direttive di cui sopra garantiranno che le richieste effettuate al tuo server web non causino un overflow del buffer nel tuo sistema. Ancora una volta, fare riferimento alla documentazione per ulteriori dettagli su ciò che fa ciascuno di essi.
Quindi aggiungi una direttiva include nel file di configurazione:
include /etc/nginx/conf.d/*.conf;
CONSIGLIO N.7: Limita il numero di connessioni tramite IP in Nginx
Per limitare le connessioni per IP, utilizzare le direttive limit_conn_zone
(in un contesto http o almeno all'esterno del blocco server) e limit_conn (in un contesto http, blocco server o posizione).
Tuttavia, tieni presente che non vengono conteggiate tutte le connessioni, ma solo quelle la cui richiesta è stata elaborata dal server e l'intera intestazione della richiesta è stata letta.
Ad esempio, impostiamo il numero massimo di connessioni su 1
(sì, è un'esagerazione, ma in questo caso funzionerà perfettamente) in una zona denominata addr (puoi impostarlo su qualsiasi valore nome che preferisci):
limit_conn_zone $binary_remote_addr zone=addr:5m;
limit_conn addr 1;
Un semplice test con Apache Benchmark (Perform Nginx Load) in cui vengono effettuate 10
connessioni totali con 2
richieste simultanee ci aiuterà a dimostrare il nostro punto:
ab -n 10 -c 2 http://192.168.0.25/index.html
Per ulteriori dettagli vedere il suggerimento successivo.
CONSIGLIO N.8: Configura i log di monitoraggio per Nginx
Dopo aver eseguito il test descritto nel suggerimento precedente, controlla il registro degli errori definito per il blocco del server:
Potresti voler utilizzare grep per filtrare i log per le richieste non riuscite effettuate alla zona addr definita nel TIP #7:
grep addr /var/www/logs/tecmintlovesnginx.error.log --color=auto
Allo stesso modo, è possibile filtrare il registro degli accessi per informazioni di interesse, come ad esempio:
- IP del cliente
- Tipo di browser
- Tipo di richiesta HTTP
- Risorsa richiesta
- Blocco del server che risponde alla richiesta (utile se più host virtuali accedono allo stesso file).
E intraprendi le azioni appropriate se rilevi attività insolite o indesiderate.
CONSIGLIO N.9: Previeni il collegamento diretto delle immagini in Nginx
L'hotlinking delle immagini avviene quando una persona visualizza in un altro sito un'immagine ospitata sul tuo. Ciò provoca un aumento dell'utilizzo della larghezza di banda (per il quale paghi) mentre l'altra persona mostra felicemente l'immagine come se fosse di sua proprietà. In altre parole, per te è una doppia perdita.
Ad esempio, supponiamo che tu abbia una sottodirectory denominata img
all'interno del blocco del server in cui memorizzi tutte le immagini utilizzate in quell'host virtuale. Per impedire ad altri siti di utilizzare le tue immagini, dovrai inserire il seguente blocco di posizione all'interno della definizione del tuo host virtuale:
location /img/ {
valid_referers none blocked 192.168.0.25;
if ($invalid_referer) {
return 403;
}
}
Quindi modifica il file index.html
in ciascun host virtuale come segue:
192.168.0.26
192.168.0.25
<!DOCTYPE html>
<html>
<head>
<meta charset=”utf-8″>
<title>Nginx means power</title>
</head>
<body>
<h1>Nginx means power!</h1>
<img src=”http://192.168.0.25/img/nginx.png” />
</body>
</html>
<!DOCTYPE html>
<html>
<head>
<meta charset=”utf-8″>
<title>Tecmint loves Nginx</title>
</head>
<body>
<h1>Tecmint loves Nginx!</h1>
<img src=”img/nginx.png” />
</body>
</html>
Ora esplora ciascun sito e, come puoi vedere, l'immagine viene visualizzata correttamente in 192.168.0.25 ma viene sostituita da una risposta 403 in 192.168.0.26 forte>:
Tieni presente che questo suggerimento dipende dal browser remoto che invia il campo Referer.
SUGGERIMENTO n. 10: disabilita SSL e abilita solo TLS in Nginx
Quando possibile, fai tutto il possibile per evitare SSL in qualsiasi delle sue versioni e utilizza invece TLS. Il seguente ssl_protocols
dovrebbe essere inserito in un contesto server o http nel file host virtuale o è un file separato tramite una direttiva include (alcune persone usano un file chiamato ssl.conf
, ma dipende interamente da te):
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
Per esempio:
CONSIGLIO N.11: Crea certificati in Nginx
Prima di tutto, genera una chiave e un certificato. Sentiti libero di utilizzare un diverso tipo di crittografia se desideri:
openssl genrsa -aes256 -out tecmintlovesnginx.key 1024
openssl req -new -key tecmintlovesnginx.key -out tecmintlovesnginx.csr
cp tecmintlovesnginx.key tecmintlovesnginx.key.org
openssl rsa -in tecmintlovesnginx.key.org -out tecmintlovesnginx.key
openssl x509 -req -days 365 -in tecmintlovesnginx.csr -signkey tecmintlovesnginx.key -out tecmintlovesnginx.crt
Quindi aggiungi le seguenti righe all'interno di un blocco server separato in preparazione per il suggerimento successivo (reindirizzamento http --> https
) e sposta anche le direttive relative a SSL nel nuovo blocco:
server {
listen 192.168.0.25:443 ssl;
server_tokens off;
server_name tecmintlovesnginx.com www.tecmintlovesnginx.com;
root /var/www/tecmintlovesnginx.com/public_html;
ssl_certificate /etc/nginx/sites-enabled/certs/tecmintlovesnginx.crt;
ssl_certificate_key /etc/nginx/sites-enabled/certs/tecmintlovesnginx.key;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
}
Nel prossimo suggerimento verificheremo come il nostro sito ora utilizza un certificato autofirmato e TLS.
SUGGERIMENTO n.12: reindirizzare il traffico HTTP su HTTPS in Nginx
Aggiungi la seguente riga al primo blocco del server:
return 301 https://$server_name$request_uri;
La direttiva di cui sopra restituirà una risposta 301 (Moved permanentemente), che viene utilizzata per il reindirizzamento URL permanente ogni volta che viene effettuata una richiesta alla porta 80 del tuo host virtuale e reindirizzerà la richiesta al server bloccato da noi aggiunto nel suggerimento precedente.
L'immagine seguente mostra il reindirizzamento e conferma il fatto che stiamo utilizzando TLS 1.2 e AES-256 per la crittografia:
Riepilogo
In questo articolo abbiamo condiviso alcuni suggerimenti per proteggere il tuo server web Nginx. Ci piacerebbe sapere cosa ne pensi e, se hai altri suggerimenti che vorresti condividere con il resto della community, non esitare a farcelo sapere inviandoci una nota utilizzando il modulo dei commenti qui sotto.