Installing and Configuring Nginx with HTTP/3 (QUIC) support from source on Ubuntu 24.04 LTS: Performance Guides
Prerequisites and Dependencies
Before compiling Nginx with HTTP/3 support, ensure your Ubuntu 24.04 LTS system is up-to-date and has the necessary development tools and libraries installed. This includes the GCC compiler, OpenSSL development headers, and the BoringSSL library, which is a fork of OpenSSL and a dependency for HTTP/3. We will also need the `libp7-dev` package for Brotli compression, which is often used in conjunction with HTTP/3 for better performance.
Execute the following commands to install these prerequisites:
First, update your package lists and upgrade existing packages:
sudo apt update && sudo apt upgrade -y
Next, install the build essentials, OpenSSL development files, and Brotli development files:
sudo apt install -y build-essential libssl-dev zlib1g-dev libpcre3 libpcre3-dev libbrotli-dev git
Compiling BoringSSL
HTTP/3 relies on QUIC, which in turn uses TLS 1.3. While OpenSSL can be used, BoringSSL is often recommended and sometimes required by Nginx’s HTTP/3 module. We’ll compile BoringSSL from source.
Clone the BoringSSL repository:
cd /usr/local/src sudo git clone https://boringssl.googlesource.com/boringssl cd boringssl
Compile and install BoringSSL. The `make install` command will place the headers and libraries in the appropriate system directories.
sudo make sudo make install
After installation, it’s good practice to update the linker cache:
sudo ldconfig
Downloading and Compiling Nginx with HTTP/3 Module
Now, we’ll download the latest stable Nginx source code and compile it with the necessary modules for HTTP/3. The HTTP/3 module is typically included as a dynamic module or can be compiled statically. For simplicity and to ensure all dependencies are met, we’ll compile it statically.
Navigate back to your source directory and download the Nginx source. Replace `1.25.3` with the latest stable version if available.
cd /usr/local/src sudo wget http://nginx.org/download/nginx-1.25.3.tar.gz sudo tar -zxvf nginx-1.25.3.tar.gz cd nginx-1.25.3
The HTTP/3 module is often referred to as `ngx_http_v2_module` and `ngx_http_v3_module`. The QUIC support is usually enabled via the `–with-stream_quic_module` and `–with-http_v3_module` flags. We also need to explicitly link against BoringSSL.
The `./configure` command is critical. Here’s a robust set of options for a high-performance Nginx with HTTP/3:
sudo ./configure \
--prefix=/etc/nginx \
--sbin-path=/usr/sbin/nginx \
--modules-path=/usr/lib/nginx/modules \
--conf-path=/etc/nginx/nginx.conf \
--error-log-path=/var/log/nginx/error.log \
--http-log-path=/var/log/nginx/access.log \
--pid-path=/var/run/nginx.pid \
--lock-path=/var/run/nginx.lock \
--user=nginx \
--group=nginx \
--with-compat \
--with-file-aio \
--with-threads \
--with-http_addition_module \
--with-http_auth_request_module \
--with-http_dav_module \
--with-http_flv_module \
--with-http_gunzip_module \
--with-http_gzip_static_module \
--with-http_mp4_module \
--with-http_random_index_module \
--with-http_realip_module \
--with-http_secure_link_module \
--with-http_slice_module \
--with-http_ssl_module \
--with-http_stub_status_module \
--with-http_sub_module \
--with-http_v2_module \
--with-http_v3_module \
--with-stream \
--with-stream_realip_module \
--with-stream_ssl_preread_module \
--with-stream_ssl_module \
--with-stream_quic_module \
--with-stream_autoindex_module \
--with-stream_stub_status_module \
--with-pcre \
--with-pcre-jit \
--with-brotli=dynamic \
--with-openssl=/usr/local/include \
--with-openssl-opt=enable-tls1_3 \
--with-ld-opt="-L/usr/local/lib -lssl -lcrypto -Wl,-rpath=/usr/local/lib" \
--add-module=/usr/local/src/nginx-quic/quiche/nginx
Note on `–with-openssl` and `–with-ld-opt`: These flags are crucial for telling Nginx to use our compiled BoringSSL. The `–with-openssl=/usr/local/include` points to the BoringSSL headers, and `–with-ld-opt` ensures the linker finds the BoringSSL libraries. The `-Wl,-rpath=/usr/local/lib` is important for runtime library loading.
Note on `–with-http_v3_module` and `–with-stream_quic_module`: These enable the HTTP/3 and QUIC protocols respectively. They are often dependent on each other and require a modern OpenSSL/BoringSSL build.
Note on `–with-brotli=dynamic`: This enables Brotli compression as a dynamic module, which can be loaded later. This is beneficial for static assets.
Note on `–add-module=/usr/local/src/nginx-quic/quiche/nginx`: This is a common way to include the QUIC module if it’s not directly part of the main Nginx source tree or if you’re using a specific fork like `nginx-quic`. If you are using a standard Nginx source and the HTTP/3 module is integrated, this might not be necessary. For this guide, we assume a standard Nginx source and that the HTTP/3 module is enabled via the `./configure` flags. If you encounter issues, you might need to clone a specific `nginx-quic` fork and use this flag.
After configuring, compile and install Nginx:
sudo make sudo make install
It’s essential to create the `nginx` user and group if they don’t exist:
sudo groupadd -g 1000 nginx sudo useradd -u 1000 -g nginx -s /sbin/nologin -d /var/cache/nginx -M nginx
Ensure the log directories and Nginx configuration directories are owned by the `nginx` user:
sudo mkdir -p /var/log/nginx sudo chown -R nginx:nginx /var/log/nginx sudo mkdir -p /etc/nginx/conf.d sudo chown -R nginx:nginx /etc/nginx
Configuring Nginx for HTTP/3
To enable HTTP/3, you need to configure your Nginx server block to listen on a UDP port and specify the necessary SSL/TLS settings. HTTP/3 requires TLS 1.3.
Edit your main Nginx configuration file, typically `/etc/nginx/nginx.conf`, or create a new server block configuration file in `/etc/nginx/conf.d/`. Here’s an example configuration snippet for a server block:
# Load dynamic Brotli module
load_module modules/ngx_http_brotli_filter_module.so;
load_module modules/ngx_http_brotli_static_module.so;
http {
# ... other http configurations ...
# Brotli compression settings
brotli on;
brotli_comp_level 6;
brotli_static on;
brotli_types text/plain text/css application/json application/javascript application/xml application/xhtml+xml text/javascript image/svg+xml;
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
# HTTP/3 listener on UDP port 443
listen 443 quic reuseport;
listen [::]:443 quic reuseport;
server_name your_domain.com www.your_domain.com;
ssl_certificate /etc/letsencrypt/live/your_domain.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/your_domain.com/privkey.pem;
# TLS 1.3 is mandatory for HTTP/3
ssl_protocols TLSv1.3;
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';
ssl_prefer_server_ciphers off; # For TLS 1.3, client and server negotiate more freely
# HTTP/3 specific settings
add_header Alt-Svc 'h3=":443"; ma=86400'; # Announce HTTP/3 support
# Other server configurations (root, location blocks, etc.)
root /var/www/your_domain.com/html;
index index.html index.htm;
location / {
try_files $uri $uri/ =404;
}
# ... other location blocks ...
}
# ... other server blocks ...
}
Explanation of Key Directives:
load_module modules/ngx_http_brotli_filter_module.so;andload_module modules/ngx_http_brotli_static_module.so;: These lines dynamically load the Brotli compression modules.brotli on;,brotli_comp_level,brotli_static on;,brotli_types: These configure Brotli compression for supported content types.listen 443 quic reuseport;: This directive tells Nginx to listen for QUIC traffic on UDP port 443. The `reuseport` option is crucial for allowing multiple Nginx worker processes to bind to the same port, improving performance and scalability.ssl_protocols TLSv1.3;: HTTP/3 mandates TLS 1.3.add_header Alt-Svc 'h3=":443"; ma=86400';: This is the `Alternative Service` header. It informs the client that HTTP/3 is available on UDP port 443 for this host. `ma=86400` sets the maximum age for this advertisement (24 hours).
Firewall Configuration
For HTTP/3 to work, you must allow UDP traffic on port 443 through your firewall. If you are using `ufw`:
sudo ufw allow 443/udp sudo ufw allow 443/tcp sudo ufw reload
If you are using `iptables` directly, you’ll need rules similar to:
sudo iptables -A INPUT -p udp --dport 443 -j ACCEPT sudo iptables -A INPUT -p tcp --dport 443 -j ACCEPT # Save iptables rules if necessary (e.g., using iptables-persistent)
Testing and Verification
After configuring Nginx, test your configuration syntax and restart the service.
sudo nginx -t sudo systemctl restart nginx
To verify HTTP/3 support, you can use browser developer tools (e.g., Chrome’s Network tab, which shows the “Protocol” column) or online tools like KeyCDN’s HTTP/3 Test. You can also use `curl` with specific flags, though native HTTP/3 support in `curl` can be experimental and requires a specific build.
A simple way to check if Nginx is listening on UDP port 443 is using `ss`:
sudo ss -lunp | grep 443
You should see an entry indicating `nginx` listening on `0.0.0.0:443` or `[::]:443` with the `udp` protocol.
Performance Tuning Considerations
Enabling HTTP/3 is a significant step for performance, but further tuning can optimize its benefits:
- Worker Connections: Ensure
worker_connectionsinnginx.confis set appropriately for your system’s resources (e.g.,worker_connections 4096;). - Worker Processes: Set
worker_processes auto;to let Nginx determine the optimal number of worker processes based on your CPU cores. - `reuseport`: As mentioned, this is critical for UDP listeners to distribute load across worker processes.
- Brotli Compression Level: Experiment with
brotli_comp_level. Higher levels offer better compression but consume more CPU. Level 6 is a good balance. - TLS 1.3 Cipher Suites: While Nginx defaults are generally good, ensure your cipher suite list is optimized for TLS 1.3. The example provided is a reasonable starting point.
- `sendfile` and `tcp_nopush`: For TCP connections, these directives improve efficiency. Ensure they are enabled where appropriate.
- Keepalive Settings: Tune
keepalive_timeoutandkeepalive_requestsfor TCP connections to balance resource usage and connection efficiency. - Logging: For high-traffic sites, consider disabling or optimizing access logging for performance-critical paths, or use asynchronous logging mechanisms.
Compiling from source gives you fine-grained control over Nginx’s capabilities and performance. By carefully selecting modules and compile-time options, you can tailor Nginx to your specific needs, including the adoption of modern protocols like HTTP/3.
Leave a Reply
You must be logged in to post a comment.