HTTP3.0, also known as HTTP over QUIC. The core is QUIC(pronunciation quick) protocol, proposed by Google in 2015 SPDY V3 evolved from the new protocol, the traditional HTTP protocol is based on the transport layer TCP protocol, and QUIC is based on the transport layer UDP protocol, can be defined as: HTTP3.0 Is a UDP based secure and reliable HTTP2.0 protocol that has the following features:

  • UDP – based reduces the TCP three-way handshake and TLS handshake time
  • Solve the problem of line end blocking when multiplex packet loss
  • Optimized the retransmission policy
  • Flow control
  • Connect the migration

For a detailed explanation of HTTP3.0, I will not go into more detail here. For those interested in this article, please refer to my previous article the History of HTTP (HTTP1.1, HTTPS, SPDY, HTTP2.0, QUIC, HTTP3.0). This article focuses on how to enable HTTP3.0 support in Nginx.

Scheme selection

As for HTTP3.0, the protocol is still in draft phase and there is no complete standard yet, so browser vendors are only supporting developer versions of Chrome, such as Chrome Canary, and server vendors are following suit. For Nginx, There are two options available to support HTTP3.0:

  • Based on Cloudflare’s branch version of Nginx: Cloudflare has always been at the forefront of HTTP3.0/QUIC by developing a branch from Nginx and compiling an Nginx server that supports HTTP3.0 with the help of its own open source project, QUIC.
  • Nginx official NGINX-QUIC Project: On June 10, Nginx announced that it was working on HTTP3.0/QUIC support. The current project is being maintained at Nginx-Quic, which has nothing to do with Cloudflare’s NGinx-based branch.

Based on this, this article will deploy Nginx-Quic to make Nginx support HTTP3.0/ Quic.

Transformation process

Our ultimate goal is to get nginx-quic version of nginx executable file, need to go through a series of installation and compilation, during may encounter a lot of problems, if you do not want to actually operate, you can directly use my compiled version of nginx-quic.linux-x86_64.zip portal.

Preparations:

Nginx-quic relies on boringSSL, so you need to download the boringSSL source portal, and then you need to compile and install boringSSL. Before you do this, To install some front modules on Linux, use yum to install them, run the following command:

sudo yum install build-essential mercurial psmisc lsb-release cmake golang libunwind-dev git libpcre3-dev zlib1g-dev
Copy the code

What is boringSSL:

For Nginx, the SSL library must be configured at compile time. Whether it is HTTP3.0 or HTTP2.0, it must always be based on HTTPS. The encryption algorithm is mainly provided by OpenSSL, and BoringSSL is a branch of OpenSSL created by Google. The UDP 0-RTT encryption algorithm is used to support TLS1.3 data transmission. Some features of BoringSSL are synchronized to OpenSSl when appropriate.

Compile and install boringSSL:

cd boringssl-master/
mkdir build
cdbuild cmake .. / makeCopy the code

After execution, can be inbuild/crypto, andbuild/sslGet the corresponding file, as shown in the figure below:

Note that compiling and installing boringSSL requires a version above cMake3.

Install 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
Copy the code

After the command is executed, the corresponding nginx executable file is generated in the /root/nginx directory, as shown in the following figure:

The configuration file is in conf/, and the nginx command is in sbin/.

Modify the configuration file to start nginx:

vi /root/nginx/conf/nginx.conf
Copy the code

Add http3 configuration:

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"; h3-27=":443"; h3-25=":443"; h3-T050=":443"; h3-Q050=":443"; h3-Q049=":443"; h3-Q048=":443"; h3-Q046=":443"; h3-Q043=":443"'; # Advertise that QUIC is available }Copy the code

TLSv1.3 is required, and http2 can be used if the browser does not support HTTP3. In addition, add_header Alt-svc is indispensable to add this return header.

  • The full name of alt-SVC is “alternative-service”, which literally means “Alternative Service”. This header lists the alternative access methods for the current site, allowing the server to tell the client “Look, I’m providing the same service with this protocol on this port on this host.” Generally used to provide support for emerging protocols such as “QUIC” while achieving downward compatibility. Refer to the MDN.

Verify HTTP3 in effect:

Since browsers currently have limited support for HTTP3.0/QUIC, you can verify that your site has successfully enabled HTTP3 by using http3check.net/, as in my case:

Pit some summary

The whole process seems very simple, but the real configuration process encountered a lot of pits, the front and back and the search problems took a day and a half to really solve, record these problems, and share with everyone.

Enable UDP port 443:

The QUic protocol uses UDP port 443, which is disabled for Centos7 by default. You can enable this port by running the following command:

firewall-cmd --zone=public --add-port=443/udp --permanent
Copy the code

If the project is hosted on Aliyun, the security group policy of ECS needs to be updated to enable the corresponding protocol and port, as shown in the figure below:

The TLS version is backward compatible:

The nginx configuration file uses TLS 1.3, so the encryption algorithm will be modified. However, some browsers do not support such a high version, especially Apple’s Safari. Therefore, the nginx configuration file should be configured with several versions of backward compatibility.

Ssl_protocols TLSv1 TLSv1.1 TLSv1.2 TLSv1.3;Copy the code

-werror Error:

When compiling nginx-quic, the following error is sometimes encountered:

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]#Copy the code

The solution:

cd nginx-quic\objs

vi Makefile

Copy the code

CFLAGS = -pipe -o-w -wall -wpointer-arith -wno-unused-parameter -werror -g -i… /boringssl-master/include removes the -werror parameter.

You only need to configure reusePort once:

If you need to enable http3 for multiple domain names, you are advised to configure reusePort only on the root domain name. If multiple reusePorts are displayed in a configuration file, an error message is displayed. Therefore, configure http3 as follows:

    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;

    }
Copy the code

Performance issues when compiling an installation:

If the compilation and installation times similar to the following error, may be the host content is insufficient, you need to close some running programs to and from the next.

. c++: internal compiler error: Killed (program cc1plus)Copy the code

Start your HTTP3 journey, code words are not easy, if this article has helped you, give it a like