源码编译nginx体验http3.0(quic)协议

1,299 阅读1分钟

支持http3.0协议的nginx有两个方案可以选择,一个是cloudflare的分支版本,一个nginx-quic项目。
nginx-quic是ngixn官网研发支持http3.0协议的项目。本次目的是安装nginx-quic体验http3.0协议。

我这里使用Ubuntu20.04,当前官方最新版本nginx-1.23.2,首先安装编译依赖包,没有这些依赖包,后面编译nginx可能会出错。

apt update
apt install -y gcc g++ cmake golang libpcre3-dev

这次nginx不使用openssl,而是要用boringssl。

git clone https://github.com/google/boringssl
cd boringssl/

创建build目录,用于存放编译后的文件。make编译过程中会从go官网下载模块,由于国内网络的问题,推荐配置一下golang proxy。

export GOPROXY=https://proxy.golang.com.cn,direct
mkdir -pv .openssl/lib build
cmake -B build
make -C build

编译完成后,build目录会生成两个目录:crypto和ssl,这两个目录有nginx需要的文件。
将libcrypto.a和libssl.a复制到.openssl/lib下,后面编译需要使用。
.openssl/include很关键,nginx编译会找这个目录。

cp build/crypto/libcrypto.a build/ssl/libssl.a .openssl/lib
ln -s $PWD/include .openssl/include

获取nginx quic分支的源码包,貌似官网没提供各个版本的源码包,只能下载最新版的。

cd ~/
curl -O https://hg.nginx.org/nginx-quic/archive/quic.tar.gz
tar xf quic.tar.gz
cd nginx-quic-quic/

开始编译nginx,一切从简,毕竟只是为了测试http3.0。

./auto/configure --prefix=/usr/local/nginx-quic \
--with-pcre \
--with-http_ssl_module \
--with-http_v2_module \
--with-http_v3_module \
--without-http_gzip_module \
--with-openssl=../boringssl

执行configure后不要着急执行make,而是要更新一下ssl.h文件。

这里很有意思,大概说一下,在make过程中,make会通过判断ssl.h文件的时间戳,如果时间戳在执行configure后有更新,表示boringssl编译成功了,如果时间戳没更新表示boringssl编译失败了。
就算你在执行configure前更新ssl.h也是不行的,必须在configure后更新,这是经过我测试得到的结论。

touch ../boringssl/.openssl/include/openssl/ssl.h

最后执行make完成编译,nginx会安装到--prefix指定的位置。

make
make install

看下nginx是不是成功安装了,执行nginx -V看到有compatible; BoringSSL就是成功了的。

root@ubuntu:~# /usr/local/nginx-quic/sbin/nginx -V
nginx version: nginx/1.23.2
built by gcc 9.4.0 (Ubuntu 9.4.0-1ubuntu1~20.04.1) 
built with OpenSSL 1.1.1 (compatible; BoringSSL) (running with BoringSSL)
TLS SNI support enabled
configure arguments: --prefix=/usr/local/nginx-quic --with-pcre --with-http_ssl_module --with-http_v2_module --with-http_v3_module --without-http_gzip_module --with-openssl=../boringssl
root@ubuntu:~# 

在nginx的配置文件中加入这些内容,http3关键字表示启用http3.0协议。

    server {
        listen 443 http3 reuseport;
        listen 443 ssl http2;

        ssl_certificate      cert.crt;
        ssl_certificate_key  cert.key;
        ssl_protocols TLSv1.3;

        add_header alt-svc 'h3=":443"; ma=86400';
        
        location / {
            default_type text/html;
            return 200 $server_protocol;
        }
    }

使用Chrome或者Edge浏览器访问,如果返回HTTP/3.0那就对了。 使用支持http3协议的curl访问也行。

root@ubuntu:~# /usr/local/curl-http3/bin/curl -V | grep HTTP3
Features: alt-svc AsynchDNS HSTS HTTP2 HTTP3 HTTPS-proxy IPv6 Largefile NTLM NTLM_WB SSL threadsafe TLS-SRP UnixSockets
root@ubuntu:~# 
root@ubuntu:~# /usr/local/curl-http3/bin/curl https://www.example.com --resolve www.example.com:443:192.168.3.47 --http3 
HTTP/3.0
root@ubuntu:~#