hjr265.me / blog /

Setup HTTP3 with NGINX Mainline

October 8, 2023 #100DaysToOffload #NGINX

HTTP3 is here. Well, almost.

If you are using NGINX, you can update to the mainline version and start using HTTP3 today experimentally.

Installing NGINX Mainline

As of writing this blog post, NGINX v1.24 is the latest stable version. But, HTTP3 is available in v1.25.

On Ubuntu/Debian-esque servers, the easiest way to install the mainline NGINX version is to use NGINX’s official repository.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
apt install curl gnupg2 ca-certificates lsb-release debian-archive-keyring

# Import the official NGINX signing key.
curl https://nginx.org/keys/nginx_signing.key | gpg --dearmor \
    | tee /usr/share/keyrings/nginx-archive-keyring.gpg >/dev/null

# Add the APT repository.
echo "deb [signed-by=/usr/share/keyrings/nginx-archive-keyring.gpg] \
http://nginx.org/packages/mainline/debian `lsb_release -cs` nginx" \
    | tee /etc/apt/sources.list.d/nginx.list

# Install NGINX.
apt update
apt install nginx=1.25.*

nginx -v # Verify installation.

Alternatively, you can also do this in Docker.

Enable HTTP3 for an NGINX Server Block (Virtual Host)

To enable HTTP3 for a server block, first configure SSL and verify the server block works.

Next, add a listen directive with the quic parameter and a response header advertising the support for HTTP3:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
server ... {
  listen 443 quic reuseport; # For HTTP3
  listen 443 ssl;

  ssl_certificate     certs/example.com.crt;
  ssl_certificate_key certs/example.com.key;

  location / {
    add_header Alt-Svc 'h3=":443"; ma=86400'; # Response header to advertise HTTP3 support
  }
}

It is worth noting that if you have multiple server blocks where you want to enable HTTP3, you can use the reuseport parameter only once per address:port pair.

Open 443/UDP

If you have the server behind a firewall or with iptables rules blocking 443/UDP, reconfigure and open the port. HTTP3, unlike earlier versions of HTTP, is a UDP-based protocol.

Yes, it took me a bit to realize my firewall was blocking 443/UDP.

Restart NGINX

Validate your NGINX configuration with nginx -t and restart NGINX.

For some reason, reloading NGINX with systemctl reload didn’t quite get HTTP3 working.

Test HTTP3

Finally, test to make sure that HTTP3 is working.

You may use something like http3check.net or curl --http3 (if built with HTTP3 capabilities).


This post is 60th of my #100DaysToOffload challenge. Want to get involved? Find out more at 100daystooffload.com.


comments powered by Disqus