前置条件
系统版本:Ubuntu 20.04 Nginx 版本:1.18(稍后需要升级) 用来测试的服务:当前存在可用的 HTTPS/2 网站 OpenSSL:3.0.2(可选升级)
检查 Nginx 版本并升级
我的系统恰好是 Ubuntu 20.04 + Nginx 1.18,可以参考这篇文章升级 Nginx:Upgrading Nginx from version 1.18 to 1.25 (Ubuntu 20.04)
# 备份 Nginx 配置
$ sudo cp -r /etc/nginx /etc/nginx-backup
# 添加 Nginx Repository
$ wget http://nginx.org/keys/nginx_signing.key
$ sudo mv nginx_signing.key /etc/apt/trusted.gpg.d/nginx_signing.gpg
# sudo apt-key add nginx_signing.key
$ echo "deb http://nginx.org/packages/mainline/ubuntu `lsb_release -cs` nginx" | sudo tee /etc/apt/sources.list.d/nginx.list
# 更新软件列表
$ sudo apt update
# 安装最新的 Nginx
$ sudo apt install nginx
# 检查版本
$ nginx -v
nginx version: nginx/1.27.1
已升级到了 1.27 版本
Nginx 示例配置
没有特别需要说明的,字段含义可以问下 AI,修改配置后记得 nginx -s reload
加载配置
server {
# HTTP/3
listen 443 quic reuseport;
listen [::]:443 quic reuseport;
# HTTP/2
listen 443 ssl;
listen [::]:443 ssl;
http2 on;
server_name yasking.org;
merge_slashes off;
# 证书
ssl_certificate /etc/letsencrypt/live/yasking.org-0001/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/yasking.org-0001/privkey.pem;
ssl_protocols TLSv1.2 TLSv1.3;
# ssl_prefer_server_ciphers on;
ssl_ciphers 'TLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256: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';
# O-RTT QUIC connection resumption
ssl_early_data on;
# Add Alt-SvC header to negotiate HTTP/3.
add_header Alt-Svc 'h3=":443";ma=86400';
ssl_session_timeout 1d;
ssl_session_cache shared:SSL:50m;
ssl_session_tickets off;
# OCSP Stapling
ssl_stapling on;
ssl_stapling_verify on;
resolver 8.8.8.8;
# 启用 HSTS
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload";
add_header X-Content-Type-Options nosniff;
# 日志配置
access_log /var/log/nginx/yasking.access.log;
error_log /var/log/nginx/yasking.error.log;
root /usr/share/nginx/html;
index index.html index.htm;
location / {
try_files $uri $uri/ =404;
}
}
# 强制 HTTP 重定向到 HTTPS
server {
listen 80;
server_name yasking.org;
return 301 https://$server_name$request_uri;
}
升级 OpenSSL 版本(可选)
当前版本 3.0.2,当前最新是 3.3.2,不升级也可以,升级步骤如下
# 下载当前最新的 OpenSSL 程序源码
$ wget https://www.openssl.org/source/openssl-3.3.2.tar.gz
# 解压缩并生成编译配置
$ sudo tar -zxvf openssl-3.3.2.tar.gz -C /usr/src/
$ cd /usr/src/
$ sudo ln -s openssl-3.3.2 openssl
$ cd openssl
$ ./config --prefix=/usr/local/ssl
# 机器 CPU 不太行的话执行 sudo make -j 1 && sudo make install
$ sudo make -j $(nproc) && sudo make install
# 新建 /etc/ld.so.conf.d/openssl-3.0.conf 添加一行 /usr/local/ssl/lib64,此处的 /usr/local/ssl 根据 ./config 的 --prefix 参数确定
$ cat /etc/ld.so.conf.d/openssl-3.0.conf
/usr/local/ssl/lib64
# 备份原 OpenSSL 可执行程序,创建新的链接
$ sudo mv /usr/bin/openssl /usr/bin/openssl_bak
$ sudo ln -s /usr/local/ssl/bin/openssl /usr/bin/openssl
# 链接运行时的动态链接库
$ sudo ldconfig
# 查看库的安装情况
$ sudo ldconfig -v
HTTPS/3 访问验证
Curl 命令
$ docker run -t --rm alpine/curl-http3 curl --http3 -I https://yasking.org:443
macOS Chrome 129
Windows Firefox 130
在火狐上有个叫「HTTP Version Indicator」的扩展,安装后可以显示 HTTP 协议版本
为什么不是 macOS 的 Firefox 测试?因为它一直显示 HTTP/2,清除缓存也没用,我暂不清楚原因
最后
HTTP/3 虽然不是一个新技术,但也在快速发展和完善中,可能今天的配置和参数符合标准,后天浏览器就不认降级回 HTTP/2
云平台、各个基础组件库都需要陆续迭代支持,需要一个过程,本篇借助 Nginx 使得主域名支持通过 HTTP/3 协议访问
相比于一两年前,部署方便很多,Nginx 和 OpenSSL 都不用自己编译,安装新版即可,先这样