SupportHTTP3.0/QUICNginx中的HTTP3.0,也称为HTTPoverQUIC。核心是QUIC(读作quick)协议,是Google在2015年提出的SPDYv3演变而来的新协议。传统的HTTP协议是基于传输层TCP的协议,而QUIC是基于传输层UDP的协议,可定义程:HTTP3.0UDP基于安全可靠的HTTP2.0协议,主要有以下特点:图片来自Nginx官方博客基于UDP,减少了TCP三次握手和TLS握手时间,解决多路复用丢包时的队头阻塞问题,优化RetransmissionPolicyFlowControlConnectionMigration本文主要讲解如何在Nginx中开启HTTP3.0支持。方案选择对于HTTP3.0,由于整个协议还处于草案阶段,目前还没有完整的标准,所以各大浏览器厂商只会在开发版支持,比如ChromeCanary,Chrome的金丝雀版本[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-basedNginx-basedbranch无所谓,是比较正统的方案。基于此,本文将部署nginx-quic,使Nginx支持HTTP3.0/QUIC。在改造过程中,我们的最终目标是获取nginx-quic版本的nginx可执行文件。它需要经过一系列的安装和编译。这期间,可能会遇到很多问题。如果读者不想实际操作,可以直接使用我编译的版本。nginx-quic.linux-x86_64.zip传送门[5]。准备工作:以centos7为例,下载nginx-quic源码传送门[6],下载完成后需要编译安装,因为nginx-quic依赖boringSSL,所以需要下载boringSSL源码portal[7],然后还需要编译安装boringSSL。在执行这些操作之前,需要先在linux上安装一些前置模块,通过yum安装,执行如下命令:sudoyuinstallbuild-essentialmercurialpsmiclsb-releasecmakegolanglibunwind-devgitlibpcre3-devzlib1g-devWhatisboringSSL:对于Nginx来说,当编译的时候需要配置相应的SSL库,无论是HTTP3.0还是HTTP2.0,都是基于HTTPS的,加密算法主要由OpenSSL提供,而BoringSSL是Google创建的支持TLS1.3加密的OpenSSL分支UDP协议0-RTT数据传输的算法(可以理解为TLS1.3是标准协议,BoringSSL是实现工具),BoringSSL的一些特性会在合适的时候同步到OpenSSL。编译安装boringSSL:执行cdboringssl-master/mkdirbuildcdbuildcmake../make后,在build/crypto和build/ssl下可以得到相应的文件,如下图:注意编译需要cmake3以上版本并安装boringSSL。编译安装nginx-quic:cdnginx-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"makemakeinstall执行命令后,它会在/root/nginx目录下生成对应的nginx可执行文件,如下图所示:其中配置文件在conf/下,nginx命令在sbin/目录下。修改配置文件,启动nginx:vi/root/nginx/conf/nginx.conf添加http3配置:server{listen443sslhttp2;#TCPlistenerforHTTP/2listen443http3reuseport;#UDPlistenerforQUIC+HTTP/3ssl_protocolsTLSv1.3;#QUICrequiresTLS1.3ssl_certificatessl/www.example。com.crt;ssl_certificate_keyssl/www.example.com.key;add_headerAlt-Svc'quic=":443";h3-27=":443";h3-25=":443";h3-T050=":443";h3-Q050=":443";h3-Q049=":443";h3-Q048=":443";h3-Q046=":443";h3-Q043=":443"';#AdvertisethatQUICisavailable其中,需要TLSv1.3版本,当浏览器不支持http3时,可以选择http2。另外add_headerAlt-Svc是少不了的,要加上这个返回头。Alt-Svc的全称是“Alternative-Service”,直译为“替代服务”。这个头列出了当前站点的替代访问方法列表,这样服务器就可以告诉客户端“看,我使用这个协议在这个主机的这个端口上提供相同的服务”。它通常用于实现向后兼容,同时为“QUIC”等新兴协议提供支持。参见MDN[8]。验证HTTP3是否生效:由于目前浏览器对HTTP3.0/QUIC的支持有限,可以通过http3check.net/[9]验证站点是否成功启用HTTP3。以我的站点为例:坑点总结整个过程看似很简单,但是在实际配置过程中遇到了很多坑。解决了前后题和搜索题,用了一天半的时间。我会把这些问题记录下来,分享给大家。开启UDP443端口:由于quic协议使用UDP443端口,centos7默认关闭该端口,可以使用以下命令开启:firewall-cmd--zone=public--add-port=443/udp--permanent如果项目托管在阿里云,需要更新ECS的安全组策略对外开放相应的协议和端口,如下图:TLS版本向下兼容:由于使用TLS1.3,相应的加密算法将被修改。但是,有些浏览器不支持这么高的版本,尤其是苹果的Safari。因此,在配置nginx配置文件时,需要配置多个版本,以实现向后兼容。代码如下:ssl_protocolsTLSv1TLSv1.1TLSv1.2TLSv1。3;-Werror错误问题:在编译nginx-quic时,有时会遇到如下错误:cc-c-pipe-O-W-Wall-Wpointer-arith-Wno-unused-parameter-Werror-g-I../boringssl-master/include-Isrc/core-Isrc/event-Isrc/event/modules-Isrc/os/unix-Iobjs\-oobjs/src/os/unix/ngx_linux_sendfile_chain.o\src/os/unix/ngx_linux_sendfile_chain.ccc-c-pipe-O-W-Wall-Wpointer-arith-Wno-unused-parameter-Werror-g-I../boringssl-master/include-Isrc/core-Isrc/event-Isrc/event/modules-Isrc/os/unix-Iobjs\-oobjs/src/event/ngx_event_openssl.o\src/event/ngx_event_openssl.ccc-c-pipe-O-W-Wall-Wpointer-arith-Wno-unused-parameter-Werror-g-I../boringssl-master/include-Isrc/核心-Isrc/事件-Isrc/事件/模块-Isrc/os/unix-Iobjs\-oobjs/src/event/ngx_event_openssl_stapling.o\src/event/ngx_event_openssl_stapling.ccc-c-pipe-O-W-Wall-Wpointer-arith-Wno-unused-parameter-Werror-g-I../boringssl-master/include-Isrc/core-Isrc/event-Isrc/event/modules-Isrc/os/unix-Iobjs\-oobjs/src/event/ngx_event_quic.o\src/event/ngx_event_quic.ccc-c-pipe-O-W-Wall-Wpointer-arith-Wno-unused-parameter-Werror-g-I../boringssl-master/include-Isrc/core-Isrc/event-Isrc/event/modules-Isrc/os/unix-Iobjs\-oobjs/src/event/ngx_event_quic_transport.o\src/event/ngx_event_quic_transport.csrc/event/ngx_event_quic_transport.c:Infunction'ngx_quic_create_stream':src/event/ngx_event_quic_transport.c:54:9:error:comparisonisalwaystrueduetolimitedrangeofdatatype[-错误-limits]:((uint32_t)value)<=16383?2\^src/event/ngx_event_quic_transport.c:1299:15:note:inexpansionofmacro'ngx_quic_varint_len'len=ngx_quic_varint_len(sf->type);^cc1:allwarningsbeingtreatedaserrorsmake[1]:***[objs/src/event/ngx_event_quic_transport.o]Error1make[1]:Leavingdirectory`/root/nginx-quic'make:***[build]Error2[root@iz2zehmi1ztqtx8tg6ca7gznginx-quic]#解决办法是:cdnginx-quic\objsviMakefile找到CFLAGS=-pipe-O-W-Wall-Wpointer-arith-Wno-unused-parameter-Werror-g-I../boringssl-master/include去掉-Werror参数reuseport只需要配置一次:如果有多个域名需要开启http3,建议只在根域名上配置reuseport。如果一个配置文件中出现多个reuseport,会报错。配置如下:server{listen443sslhttp2;#TCPlistenerforHTTP/2listen443http3reuseport;#UDPlistenerforQUIC+HTTP/3server_namewww.nihaoshijie.com.cndefault_server;}server{listen443sslhttp2;#TCPlistenerforHTTP/2listen443http3;#UDPlistenerforQUIC+HTTP/3server_nameapp.nihaoshijie.com.cndefault_server;}server;}编译安装过程中的性能问题:如果编译安装过程中报类似如下的错误,可能是宿主机内容不足,需要关闭一些正在运行的程序才能继续。...c++:internalcompilererror:Killed(programcc1plus)现在开始您的HTTP3之旅!
