Pages

Sunday, 22 November 2020

编译Nginx使网站支持QUIC-HTTP3

 网站支持HTTP3,有多种方法可以实现,比如直接用Caddy v2;或者手工编译Nginx,打入Cloudflare开发的quiche补丁;Nginx官方10号宣布支持HTTP3,于是又多出一种方法了。由于是Nginx老用户了,于是,分享打quiche补丁编译和官方编译Nginx-quic两种方法,以及博客配置的过程。

打补丁编译Nginx

首先是要下载Nginx和Cloudflare的quiche,但是实际编译中还需要cmake、go运行库、还有rust,咱们一步一步来。

下载nginx

Nginx官网:https://nginx.org/en/download.html

打开官网下载最新的nginx-1.19.0并解压:

wget -c https://nginx.org/download/nginx-1.19.0.tar.gz -O - | tar -xz

下载quiche

git clone --recursive https://github.com/cloudflare/quiche

下载go

下载go并解压到/usr/local路径下:

wget -c https://dl.google.com/go/go1.14.linux-amd64.tar.gz -O - | tar -xz -C /usr/local/

设置go环境变量,也可以写入到profile中

vi ~/.profile 写入下面内容:

1
2
3
4
5
export PATH=$PATH:/usr/local/go/bin
export PATH=$PATH:$HOME/.cargo/bin
export GOROOT=/usr/local/go
export GOBIN=$GOROOT/bin
export PATH=$PATH:$GOBIN

保存后,source ~/.profile

下载安装cmake

下载最新cmake,并编译安装:

1
2
3
4
5
6
#下载最新cmake
wget https://github.com/Kitware/CMake/releases/download/v3.16.8/cmake-3.16.8.tar.gz
#编译安装
tar zxf cmake-3.16.8.tar.gz && cd cmake-3.16.8 && ./bootstrap && make && make install
#创建软连接
ln -s /usr/local/bin/cmake /usr/bin/cmake

下载安装rust

curl https://sh.rustup.rs -sSf | sh

编译nginx

1
2
3
4
5
6
7
8
9
10
11
cd nginx-1.19.0
#打入quiche的path,官方说是支持nginx-1.16.1版,其实nginx-1.19.0版也是支持的
patch -p01 < ../quiche/extras/nginx/nginx-1.16.patch

#带插件编译nginx,这一步的路径和插件最好沿用老nginx的,以便无缝升级。
#nginx -V 查看老nginx路径和插件,复制下内容,然后加上下面的quiche插件就可以编译了。
#编译前应停止老版nginx,命令:systemctl stop nginx
./configure --prefix=$PWD --with-http_ssl_module --with-http_v2_module --with-http_v3_module --with-openssl=../quiche/deps/boringssl --with-quiche=../quiche
make
#最后一步make install是为了把文件打入指定路径,非必须执行
make install

编译好的Nginx二进制文件在/nginx-1.19.0/objs/文件夹里,或者直接在你编译时指定的路径里。

配置nginx.conf

vi /etc/nginx/nginx.conf

主要是在443端口下写入quic支持,和atl-svc响应头

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
events {
worker_connections 1024;
}

http {
server {
# 开启quic
listen 443 quic reuseport;

listen 443 ssl http2;
#证书路径
ssl_certificate cert.crt;
ssl_certificate_key cert.key;

#要支持quic必须要开启TLSv1.3
ssl_protocols TLSv1 TLSv1.1 TLSv1.2 TLSv1.3;

#Alt-Svc响应头
add_header alt-svc 'h3-27=":443"; ma=86400,h3-29=":443"; ma=86400';
}
}

保存,重启Nginx后,网站就应该支持HTTP/3了,可以按照下文的测试方法去测试一下。

下面分享编译官方Nginx-quic的方法:

编译官方Nginx-quic

首先放出nginx-quic官方网站:

https://hg.nginx.org/nginx-quic

因为官方用的也是BoringSSL库,所以可以借用上面quiche插件里面的BoringSSL,编译环境可参照上面,主要也就是cmake、go运行库、还有rust.

下载nginx-quic

下载并解压nginx-quic

wget -c https://hg.nginx.org/nginx-quic/archive/tip.tar.gz -O - | tar -xz

下载BoringSSL库

1
2
3
4
5
6
git clone https://boringssl.googlesource.com/boringssl
cd boringssl/
mkdir build
cd build/
cmake ..
make

如果你上面下载了quiche插件,这一步其实是不需要的,下面编译可以借用quiche里面的BoringSSL库。

编译nginx-quic

1
2
3
4
5
6
7
8
cd nginx-quic
#带插件编译nginx,这一步的路径和插件最好沿用老nginx的,以便无缝升级,编译前应停止老版nginx
#nginx -V 查看老nginx路径和插件,复制下内容,然后加上下面的boringssl就可以编译了
#boringssl库路径是沿用上面quiche文件夹里面的,如果是单独下载的BoringSSL,修改下路径就好了
./auto/configure --with-debug --with-http_v3_module --with-cc-opt="-I../quiche/deps/boringssl/include" --with-ld-opt="-L../quiche/deps/boringssl/build/ssl -L../quiche/deps/boringssl/build/crypto"
make
#最后一步make install是为了把文件打入指定路径,非必须执行
make install

nginx-quic配置nginx.conf

vi /etc/nginx/nginx.conf

主要是在443端口下写入http3支持,和atl-svc响应头

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
27
28
29
events {
worker_connections 1024;
}

http {
#http3日志记录
log_format quic '$remote_addr - $remote_user [$time_local] '
'"$request" $status $body_bytes_sent '
'"$http_referer" "$http_user_agent" "$quic" "$http3"';

error_log /var/log/nginx/error.log crit;
access_log /var/log/nginx/access.log quic;

server {
# 开启http3,注意这一步不同于上面,上面填写的是quic
listen 443 http3 reuseport;

listen 443 ssl http2;
#证书路径
ssl_certificate cert.crt;
ssl_certificate_key cert.key;

#要支持quic必须要开启TLSv1.3
ssl_protocols TLSv1.2 TLSv1.3;

#Alt-Svc响应头,注意这个响应头填写也不同于上面
add_header alt-svc '$http3=":443"; ma=86400';
}
}

启动nginx后,网站就应该支持http3了,可以按照下面方法测试一下。

测试HTTP/3支持

UDP端口测试

QUIC-HTTP/3是基于UDP协议的,因此需要开放服务器的UDP 443端口,一般服务器是默认开放的,可以检测一下自己的UDP 443端口是否开放?服务端检查443端口命令:

netstat -anp | grep "443"

如果udp 443端口没有开放给nginx,那么可以使用iptables开放443端口:

1
2
3
4
5
iptables -I INPUT -p udp --dport 443 -j ACCEPT

service iptables save

service iptables restart

或者,在本地电脑上,执行下面的命令:

nc -v -u 1.2.3.4 443

其中,1.2.3.4为您的服务器IP地址,若收到类似下面的回显,则说明进入服务器的UDP 443端口开放了。

Connection to 1.2.3.4 443 port [udp/*] succeeded!

然后,再测试一下出服务器的UDP 443端口。在服务器上执行下面的命令:

nc -v -u google.com 443

如果收到类似下面的回显,说明设置成功。

Connection to google.com 443 port [udp/*] succeeded!

网站测试

目前,有两个网站可以用来测试我们的网站是否支持QUIC-HTTP/3。

这两个网站分别是:

https://gf.dev/http3-test

https://http3check.net/

输入自己的域名即可测试网站是不是支持http/3

浏览器开启http3

Firefox开启http3

首先在火狐地址栏输入:about:config

然后搜索http3,找到network.http.http3.enabled 把 false 改成 true,重启、就可以了。

Chrome canary开启http3

注意,只有金丝雀版chrome才支持http3,在地址栏输入 chrome://flags/

搜索quic,找到Experimental QUIC protocolDefault改成Enabled,重启浏览器。

然后,在Chrome canary的快捷方式,右键、属性,在目标栏尾处添加--enable-quic --quic-version=h3-29 即可。

最后,在浏览支持http3的网站时,按f12键可以查看网络、协议显示为HTTP/3或者h3-29.

注:本文说的HTTP/3指的是IETF QUIC,而非Google QUIC,这两个,现阶段是完全不同的分支。文中说的Cloudflare的quiche补丁只支持IETF QUIC,还没有支持Google QUIC,所以IETF QUIC在Google Chrome浏览器中并不被很好地支持,需要指定启动项,当然它自家的Google QUIC倒是支持的很好。最新版火狐是直接走IETF QUIC的HTTP3的,且支持得很好。

参考:

-----------------------------

浏览器如何开启 HTTP3/QUIC 

HTTP/2 和 HTTP/3 之间的主要区别在于它们使用的传输协议。HTTP/3 使用一种称为QUIC的新协议来代替 TCP 。

QUIC(Quick UDP Internet Connection)是谷歌制定的一种基于UDP的低时延的互联网传输层协议。我们知道,TCP/IP协议族是互联网的基础。其中传输层协议包括TCP和UDP协议。与TCP协议相比,UDP更为轻量,但是错误校验也要少得多。这意味着UDP往往效率更高(不经常跟服务器端通信查看数据包是否送达或者按序),但是可靠性比不上TCP。通常游戏、流媒体以及VoIP等应用均采用UDP,而网页、邮件、远程登录等大部分的应用均采用TCP。

QUIC很好地解决了当今传输层和应用层面临的各种需求,包括处理更多的连接,安全性,和低延迟。QUIC融合了包括TCP,TLS,HTTP/2等协议的特性,但基于UDP传输。QUIC的一个主要目标就是减少连接延迟,当客户端第一次连接服务器时,QUIC只需要1RTT(Round-Trip Time)的延迟就可以建立可靠安全的连接,相对于TCP+TLS的1-3次RTT要更加快捷。之后客户端可以在本地缓存加密的认证信息,再次与服务器建立连接时可以实现0-RTT的连接建立延迟。QUIC同时复用了HTTP/2协议的多路复用功能(Multiplexing),但由于QUIC基于UDP所以避免了HTTP/2的队头阻塞(Head-of-Line Blocking)问题。因为QUIC基于UDP,运行在用户域而不是系统内核,使得QUIC协议可以快速的更新和部署,从而很好地解决了TCP协议部署及更新的困难。

 

QUIC 特点

  • 降低了连接建立时延
  • 改进了握手控制
  • 多路复用
  • 避免线头阻塞
  • 前向纠错
  • 连接迁移
  • 默认使用 TLS 1.3 作为全链路安全

 

总的说来开启HTTP3/QUIC会使我们更快打开网站服务等,不过这个是需要双向支持才可以,需要网站和用户的浏览器同时开启HTTP3/QUIC。

恰好本站支持HTTP3/QUIC,为了更快的访问本站,各位用户可以在浏览器开启HTTP3/QUIC支持,目前支持HTTP3/QUIC的浏览器有:Firefox、Chrome、Microsoft Edge(基于Chromium)

使用以后比传统的HTTP1.1和HTTP2协议要快不少,推荐大家使用。目前HTTP3/QUIC目前尚未大规模普及,各大主流浏览器默认也并没有打开相关选项,用户在浏览网页时默认仍然使用HTTP1.1和HTTP2协议,需要手动打开选项使浏览器在发现网站支持HTTP3/QUIC时尝试使用该协议。

 

Firefox 75 及以上版本已支持 HTTP3/QUIC,在地址栏输入 about:config,配置 network.http.http3.enabled = true

Chrome 83 及以上版本支持 HTTP/3,地址栏输入chrome://flags#enable-quic,配置为 Enabled 重启浏览器即可

Microsoft Edge(基于Chromium)与 Chrome 同步支持,地址栏输入 edge://flags#enable-quic,配置为 Enabled 重启浏览器即可.

 

 

 

No comments:

Post a Comment