Enable HTTP/3 in NGINX

Published in

on

HTTP/3 is the latest and most up-to-date version of the HTTP, designed to improve upon the limitations and performance issues of its predecessors, HTTP/1, HTTP/1.1 and HTTP/2. Built on the QUIC (Quick UDP Internet Connections) transport protocol, totally new, HTTP/3 offers several enhancements, including reduced latency, faster connection establishment, and improved security.

QUIC, initially developed by Google, that replaces traditional use of TCP with UDP, allowing for multiplexed connections without head-of-line blocking, a significant issue in HTTP/2 where packet loss could delay the entire connection.

One of the standout features of HTTP/3 is its ability to maintain connections even when network conditions change, such as switching from Wi-Fi to mobile data. This is achieved through QUIC’s connection migration capabilities, providing a smoother and more reliable browsing experience for users.

Additionally, HTTP/3 incorporates TLS 1.3 natively, enhancing security by encrypting more of the connection setup process and reducing the number of round trips required to establish a secure connection.

HTTP/3 - QUIC
HTTP/3 – QUIC

These improvements make HTTP/3 particularly well-suited for modern web applications and services that demand high performance and low latency.

For the time being it was introduced, many draft versions have come and tested and now finally it is out of draft to be implemented on web servers and internet tools.

In this article, which is a kind of tutorial, I’ll show you how to enable HTTP/3 in Nginx.

Before we begin, make sure you have installed the latest version of stable Nginx. As of writing this tutorial, NGINX 1.26 is the latest stable version that supports HTTP/3.

Directives highlighted in yellow shows the addition in configs.

server {
    listen 443 ssl;
    listen [::]:443 ssl;
    listen 443 quic reuseport;
    listen [::]:443 quic reuseport;

    # Enable http/2.
    http2 on;
#Earlier it was written in listen directive but as http3 came, NGINX moved this to a separate and dedicated directive. Now, it offers us an option to disable/enable it. It is recommended to keep it on to support all old news browsers.

    # Enable http/3.
    http3 on;
    quic_retry on;
    # Add http/3 headers. Move these headers where others are located.
    add_header Alt-Svc 'h3=":$server_port"; ma=86400';
    add_header x-quic 'h3';

    # Server details.
    server_name example.com www.example.com;
    root /var/www/html;
    index index.php;

    # SSL certificate and key.
    ssl_certificate /location/cert.pem;
    ssl_certificate_key /location/cert_key.pem;

    # SSL configurations, including strong ciphers.
    ssl_protocols TLSv1.3 TLSv1.2;
    ssl_ciphers ssl_ciphers HIGH:!aNULL:!MD5;
    ssl_prefer_server_ciphers on;
    ssl_stapling on;
    ssl_early_data on; # Enables 0-RTT.

    # Index location block.
    location / {
        try_files $uri $uri/ /index.php?args; 
    }

    location ~ \.php$ {
        # ... PHP location block ....
    }
}

You can also define very specific SSL ciphers if you don’t like the above one, like this:

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:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384;

Once you made the changes and saved the configuration file, now test the configs and if everything looks okay then restart/reload the nginx service, for that use the following commands.

sudo nginx -t

If it shows successful message, then only restart the Nginx.

sudo systemctl restart nginx

Now, try to load the website a few times and check for http/3 headers.

If you don’t know how to test it, read this article about http/3 test tools.

Leave a Reply

Your email address will not be published. Required fields are marked *