Cosa è NGINX ed a cosa serve

NGINX: le sue origini

Il nome Nginx si pronuncia “engin-ecs”.

Nginx è un server web open source ad alte prestazioni; è disponibile anche una versione enterprise del server arricchita con funzionalità aggiuntive. In questo articolo, tuttavia, ci limitiamo a presentare la versione open source.

Nginx è stato creato da Igor Sysoev, che lo ha pubblicato nel 2004 con licenza BSD.

Generalmente parlando, Nginx offre maggiori performance rispetto ad Apache o altri server web: Nginx, infatti, è stato creato specificamente per affrontare il problema C10k: implementare un web server in grado di rispondere a più di diecimila client contemporaneamente. Le performance sono rese possibili dalla sua architettura ad eventi.

 

Negli ultimi anni, Nginx si è affermato come uno dei server più utilizzati a livello mondiale, grazie anche all’impiego che ne fanno grandi aziende web.

Utilizzi comuni

  • Server web: Nginx può essere utilizzato come server web autonomo per ospitare pagine web statiche e siti dinamici. Grazie alle sue prestazioni elevate, è particolarmente adatto per siti ad alto traffico.
  • Reverse proxy: Nginx è spesso utilizzato come server proxy inverso per bilanciare il carico del traffico web su più server backend, migliorando così la scalabilità e l’affidabilità del sistema.
  • Caching: Nginx può essere configurato per memorizzare in cache risorse statiche e dinamiche, riducendo così il carico sui server backend e migliorando i tempi di caricamento delle pagine.
  • TLS/SSL termination: Nginx può essere utilizzato per terminare le connessioni TLS/SSL e gestire la crittografia delle comunicazioni web, migliorando la sicurezza e la privacy dei dati degli utenti.

Architettura e modello di gestione I/O

Nginx utilizza un modello di gestione I/O non bloccante, noto anche come event-driven o asincrono. Ciò significa che anziché utilizzare un thread dedicato per ogni connessione, viene utilizzato un singolo thread principale che gestisce molteplici connessioni in modo asincrono, consentendo di gestire un grande numero di connessioni simultanee con un utilizzo efficiente delle risorse.

Il core è composto da un ciclo principale (event loop) che ascolta le connessioni in ingresso, gestisce gli eventi di I/O e distribuisce le richieste ai worker process o threads, se configurati. Questo modello di gestione permette a Nginx di ottenere elevate prestazioni e di scalare efficacemente su hardware multi-core.

L’architettura prevede due componenti fondamentali: master e worker.

  • Il worker gestisce le connessioni con i client e le richieste da questi inoltrate. Il worker è implementato come processo che non richiede privilegi elevati.
  • Il master è incaricato del coordinamento dei worker. Esso ha accesso a elementi privilegiati del sistema per effettuare operazioni come il binding di porte, il caricamento di file configurazione, etc.

Moduli e configurazione

Nginx è estremamente flessibile e modulare grazie al supporto per una vasta gamma di moduli che possono essere abilitati o disabilitati in base alle esigenze dell’applicazione. Alcuni dei moduli più comuni includono:

  • HTTP module: Fornisce funzionalità di base per il server web HTTP, inclusi moduli per il controllo degli accessi, la compressione gzip, la gestione dei log e altro ancora.
  • SSL module: Abilita il supporto per TLS/SSL, consentendo la configurazione di certificati SSL e la gestione delle connessioni crittografate.
  • Proxy module: Permette di configurare Nginx come server proxy inverso per instradare il traffico verso server backend.
  • Load balancing module: Fornisce funzionalità di bilanciamento del carico per distribuire il traffico su più server backend in modo equo e affidabile.
  • Caching module: Consente di memorizzare in cache risorse statiche e dinamiche per migliorare le prestazioni del sito web.

Configurazione

La configurazione di Nginx è specificata nel file principale nginx.conf, che si trova solitamente nella directory /etc/nginx/; si possono usare altri file di configurazione richiamati dal file principale. Le opzioni specificate nel file di configurazione si chiamano direttive. Vi sono due tipi di direttive: quelle semplici specificano solo un valore e si concludono con un punto e virgola.

Le direttive composte, invece contengono più campi. Queste ultime direttive vengono chiamate anche blocchi e sono delimitate da parentesi graffe; è possibile includere nella configurazione dei commenti facendolo precedere dal carattere hash (#).

Vediamo un esempio di un blocco (tratto da qui):

server {
listen 80 default_server;
server_name miosito.com www.miosito.com;
root /var/www/miosito.com;
index index.html;
try_files $uri /index.html;
}

Un esempio minimale di configurazione di Nginx (riportato qui):

user nginx;
worker_processes 1;
events {}
error_log nginx_error.log;
http {
server {
listen 80;
location / {
root /var/www/html;
}
}
}

Questo file configura Nginx come web server che serve contenuti statici mediante il protocollo HTTP. Il web server Nginx avvia un demone in background (su sistemi Linux) con utente nginx e ascolta sulla porta 80, servendo i file statici che si trovano in /var/www/html.

Reverse Proxy

Un reverse proxy è un server web che si interpone tra i client HTTP (o HTTPS o, possibilmente, altri protocolli) e uno o più server che offrono risorse. I client interrogano il reverse proxy inviando a questo le richieste HTTP; il server proxy funge da client intermedio interrogando i server interni, i quali elaborano le risposte alle richieste.

Il proxy inoltra la richiesta al client, eventualmente modificandone alcune parti (ad esempio, gli header).

nginx reverse proxy

Un particolare esempio di reverse proxy è un load balancer: questo è un proxy che si interfaccia a più web server che forniscono gli stessi contenuti; il load balancer distribuisce il carico delle richieste tra i vari server web in modo da garantire velocità e stabilità del servizio, evitando sovraccarichi per i server.

Un proxy server può aggiungere funzionalità alle applicazioni web, ad esempio la cifratura TLS a un server HTTP.

Un esempio di configurazione di Nginx come reverse proxy (da qui), che si ottiene usando al direttiva location:

 

location /home/ {
proxy_pass http://myotherdomain.com/path/;
}

L’intera location viene mappata sul server esterno. Ad esempio, se si richiede al server l’indirizzo /home/dir/page.html il server Nginx richiederà al server esterno la risorsa /path/dir/page.html. È possibile specificare una porta redirect diversa da quelle standard (cf. qui):

location /home/ {
proxy_pass http://myotherdomain.com:8080/path/;
}

 

Il Load Balancer di Nginx

Nginx supporta tre differenti modalità di load balancing:

  1. round-robin: una richiesta viene reindirizzata in ciclo ai server disponibili;
  2. least-connected: una richiesta viene reidirizzata al server che ha meno connessioni attive;
  3. ip-hash: si utilizza una funzione di hashing per associare l’indirizzo IP di un client all’identificativo del server a cui viene indirizzata la richiesta.

nginx load balancing

Vediamo un esempio (adattato da qui):

http {
upstream servers {
server n1.domain.org;
server n2.domain.org;
}
server {
listen 80;
location / {
proxy_pass http://domain.org;
}
}
}

 

La modalità di load balancing utilizzata di default da Nginx è round-robin. Altre tecniche di load balancing devono essere specificate nella direttiva upstream (da qui):

http {
upstream servers {
least_conn;
server n1.domain.org;
server n2.domain.org;
}
server {
listen 80;
location / {
proxy_pass http://domain.org;
}
}
}

 

Nginx può anche agire come load balancer per il traffico TCP/UDP, offrendo un’efficace distribuzione del carico su più server backend: è possibile configurare il bilanciamento del carico per protocolli non HTTP, come ad esempio TCP e UDP.

Nginx fornisce funzionalità avanzate di bilanciamento del carico, tra cui algoritmi di bilanciamento, monitoraggio dello stato dei server backend e la possibilità di configurare pool di server per gestire diversi tipi di traffico.

Ad esempio, possiamo configurare Nginx per redistribuire il traffico tra diversi server DNS (v. qui):

stream {
upstream dns_servers {
server ns1.domain.org:53;
server ns2.domain.org:53;
server ns3.domain.org:53;
}
server {
listen 53 udp;
proxy_pass dns_servers;
}
}

 

Anche in modalità TCP / UDP, Nginx supporta diverse modalità di load balancing:

  • round-robin;
  • least-conn: si inoltra lo stream al server che ha meno connessioni attive;
  • hash: si usa una funzione di hashing per associare ad ogni client un server;
  • random: l’assegnazione del server che riceverà lo stream è casuale.

Sicurezza in Nginx

Nginx offre diverse funzionalità di sicurezza per proteggere il server e le applicazioni web, tra cui:

TLS/SSL: può essere configurato per usare SSL/TLS in modo da crittografare le comunicazioni web, proteggendo così i dati scambiati tra server e client.

Controllo degli accessi: può utilizzare regole di controllo degli accessi per limitare le risorse del server.

Protezione da attacchi: permette di configurare filtri e regole per proteggere il server da attacchi DDoS, XSS e altri comuni attacchi web.

TLS/SSL

Nginx supporta il protocollo HTTPS, che può essere configurato usando il parametro ssl nella direttiva listen. Ad esempio (cf. qui):

# …
server {
listen 443 ssl;
#…
}

In questo caso, bisogna fornire al server un certificato e la relativa chiave privata. La posizione nel file system del certificato e della sua chiave privata si indicano usando ssl_certificate e ssl_certificate_key come segue (v. qui):

# …
server {
listen 443 ssl;
server_name mydomain.net;
ssl_certificate certificate.pem;
ssl_certificate_key privatekey.key;
#…
}

Conclusioni su Nginx

Nginx è un server web e reverse proxy estremamente potente e flessibile, con un’architettura modulare e un modello di gestione I/O efficiente. Con le sue prestazioni elevate, la scalabilità e le numerose funzionalità di configurazione, Nginx è diventato uno strumento essenziale per gestire il traffico web e ottimizzare le prestazioni delle applicazioni online.

Con una corretta configurazione e tuning, Nginx può contribuire significativamente a migliorare l’affidabilità, la sicurezza e le prestazioni del tuo server web.

Ti invitiamo a leggere gli altri interessantissimi articoli del nostro tech-blog!