如何在Nginx中开启HTTP3.0的支持
本篇内容介绍了“如何在Nginx中开启HTTP3.0的支持”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!
方案选择
对于HTTP3.0,由于整个协议还是处于草案阶段,目前来说没有一个完整的标准,所以各大浏览器厂商还只是在开发者版本中才会支持,例如Chrome的金丝雀版本Chrome Canary[1],并且各个服务器厂商也是在持续跟进中,对于Nginx来说,支持HTTP3.0目前有两种方案可以选择:
- 基于Cloudflare的分支版本Nginx:对于HTTP3.0/QUIC,Cloudflare始终走在了前列,借助于自家维护的开源项目 quic [2],从Nginx中拉出了一个分支来开发,并编译出了对HTTP3.0支持的Nginx服务器。
- Nginx官方Nginx-quic项目:今年6月10日,Nginx 官博 [3]发布公告称已经在研发支持HTTP3.0/QUIC协议的工作,目前项目维护在 nginx-quic [4],该项目和基于Cloudflare基于Nginx的分支并无关系,算是相对于正统的方案。
基于此,本文将会以部署nginx-quic的方式来让Nginx支持HTTP3.0/QUIC。
改造过程
我们最终的目的是得到nginx-quic版本的nginx可执行文件,需要经过一系列的安装和编译,期间可能会遇到很多问题,如果各位读者不想实际操作,可以直接用我编译好的版本nginx-quic.linux-x86_64.zip 传送门[5]。
准备工作:
以centos7为例,下载nginx-quic源码传送门[6],下载完成之后,需要进行编译安装,由于nginx-quic依赖boringSSL,所以还需下载boringSSL源码传送门[7],然后同样需要编译安装boringSSL,执行这些操作之前,需要在linux上安装一些前置模块,通过yum来安装,执行以下命令:
sudo yum install build-essential mercurial psmisc lsb-release cmake golang libunwind-dev git libpcre3-dev zlib1g-dev
什么是boringSSL:
对于Nginx来说,在编译时需要配置对于的SSL库,不管是HTTP3.0还是HTTP2.0,始终都要基于HTTPS,而加密算法这块主要有OpenSSL来提供,而BoringSSL是谷歌创建的OpenSSL分支,用于支持TLS1.3的UDP协议0-RTT数据传输的加密算法(可以理解成TLS1.3是标准协议,BoringSSL是实现工具),BoringSSL的一些特性会在合适的时机同步给OpenSSl。
编译安装boringSSL:
cd boringssl-master/
mkdir build
cd build
cmake ../
make
执行之后,可以在build/crypto
,和build/ssl
下获得对应的文件,如下图:
注意编译安装boringSSL需要使用cmake3以上的版本。
编译安装nginx-quic:
cd nginx-quic/
./auto/configure --prefix=/root/nginx --with-http_ssl_module --with-http_v2_module --with-http_v3_module --with-cc-opt="-I../boringssl-master/include" --with-ld-opt="-L../boringssl-master/build/ssl -L../boringssl-master/build/crypto"
make
make install
执行命令之后,会在/root/nginx
目录下生成对应的nginx可执行文件,如下图:
其中,配置文件在conf/
下,nginx命令在sbin/
目录下。
修改配置文件,启动nginx:
vi /root/nginx/conf/nginx.conf
添加http3配置:
server {
listen 443 ssl http2; # TCP listener for HTTP/2
listen 443 http3 reuseport; # UDP listener for QUIC+HTTP/3
ssl_protocols TLSv1.3; # QUIC requires TLS 1.3
ssl_certificate ssl/www.example.com.crt;
ssl_certificate_key ssl/www.example.com.key;
add_header Alt-Svc 'quic=":443"; h4-27=":443";h4-25=":443"; h4-T050=":443"; h4-Q050=":443";h4-Q049=":443";h4-Q048=":443"; h4-Q046=":443"; h4-Q043=":443"'; # Advertise that QUIC is available
}
其中,要求使用TLSv1.3版本,并且当浏览器不支持http3时,可以选择http2。另外,add_header Alt-Svc
添加这个返回头不可缺少。
- Alt-Svc 全称为“Alternative-Service”,直译为“备选服务”。该头部列举了当前站点备选的访问方式列表,让服务器可以告诉客户端 “看,我在这个主机的这个端口用这个协议提供相同的服务”。一般用于在提供 “QUIC” 等新兴协议支持的同时,实现向下兼容。参考 MDN [8]。
验证HTTP3生效:
由于目前浏览器对HTTP3.0/QUIC的支持性有限,可以通过http3check.net/[9]来验证站点启用HTTP3是否成功,以我的站点为例:
坑点总结
整个过程看似很简单,但是真正配置过程中遇到了不少坑,前前后后加上搜索问题花了一天半的时间才真正解决,把这些问题记录下来,分享给大家。
开启UDP的443端口:
由于quic协议使用的是UDP的443端口,这个端口对于centos7来说是默认关闭的,可以采用下面命令开启:
firewall-cmd --zone=public --add-port=443/udp --permanent
如果项目托管在阿里云上,需要更新ECS的安全组策略来对外开启对应的协议和端口,如下图:
TLS版本向下兼容:
由于使用了TLS 1.3,所以会修改对应加密算法,但是对于一些浏览器而言还不支持这么高的版本,尤其是对于苹果的Safari,所以,在配置nginx配置文件时,要多配置几个版本向下兼容,代码如下:
ssl_protocols TLSv1 TLSv1.1 TLSv1.2 TLSv1.3;
-Werror错误问题:
在编译nginx-quic时,有时会遇到如下错误:
cc -c -pipe -O -W -Wall -Wpointer-arith -Wno-unused-parameter -Werror -g -I../boringssl-master/include -I src/core -I src/event -I src/event/modules -I src/os/unix -I objs \
-o objs/src/os/unix/ngx_linux_sendfile_chain.o \
src/os/unix/ngx_linux_sendfile_chain.c
cc -c -pipe -O -W -Wall -Wpointer-arith -Wno-unused-parameter -Werror -g -I../boringssl-master/include -I src/core -I src/event -I src/event/modules -I src/os/unix -I objs \
-o objs/src/event/ngx_event_openssl.o \
src/event/ngx_event_openssl.c
cc -c -pipe -O -W -Wall -Wpointer-arith -Wno-unused-parameter -Werror -g -I../boringssl-master/include -I src/core -I src/event -I src/event/modules -I src/os/unix -I objs \
-o objs/src/event/ngx_event_openssl_stapling.o \
src/event/ngx_event_openssl_stapling.c
cc -c -pipe -O -W -Wall -Wpointer-arith -Wno-unused-parameter -Werror -g -I../boringssl-master/include -I src/core -I src/event -I src/event/modules -I src/os/unix -I objs \
-o objs/src/event/ngx_event_quic.o \
src/event/ngx_event_quic.c
cc -c -pipe -O -W -Wall -Wpointer-arith -Wno-unused-parameter -Werror -g -I../boringssl-master/include -I src/core -I src/event -I src/event/modules -I src/os/unix -I objs \
-o objs/src/event/ngx_event_quic_transport.o \
src/event/ngx_event_quic_transport.c
src/event/ngx_event_quic_transport.c: In function ‘ngx_quic_create_stream’:
src/event/ngx_event_quic_transport.c:54:9: error: comparison is always true due to limited range of data type [-Werror=type-limits]
: ((uint32_t) value) <= 16383 ? 2 \
^
src/event/ngx_event_quic_transport.c:1299:15: note: in expansion of macro ‘ngx_quic_varint_len’
len = ngx_quic_varint_len(sf->type);
^
cc1: all warnings being treated as errors
make[1]: *** [objs/src/event/ngx_event_quic_transport.o] Error 1
make[1]: Leaving directory `/root/nginx-quic'
make: *** [build] Error 2
[root@iz2zehmi1ztqtx8tg6ca7gz nginx-quic]#
解决办法是:
cd nginx-quic\objs
vi Makefile
找到 CFLAGS = -pipe -O -W -Wall -Wpointer-arith -Wno-unused-parameter -Werror -g -I../boringssl-master/include
将-Werror参数去掉。
reuseport只需配置一次:
假如有多个域名需要开启http3,则reuseport建议只在根域名上配置,如果一个配置文件中出现多个reuseport,会报错,配置如下:
server {
listen 443 ssl http2; # TCP listener for HTTP/2
listen 443 http3 reuseport; # UDP listener for QUIC+HTTP/3
server_name www.nihaoshijie.com.cn default_server;
}
server {
listen 443 ssl http2; # TCP listener for HTTP/2
listen 443 http3; # UDP listener for QUIC+HTTP/3
server_name app.nihaoshijie.com.cn;
}
编译安装时的性能问题:
如果编译安装时报类似下面的错误,可能是主机的内容不足,需要关闭一些运行的程序来往下进行。
...
c++: internal compiler error: Killed (program cc1plus)
“如何在Nginx中开启HTTP3.0的支持”的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识可以关注蜗牛博客网站,小编将为大家输出更多高质量的实用文章!
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:niceseo99@gmail.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。
评论