Nel 2026 quasi tutto il traffico web viaggia in HTTPS, ma quanto di quella cifratura sta ancora costando millisecondi inutili al vostro Time To First Byte? Molte configurazioni Nginx che giravano perfettamente nel 2020 oggi trascinano direttive deprecate, parametri OCSP che non fanno più nulla e cipher suite che TLS 1.3 ignora comunque. Vale la pena rimettere mano al blocco ssl_* del vostro server, non per inseguire un punteggio più alto su SSL Labs, ma perché ogni handshake più corto si moltiplica per il numero di visitatori.
Va detto subito, con onestà: il tuning TLS non salva un backend lento. Se il TTFB del vostro sito è dominato da query al database, cache fredda o un’applicazione PHP/.NET che impiega 800ms a costruire la pagina, ottimizzare l’handshake sposta l’ago di qualche decina di millisecondi. Ma è ottimizzazione a costo quasi zero, che si somma a tutto il resto: cache, CDN, query tuning. Va fatta bene una volta e poi dimenticata.
HTTP/2 e HTTP/3: la sintassi è cambiata
Se la vostra configurazione risale a qualche anno fa, probabilmente avete ancora questa riga:
listen 443 ssl http2;
Funziona ancora, ma da Nginx 1.25.1 il parametro http2 sulla direttiva listen è deprecato: lanciando nginx -t su una build recente comparirà un warning esplicito. La forma corretta separa i due concetti:
listen 443 ssl;
http2 on;
La direttiva http2 attiva il protocollo per l’intero server block, il che è più pulito che ripeterlo su ogni riga listen. Se gestite una flotta di server dietro un load balancer, verificate che tutte le istanze montino Nginx 1.25.1 o superiore prima di effettuare lo switch: una versione più vecchia non riconosce http2 on; e si rifiuta di avviarsi.
Attivare HTTP/3 con QUIC senza compilare nulla
Fino a poco tempo fa, abilitare HTTP/3 su Nginx significava patchare e ricompilare da sorgente contro una libreria TLS con supporto QUIC: un esercizio che pochi sistemisti volevano affrontare in produzione. Quell’epoca è finita. Il supporto nativo a QUIC e HTTP/3 è arrivato nel mainline Nginx a partire dalla 1.25.0 ed è ormai maturo nel branch stable, quindi sulle distribuzioni recenti o sul repository ufficiale Nginx non serve più compilare nulla a mano.
Va detto che, nonostante l’entusiasmo degli anni scorsi, l’adozione reale di HTTP/3 procede più lentamente del previsto: a metà 2026 HTTP/2 serve poco più della metà delle richieste globali mentre HTTP/3 si attesta intorno al 21%, con un plateau che dura da diversi mesi. Parte del motivo è strutturale: un browser passa a HTTP/3 solo dopo aver scoperto il supporto tramite un header Alt-Svc o un record DNS, quindi molte prime visite non negoziano mai QUIC. Vale comunque la pena abilitarlo: sposta il trasporto su UDP ed elimina l’head-of-line blocking di TCP, un vantaggio concreto su connessioni mobili lente o con perdita di pacchetti.
Su Nginx 1.25.0 o superiore con supporto QUIC integrato, un server block tipico è:
server {
listen 443 ssl;
listen [::]:443 ssl;
listen 443 quic reuseport;
listen [::]:443 quic reuseport;
http2 on;
ssl_certificate /path/to/your/certificate.pem;
ssl_certificate_key /path/to/your/key.pem;
# Annuncia HTTP/3 ai client che arrivano via HTTP/1.1 o HTTP/2
add_header Alt-Svc 'h3=":443"; ma=86400';
# ... resto della configurazione del server
}
Attenzione a reuseport: va specificato una sola volta per combinazione IP/porta. Se gestite più server block sullo stesso indirizzo, mettete reuseport solo sul blocco predefinito e usate listen 443 quic; sugli altri, altrimenti Nginx si rifiuta di partire.
L’header Alt-Svc è il dettaglio che quasi tutti dimenticano: senza di esso i browser non hanno modo di sapere che il server parla HTTP/3 e restano su HTTP/2. Dopo la modifica, testate e ricaricate:
nginx -t
nginx -s reload
Per verificare rapidamente da riga di comando quale protocollo state effettivamente servendo:
curl --http2 -I https://vostrodominio.it/
curl --http3 -I https://vostrodominio.it/
Session cache e session ticket: il vero risparmio sull’handshake
Con HTTPS, invece di una singola andata e ritorno, la connessione richiede un handshake aggiuntivo. Attivare la cache delle sessioni TLS riduce questo costo per le connessioni ripetute:
ssl_session_cache shared:SSL:10m; # circa 40.000 sessioni
ssl_session_timeout 1d; # tempo di riutilizzo della sessione
Sui session ticket la raccomandazione è cambiata rispetto a qualche anno fa. Un tempo si consigliava di disabilitarli perché la rotazione della chiave di cifratura non era gestita correttamente da Nginx. Da Nginx 1.23.2 in poi la gestione delle chiavi per la ripresa stateless delle sessioni è molto migliorata, quindi salvo casi particolari conviene tenerli attivi:
ssl_session_tickets on;
Unica eccezione: se gestite più server Nginx dietro un bilanciatore senza sincronizzare le chiavi dei ticket tra le istanze, la ripresa della sessione si rompe silenziosamente e perdete il beneficio. In quel caso, sincronizzate le chiavi o disabilitate i ticket su tutta la flotta in modo coerente.
Quali versioni TLS tenere attive
TLS 1.0 e 1.1 sono obsoleti, bloccati da ogni browser moderno e vietati dallo standard PCI DSS: vanno disattivati ovunque, senza eccezioni. La vera decisione riguarda invece TLS 1.2 e 1.3.
Per la maggior parte dei siti pubblici, la scelta corretta è tenere entrambi attivi:
ssl_protocols TLSv1.2 TLSv1.3;
È TLS 1.3 a fare la differenza sul TTFB: riduce l’handshake a un singolo round trip e supporta la ripresa di sessione, quindi i visitatori che tornano si connettono più rapidamente. TLS 1.2 resta come fallback per client più datati e, su un sito pubblico normale, non costa nulla lasciarlo attivo.
Passate a TLS 1.3 soltanto se controllate i client che si connettono: un’API interna, un backend applicativo, un servizio dove sapete con certezza che nessun client datato deve collegarsi:
ssl_protocols TLSv1.3;
Disabilitare TLS 1.2 su un sito pubblico è il tipo di modifica che sembra pulita in un file di configurazione e poi silenziosamente taglia fuori una fetta di traffico reale. Senza un motivo specifico, lasciatelo acceso.
OCSP stapling: cosa è cambiato con Let’s Encrypt
L’OCSP stapling permette a Nginx di allegare all’handshake una prova firmata dalla CA della validità del certificato, evitando che il client debba interrogare direttamente il servizio OCSP. La configurazione classica resta questa:
ssl_stapling on;
ssl_stapling_verify on;
ssl_trusted_certificate /path/to/full_chain.pem;
resolver 8.8.8.8 8.8.4.4 valid=300s;
resolver_timeout 5s;
Ma qui c’è un cambiamento importante da conoscere se usate Let’s Encrypt: il 6 agosto 2025 Let’s Encrypt ha terminato il supporto OCSP e spento i propri responder. I certificati che emette oggi non hanno più un URL OCSP, ma un URL CRL al suo posto. Senza un responder da interrogare, ssl_stapling on; non fa più nulla sui certificati Let’s Encrypt e Nginx registra nei log un warning "ssl_stapling" ignored, no OCSP responder URL.
Il bilancio onesto nel 2026 è questo: se la vostra CA pubblica ancora un URL OCSP, lo stapling resta un piccolo vantaggio innocuo e potete tenerlo attivo. Se siete su Let’s Encrypt, le direttive sopra sono ormai inerti e potete rimuoverle per tenere puliti configurazione e log. È parte di uno spostamento più ampio del settore verso CRL e certificati a vita breve.
Buffer SSL più piccolo per ridurre il TTFB
Il parametro ssl_buffer_size imposta la dimensione del buffer usato per inviare dati via HTTPS. Il valore predefinito è 16k, pensato per risposte di grandi dimensioni, ma per minimizzare il TTFB conviene spesso un valore più piccolo:
ssl_buffer_size 4k;
Il risparmio tipico è di 30-50 millisecondi sul TTFB, variabile a seconda del carico e delle dimensioni medie delle risposte servite.
Configurazione completa consigliata per il 2026
http2 on;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_prefer_server_ciphers off;
ssl_ciphers 'ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305';
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 1d;
ssl_session_tickets on;
ssl_buffer_size 4k;
add_header Strict-Transport-Security "max-age=63072000; includeSubdomains; preload";
add_header X-Frame-Options sameorigin;
add_header X-Content-Type-Options nosniff;
Da notare: con TLS 1.3 le cipher suite sono fissate dal protocollo stesso, quindi una lunga stringa ssl_ciphers personalizzata e una direttiva ssl_ecdh_curve manuale non portano quasi nessun beneficio. I cipher elencati sopra si applicano soltanto alle connessioni TLS 1.2, e ssl_prefer_server_ciphers va disattivato perché i client moderni scelgono in modo sensato per conto proprio. Piuttosto che ottimizzare a mano all’infinito, generate una configurazione aggiornata con il Mozilla SSL Configuration Generator e incollate solo le parti che vi servono.
Se avete ancora in configurazione una riga X-Xss-Protection "1; mode=block", rimuovetela: l’XSS auditor del browser che controllava è stato eliminato da tutti i browser principali, e in alcuni casi quell’header può addirittura introdurre vulnerabilità invece di prevenirle. Una Content-Security-Policy è il sostituto moderno.
Conclusione
Nessuna di queste modifiche, presa singolarmente, trasformerà le prestazioni del vostro sito. Ma insieme costituiscono un livello di ottimizzazione a costo pressoché nullo che qualsiasi sistemista dovrebbe verificare almeno una volta l’anno, specialmente dopo un major upgrade di Nginx o un rinnovo dell’infrastruttura dei certificati. Testate sempre con nginx -t prima di ricaricare, verificate il risultato con SSL Labs e con l’ispezione della colonna Protocol negli strumenti di sviluppo del browser, e ricordate che il vero collo di bottiglia, nella maggior parte dei casi, resta ciò che succede dopo l’handshake: cache, query e tempo di generazione della risposta.
Fonte: Nginx tuning tips: HTTPS/TLS – Turbocharge TTFB/Latency, LinuxBlog.io (Hayden James).