分别编译基于最新版本OpenSSL和BoringSSL的Nginx支持HTTP3

前言

在 Nginx 上开启 HTTP/3 能带来不少性能和安全上的提升,这主要得益于其底层使用的 QUIC 协议(一种基于 UDP 的现代传输协议)。下面我用一个表格梳理了一下:

好处类型 具体说明 主要原因/技术
性能提升 降低延迟减少网络拥塞适应高并发场景 基于UDP、0-RTT连接重用、多路复用、改进的拥塞控制
用户体验优化 页面加载更快移动网络体验更顺畅弱网环境下更稳定 连接迁移、更好的丢包恢复机制
安全增强 默认加密减少中间人攻击风险 内置 TLS 1.3、放大攻击防御机制
技术优势 解决队头阻塞面向未来 QUIC 流级别多路复用、协议发展趋势

注意事项

虽然 HTTP/3 好处很多,但在 Nginx 上启用时也需要考虑以下几点:

  • Nginx 版本与编译需求:需要使用 Nginx 1.25.0 或更高版本

  • 实验性功能:目前 Nginx 中的 HTTP/3 支持在某些版本中可能仍标记为实验性(experimental)。生产环境部署前务必充分测试。

  • 客户端支持:主流现代浏览器(Chrome、Firefox、Edge 等)均已支持 HTTP/3,但仍需考虑旧版客户端或特定网络环境(如某些防火墙可能拦截 UDP)的兼容性问题。

  • UDP 端口开放:确保服务器的 UDP 443 端口(或其他你使用的端口)已在防火墙中打开。

  • 多服务器配置:如果一台服务器配置了多个域名,在配置 HTTP/3 监听时可能需要特别注意 reuseport 参数的使用,以避免端口冲突。

准备

官方的建议是使用 OpenSSL 3.5.1+ 的版本,或者 boringssl - Git at GoogleGitHub - quictls/openssl: TLS/SSL and crypto library with QUIC APIs

根据自身的需求,下载最新版本的SSL以及最新版的Nginx:nginx: download

截止到今天(2025年9月15日),通过包管理器安装到Nignx为 1.24.0 ,该版本不支持http3,需 1.25.0+ 才行。

如果想简单点的话,可以通过 add-apt-repository ppa:ondrej/nginx 添加Ondřej Surý 维护的 Nginx 官方 PPA (Personal Package Archive) 仓库,接下来直接使用 apt install nginx 即可升级到 1.28.0 版本,与目前最新的 1.29.1 都能支持http3,就不用进行编译了。

安装编译所需的基础工具:

apt install build-essential libpcre3-dev zlib1g-dev git mercurial cmake golang ninja-build perl libperl-dev libxml2-dev libxslt1-dev libexpat-dev 

编译

基于OpenSSL

一:下载OpenSSL以及Nginx

wget https://github.com/openssl/openssl/releases/download/openssl-3.5.2/openssl-3.5.2.tar.gz
tar -zxvf openssl-3.5.2.tar.gz
wget https://nginx.org/download/nginx-1.29.1.tar.gz
tar -zxvf nginx-1.29.1.tar.gz

二:编译配置

cd nginx-1.29.1

./configure \
    --prefix=/etc/nginx \
    --sbin-path=/usr/sbin/nginx \
    --conf-path=/etc/nginx/nginx.conf \
    --error-log-path=/var/log/nginx/error.log \
    --http-log-path=/var/log/nginx/access.log \
    --pid-path=/run/nginx.pid \
    --lock-path=/run/nginx.lock \
    \
    --with-threads \
    --with-file-aio \
    --with-pcre \
    --with-pcre-jit \
    \
    --with-openssl=../openssl-3.5.2 \  # 指向openssl的目录
    --with-http_ssl_module \
    --with-http_v2_module \
    --with-http_v3_module \
    --with-http_realip_module \
    --with-http_addition_module \
    --with-http_sub_module \
    --with-http_dav_module \
    --with-http_flv_module \
    --with-http_mp4_module \
    --with-http_gunzip_module \
    --with-http_gzip_static_module \
    --with-http_stub_status_module \
    --with-http_random_index_module \
    --with-http_secure_link_module \
    --with-http_degradation_module \
    --with-http_slice_module \
    --with-http_auth_request_module \
    \
    --with-mail \
    --with-mail_ssl_module \
    --with-stream \
    --with-stream_realip_module \
    --with-stream_ssl_module \
    \
    --user=www-data \
    --group=www-data

出现这个提示说明配置成功了:

三:编译和安装

make -j$(nproc)
sudo make install

基于BoringSSL

一:下载BoringSSL以及Nginx

BoringSSL 用国内网络下载可能比较麻烦,不过用国内镜像就行。

git clone https://gitee.com/mirrors/boringssl.git
wget https://nginx.org/download/nginx-1.29.1.tar.gz
tar -zxvf nginx-1.29.1.tar.gz

二:编译BoringSSL

cd boringssl
mkdir build && cd build  #创建构建目录
cmake .. -DCMAKE_BUILD_TYPE=Release  # 使用 cmake 编译
make -j$(nproc)

编译完成后,关键文件:

  • 头文件:boringssl/include/

  • 静态库:boringssl/build/libssl.a 和 boringssl/build/libcrypto.a

三:编译配置

cd nginx-1.29.1

./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=/run/nginx.pid \
    --lock-path=/run/nginx.lock \
    --with-http_ssl_module \
    --with-http_v2_module \
    --with-http_v3_module \
    --with-http_realip_module \
    --with-http_addition_module \
    --with-http_sub_module \
    --with-http_dav_module \
    --with-http_flv_module \
    --with-http_mp4_module \
    --with-pcre \
    --with-pcre-jit \
    --with-http_gunzip_module \
    --with-http_gzip_static_module \
    --with-http_stub_status_module \
    --with-http_random_index_module \
    --with-http_secure_link_module \
    --with-http_degradation_module \
    --with-http_slice_module \
    --with-http_auth_request_module \
    --with-mail \
    --with-mail_ssl_module \
    --with-stream \
    --with-stream_realip_module \
    --with-stream_ssl_module \
    --with-stream_ssl_preread_module \
    --with-cc-opt="-I/root/boringssl/include" \  #最重要的就是这两行,写绝对路径
    --with-ld-opt="-L/root/boringssl/build -L/root/boringssl/build/crypto -lssl -lcrypto -lstdc++ -lpthread -lm" \
    --user=www-data \
    --group=www-data \
    --with-threads \
    --with-file-aio \
    --with-compat

出现这个提示说明配置成功了:

四:编译和安装

make -j$(nproc)
sudo make install

创建系统服务

vim /etc/systemd/system/nginx.service

粘贴以下内容(根据你的实际路径调整):

[Unit]
Description=nginx - high performance web server
After=network.target network-online.target
Documentation=https://nginx.org/en/docs/
Wants=network-online.target

[Service]
Type=forking
PIDFile=/run/nginx.pid
ExecStartPre=/usr/sbin/nginx -t -c /etc/nginx/nginx.conf
ExecStart=/usr/sbin/nginx -c /etc/nginx/nginx.conf
ExecReload=/usr/sbin/nginx -s reload
ExecStop=/usr/sbin/nginx -s stop
PrivateTmp=true
Restart=always

[Install]
WantedBy=multi-user.target

创建必要的目录和权限(如果不存在):

mkdir -p /var/cache/nginx /var/log/nginx
chown -R www-data:www-data /var/cache/nginx /var/log/nginx
systemctl daemon-reload
systemctl enable nginx
systemctl start nginx
systemctl status nginx

基于OpenSSL 3.5.2

基于BoringSSL

大功告成!

测试

注意:HTTP/3基于UDP 443端口,确保防火墙放行!

1:创建自签名证书(测试用)

# 创建证书目录
sudo mkdir -p /etc/nginx/certs

# 生成私钥和自签名证书(有效期 365 天)
sudo openssl req -x509 -nodes -days 365 -newkey rsa:2048 \
    -keyout /etc/nginx/certs/example.com.key \
    -out /etc/nginx/certs/example.com.crt \
    -subj "/CN=localhost"

2:简单配置

编辑/etc/nginx/nginx.conf ,在http块中添加内容如下:

server {
    # for better compatibility it's recommended
    # to use the same port for http/3 and https
    listen 443 ssl;
    listen 443 quic reuseport;

    http2 on;

    index index.htm index.html index.nginx-debian.html;

    ssl_protocols TLSv1.3;
    ssl_certificate     certs/example.com.crt;
    ssl_certificate_key certs/example.com.key;

    location / {
        # used to advertise the availability of HTTP/3
        add_header Alt-Svc 'h3=":443"; ma=86400';
    }
}

3:重新载入nginx

systemctl reload nginx

4:访问网页

这里有个奇怪的现象,HTTP/3 并不是100%能够握手成功,不同浏览器反应的情况也不一样。

这次测试下来:

Safari浏览器成功显示HTTP/3协议

Edge显示HTTP/2协议

Chrome也显示的HTTP/2

最后

发表一下我的个人看法。

这两天其实一直在测试HTTP/3,从使用ondrej库安装,到自行编译,后来尝试了不同版本的OpenSSL,再尝试了官网涉及的BoringSSL,从本地测试,再到服务器上测试,过程不算坎坷,但是结果非常不稳定,相同的步骤、相同的配置,最终有显示HTTP/3的,大多数还是HTTP/2,而且,有一点非常令我困惑,成功握手HTTP/3后,打开页面的速度非常慢,远远不如HTTP/2。

这两天也查了很多关于HTTP/3的资料,非常有限,更多的推荐还是把网站代理到Cloudflare来支持HTTP/3。

至今也没搞懂,如果有懂的兄弟希望能帮我解惑。

记录一下这篇文章,等HTTP/3确定可行后,可以再来更新。


参考

Module ngx_http_v3_module

Support for QUIC and HTTP/3

0 0 投票数
文章评分
订阅评论
提醒
guest
0 评论
最旧
最新 最多投票
内联反馈
查看所有评论
滚动至顶部
0
希望看到您的想法,请您发表评论x