编译 Openresty 新增 brotli 和 http3 支持

编译 Openresty 新增 brotli 和 http3 支持

本文主要讲述如何编译 openresty 并新增 brotli 压缩和 http3 支持;并解决 http3 反代时,没有 http_post header 导致的异常。

编译 ngx_brotli

1
2
3
4
5
6
apt install make cmake gcc libpcre3 libpcre3-dev libssl-dev zlib1g zlib1g-dev
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 -m64 -march=native -mtune=native -flto -funroll-loops -ffunction-sections -fdata-sections -Wl,--gc-sections" -DCMAKE_CXX_FLAGS="-Ofast -m64 -march=native -mtune=native -flto -funroll-loops -ffunction-sections -fdata-sections -Wl,--gc-sections" -DCMAKE_INSTALL_PREFIX=./installed ..
cmake --build . --config Release --target brotlienc

这一步基本就是照着官方的步骤来的,但在树莓派 4B 上,出现了问题,我需要用下面的命令:

cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=./installed ..

编译 openresty

1
2
3
4
5
wget 'https://openresty.org/download/openresty-1.27.1.2.tar.gz'
tar -zxvf ./openresty-1.27.1.2.tar.gz
cd ./openresty-1.27.1.2
./configure --add-module=/opt/openresty/ngx_brotli --with-http_v2_module --with-http_v3_module
make && make install

注意,以上 3 步,我是以管理员身份运行的。

添加 nginx.service

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
[Unit]
Description=A high performance web server and a reverse proxy server
After=network-online.target remote-fs.target nss-lookup.target
Wants=network-online.target

[Service]
Type=forking
PIDFile=/usr/local/openresty/nginx/logs/nginx.pid
ExecStartPre=/usr/local/openresty/nginx/sbin/nginx -t
ExecStart=/usr/local/openresty/nginx/sbin/nginx
ExecReload=/usr/local/openresty/nginx/sbin/nginx -s reload
ExecStop=/usr/local/openresty/nginx/sbin/nginx -s quit

[Install]
WantedBy=multi-user.target

启用 http3

 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
server {
    listen 443 ssl;
    http2 on;
    listen 543 quic reuseport;
    server_name your-domain-name;
    charset uft-8;

    location / {
        access_by_lua_block {
            local authority = ngx.var.http_authority or ngx.var.http_host
            ngx.var.proxy_host = authority
        }
        proxy_pass https://pi-server;
        proxy_connect_timeout 60s;
        proxy_read_timeout 60s;
        proxy_send_timeout 60s;
        proxy_redirect off;
        proxy_http_version 1.1;
        proxy_set_header Host $proxy_host;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        add_header Alt-Svc 'h3=":543"; ma=86400';
    }
}

新增第 4,9-12,24 行,第 19 行做了调整,修改前为:proxy_set_header Host $http_host;
h2 和 h3 是两个不同的协议,可以运行在同一个端口,也可以不一样,h3 是 udp,由于我有其他服务占用了 443 的 udp 端口,故这里用 543,请注意,udp 端口号需要小于 1000,否则只有 firefox 有效。另外,同一个端口 quic reuseport 不能出现多次,如有多次,删除 reuseport 即可。

http3 没有 host 请求头,所以不存在 $http_host,如果网关支持 h3 但上游不支持,那么就会出现问题,我这里使用 lua 脚本解决该问题。

测试网站是否支持 http3

https://http3.wcode.net 输入你的域名,然后查看。
也可以打开浏览器的开发者工具,然后在网络下面查看,默认无协议列,可右键点击表头,比如右键点击状态,然后勾选协议。

最后更新于