隨住最近 Nginx-Quic 分支被合併到咗 Nginx 主線,Nginx 1.25.0 版本官方二進制包已經支援 Quic/HTTP3,有興趣嘅朋友可以前往 https://nginx.org/en/download.htmlhttps://nginx.org/en/linux_packages.html 下載安裝,體驗一下 Quic/HTTP3 嘅魅力,本文將主要為你介紹點樣透過編譯嘅方式開啟 Quic/HTTP3。

2024年02月20號更新:通過喺 Nginx 郵件社區討論得到咗一個解決方案,可以將 libssl 構建為共享庫嚟解決呢個問題,詳見 https://mailman.nginx.org/pipermail/nginx/2024-February/5N5IXG7BI66D5AIKORCYPVVVJTZYMUR6.html ,可以根據需要自行試。

2024年02月19號更新:因為谷歌嘅 BoringSSL 而家發佈咗一個破壞性嘅更新,所以導致編譯出錯,本文臨時將克隆到嘅 BoringSSL 版本修改為 c39e6cd9ec5acebb6de2adffc03cfe03b07f08ab 呢個 commit。
2023年11月19號更新:修正咗Nginx_brotli編譯錯誤嘅問題。
2023年06月22號更新:更新咗關於 HTTP/2 嘅配置,Nginx 已經廢棄咗 listen 指令中嘅 http2 參數,改為 http2 on;,詳見 https://hg.nginx.org/nginx/rev/08ef02ad5c54https://nginx.org/en/docs/http/ngx_http_v2_module.html ,如果你之前參照過本文編譯安裝 Nginx,請你重新編譯安裝之後修改配置,可參照示例配置

安装依赖

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# Debian 11/12
apt update
apt install build-essential ca-certificates zlib1g-dev libpcre3 libpcre3-dev tar unzip libssl-dev wget curl git cmake ninja-build mercurial libunwind-dev pkg-config
# Ubuntu 22.04/20.04
sudo su
cd /root
apt update
apt install build-essential ca-certificates zlib1g-dev libpcre3 libpcre3-dev tar unzip libssl-dev wget curl git cmake ninja-build mercurial libunwind-dev pkg-config
# CentOS 8 Stream/TencentOS Server 3.1
dnf update
dnf install gcc gcc-c++ pcre-devel openssl-devel zlib-devel cmake make libunwind-devel hg git wget
# OpenCloudOS Server 8
dnf update
dnf install gcc gcc-c++ pcre-devel openssl-devel zlib-devel cmake make hg git wget

安裝Go

下載並解壓

1
2
wget https://dl.google.com/go/go1.22.0.linux-amd64.tar.gz
rm -rf /usr/local/go && tar -C /usr/local -xzf go1.22.0.linux-amd64.tar.gz

添加环境变量

1
export PATH=$PATH:/usr/local/go/bin

具体可参考https://go.dev/doc/install

验证是否安装成功

1
go version

編譯 boringssl

Debian/Ubuntu

1
2
3
4
5
6
7
8
git clone https://github.com/google/boringssl.git
cd boringssl
git reset --hard c39e6cd9ec5acebb6de2adffc03cfe03b07f08ab
mkdir build
cd build
cmake -GNinja ..
ninja
cd ../..

CentOS 8 Stream/TencentOS Server 3.1/OpenCloudOS Server 8

1
2
3
4
5
6
7
8
git clone https://github.com/google/boringssl.git
cd boringssl
git reset --hard c39e6cd9ec5acebb6de2adffc03cfe03b07f08ab
mkdir build
cd build
cmake -DCMAKE_BUILD_TYPE=Release ..
make
cd ../..

安装 brotli 压缩

唔需要就跳过,編譯时删咗–add-module=/root/ngx_brotli

1
2
3
4
5
6
git clone --recurse-submodules -j8 https://github.com/google/ngx_brotli
cd ngx_brotli/deps/brotli
mkdir out && cd out
cmake -DCMAKE_BUILD_TYPE=Release -DBUILD_SHARED_LIBS=OFF -DCMAKE_C_FLAGS="-Ofast -march=native -mtune=native -flto -funroll-loops -ffunction-sections -fdata-sections -Wl,--gc-sections" -DCMAKE_CXX_FLAGS="-Ofast -march=native -mtune=native -flto -funroll-loops -ffunction-sections -fdata-sections -Wl,--gc-sections" -DCMAKE_INSTALL_PREFIX=./installed ..
cmake --build . --config Release --target brotlienc
cd ../../../..

編譯安裝quic

注意:
我係直接喺 /root 目錄下編寫嘅,如果你喺其它目錄下,請自行修改路徑;
如果你唔需要 brotli 壓縮,請刪除–add-module=/root/ngx_brotli
我將 Nginx 安裝喺 /www/server/nginx 目錄下,如果你需要修改,請自行修改路徑;

1
2
3
4
5
hg clone https://hg.nginx.org/nginx
cd nginx
./auto/configure --user=www --group=www --prefix=/www/server/nginx --with-pcre --add-module=../ngx_brotli --with-http_v2_module --with-stream --with-stream_ssl_module --with-http_ssl_module --with-http_gzip_static_module --with-http_gunzip_module --with-http_sub_module --with-http_flv_module --with-http_addition_module --with-http_realip_module --with-http_mp4_module --with-ld-opt=-Wl,-E --with-cc-opt=-Wno-error --with-ld-opt=-ljemalloc --with-http_dav_module --with-http_v3_module --with-cc-opt=-I../boringssl/include --with-ld-opt='-L../boringssl/build/ssl -L../boringssl/build/crypto'
make
make install

添加 www 用户

1
2
groupadd www
useradd -g www -s /sbin/nologin www

添加進程管理

我所使用的是systemd,如果你使用的是其他進程管理器,請自行修改

1
vim /usr/lib/systemd/system/nginx.service

輸入嘅內容:

1
2
3
4
5
6
7
8
9
10
11
12
13
[Unit]
Description=nginx
After=network.target

[Service]
Type=forking
ExecStart=/www/server/nginx/sbin/nginx
ExecReload=/www/server/nginx/sbin/nginx -s reload
ExecStop=/www/server/nginx/sbin/nginx -s quit
PrivateTmp=true

[Install]
WantedBy=multi-user.target

启动

1
systemctl start nginx

开机自启

1
systemctl enable nginx

配置档

范例配置档咁,想知更多功能请参考官方文件:https://nginx.org/en/docs/http/ngx_http_v3_module.html

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
server {
listen 443 ssl;
listen [::]:443 ssl;

#用嚟支援Quic或者HTTP/3
listen 443 quic reuseport;
listen [::]:443 quic reuseport;

#用嚟支援HTTP/2
http2 on;

server_name r2wind.com;

#Quic或者HTTP/3响应头
add_header Alt-Svc 'h3=":443"; ma=86400';
#HSTS
add_header Strict-Transport-Security "max-age=63072000; includeSubdomains; preload";

location / {
root /www/wwwroot/r2wind.com;
index index.html index.htm;
}

#證書配置
ssl_certificate /root/.acme.sh/smb.wiki/fullchain.cer;
ssl_certificate_key /root/.acme.sh/smb.wiki/smb.wiki.key;
ssl_session_timeout 5m;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:HIGH:!aNULL:!MD5:!RC4:!DHE;
ssl_prefer_server_ciphers on;
}

配置做好咗之后,重新加载 Nginx 就可以生效咗

1
systemctl reload nginx