How to Enable HTTP/3 in Nginx
In comparison to HTTP/2 and earlier versions of HTTP, HTTP/3, based on the QUIC (Quick UDP Internet Connections) protocol, achieves lower latency, improved network adaptability, and enhanced security. Enabling HTTP/3 support in Nginx can enhance performance and user experience, with the following key benefits:
- Lower Latency: QUIC’s 0-RTT and 1-RTT handshake mechanisms reduce connection establishment and retransmission times, accelerating page loads.
- Multiplexing: HTTP/3 allows multiple requests over a single connection via UDP, offering better recovery and reduced blocking compared to TCP.
- Fast Recovery: QUIC uses custom congestion control algorithms to quickly recover from packet loss, improving transmission efficiency.
- Enhanced Security: As an application-layer encryption protocol, QUIC provides end-to-end encryption, safeguarding data from man-in-the-middle attacks.
- Improved Network Adaptability: QUIC enables changing IP addresses or ports without disrupting sessions, enhancing support for mobile devices switching between networks.
To enable QUIC support in Nginx, OpenSSL or BoringSSL must be integrated during compilation. Manual compilation is complex, using a precompiled version is more convenient.
Below is an example demonstrating the use of the official precompiled version of Nginx on Rocky Linux 9.4:
Install Nginx (Rocky Linux 9)
To add the repo, create a file named /etc/yum.repos.d/nginx.repo
with the following contents:
[nginx-mainline]
name=nginx mainline repo
baseurl=http://nginx.org/packages/mainline/centos/$releasever/$basearch/
gpgcheck=1
enabled=1
gpgkey=https://nginx.org/keys/nginx_signing.key
module_hotfixes=true
# update repo
dnf update
# install nginx
dnf install nginx
Modify the configuration file to enable HTTP/3
Edit /etc/nginx/nginx.conf
user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log notice;
pid /var/run/nginx.pid;
events {
worker_connections 1024;
}
http {
server_tokens off;
charset utf-8;
sendfile on;
tcp_nopush on;
tcp_nodelay on;
log_not_found off;
types_hash_max_size 2048;
types_hash_bucket_size 64;
client_max_body_size 16M;
keepalive_timeout 65;
include /etc/nginx/mime.types;
default_type application/octet-stream;
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log /var/log/nginx/access.log main;
# gzip
gzip on;
gzip_min_length 1k;
gzip_vary on;
gzip_proxied any;
gzip_comp_level 5;
gzip_types text/plain text/css text/xml application/json application/javascript application/rss+xml application/atom+xml image/svg+xml;
# SSL
ssl_session_timeout 1d;
ssl_session_cache shared:SSL:10m;
ssl_session_tickets off;
# Diffie-Hellman parameter for DHE ciphersuites
# Generate the dhparam.pem file for forward secrecy
# openssl dhparam -out /etc/nginx/dhparam.pem 2048
ssl_dhparam /etc/nginx/dhparam.pem;
# Mozilla Intermediate configuration
ssl_protocols TLSv1.3 TLSv1.2;
ssl_ciphers HIGH:!aNULL:!MD5;
# OCSP Stapling
ssl_stapling off;
ssl_stapling_verify off;
# DNS
resolver 1.1.1.1 1.0.0.1 [2606:4700:4700::1111] [2606:4700:4700::1001] valid=60s;
resolver_timeout 2s;
include /etc/nginx/http.d/*.conf;
}
Edit /etc/nginx/http.d/example.com.conf
server {
listen [::]:443 quic;
listen 443 quic;
listen [::]:443 ssl;
listen 443 ssl;
listen [::]:80;
listen 80;
http2 on;
# enable http3
http3 on;
add_header Alt-Svc 'h3=":443"; ma=86400';
# enable 0-RTT
ssl_early_data on;
# openssl rand 80 > /srv/ssl/ssl_session_ticket_key.key
ssl_session_ticket_key /srv/ssl/ssl_session_ticket_key.key;
server_name www.example.com example.com;
# redirect non-www to www, http to https
if ($http_host = "example.com") {
return 301 https://www.example.com$request_uri;
}
if ($scheme = "http" ) {
return 301 https://www.example.com$request_uri;
}
# root
root /srv/web/example.com/www_public;
index index.html;
#try_files $uri $uri/ /index.html;
# redirect server error pages to the static page /50x.html
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
# SSL
ssl_certificate /srv/ssl/example.com_fullchain.cer;
ssl_certificate_key /srv/ssl/example.com.key;
# logging
access_log /var/log/nginx/example.com.access.log combined buffer=512k flush=1m;
error_log /var/log/nginx/example.com.error.log warn;
}
Key configuration for HTTP/3
# use port 443 for quic
listen [::]:443 quic;
listen 443 quic;
# enable http/3
http3 on;
# required for browsers to direct them to quic port; expired in 24h
add_header Alt-Svc 'h3=":443"; ma=86400';
# enable 0-RTT
ssl_early_data on;
Start Nginx
# test the config file
nginx -t
# start nginx automatically when system boots
systemctl enable nginx
# start nginx
systemctl start nginx
Precompiled Packages and Reference
- nginx: Linux packages https://nginx.org/en/linux_packages.html
- Support for QUIC and HTTP/3 https://nginx.org/en/docs/quic.html
Read Other Posts