searchusermenu
  • 发布文章
  • 消息中心
点赞
收藏
评论
分享
原创

Nginx QUIC模块的编译和测试

2023-06-28 03:08:48
479
0

一、简介

Nginx在1.25.0版本将nginx-quic分支正式合入主线,标志着Nginx主线版本也可以支持IETF QUIC和HTTP/3协议。QUIC和HTTP/3协议的关系如下图所示:

(图片来源:https://en.wikipedia.org/wiki/QUIC

QUIC协议在UDP层之上实现了可靠传输+加密,相当于HTTPS的TCP+TLS层。HTTP/3协议基于QUIC协议,在QUIC层之上实现了HTTP语义。

Nginx在1.25.0新增quic核心模块,用于实现QUIC协议栈、连接管理、事件管理功能。新增ngx_http_v3_module模块,用于实现HTTP/3协议。由于Nginx主要用于HTTP服务器,本文主要测试Nginx HTTP/3协议的功能。

 

二、编译quictls密码库

Nginx实现QUIC协议需要依赖特定TLS库。目前可使用TLS库主要有BoringSSLLibreSSL, QuicTLS等库。QuicTLS库对OpenSSL的兼容性最好、编译相对简单。本文使用QuicTLS作为Nginx的TLS库。

2.1 下载quictls源代码

quictls的项目位于https://github.com/quictls/openssl,quictls对OpenSSL官方各主要发行版做了QUIC API的适配。可根据使用的OpenSSL版本选择quictls版本。本文使用OpenSSL_1_1_1u的quictls版本,下载链接如下:

https://github.com/quictls/openssl/releases/tag/OpenSSL_1_1_1u-quic1

2.2 编译和安装

解压quictls代码,然后执行编译安装:

cd openssl-OpenSSL_1_1_1u-quic1/

./config no-shared --prefix=/usr/local/OpenSSL_1_1_1u-quic1

make -j `nproc`

make install_sw

完成后,quictls安装到/usr/local/OpenSSL_1_1_1u-quic1目录下。

三、编译Nginx

3.1 下载Nginx代码

Nginx的项目位于https://github.com/nginx/nginx,Nginx从1.25.0开始正式支持QUIC和HTTP/3。本文使用1.25.1版本,下载链接如下:

https://github.com/nginx/nginx/releases/tag/release-1.25.1

3.2 编译和安装

解压Nginx代码,然后执行编译安装:

cd nginx-release-1.25.1

auto/configure --prefix=/usr/local/nginx-quic --with-debug --with-http_ssl_module --with-http_v3_module --with-cc-opt=-I/usr/local/OpenSSL_1_1_1u-quic1/include --with-ld-opt='-L/usr/local/OpenSSL_1_1_1u-quic1/lib/'

make -j `nproc`

make install

完成后,Nginx安装到/usr/local/nginx-quic目录下。

四、配置和启动nginx

(1)在/usr/local/nginx-quic/conf/目录下,新建http3_test.conf配置文件。listen 8443 quic表示Nginx监听UDP 8443实现QUIC协议;listen 8443 ssl表示Nginx监听TCP 8443端口实现HTTPS协议。

server {
        # for better compatibility it's recommended
        # to use the same port for quic and https
        listen 8443 quic reuseport;
        listen 8443 ssl reuseport;

        ssl_certificate     certs/test.crt;
        ssl_certificate_key certs/test.key;

        location / {
            # required for browsers to direct them to quic port
            add_header Alt-Svc 'h3=":8443"; ma=86400';
        }
    }

 

(2)修改/usr/local/nginx-quic/conf/nginx.conf文件,在http配置块增加一行配置:

include http3_test.conf;

(3)切换到/usr/local/nginx-quic/sbin目录,启动Nginx

(4)观察Nginx启动进程和监听端口成功

[root@localhost sbin]# ps -aux|grep nginx
root       21743  0.0  0.0   8896  5488 ?        Ss   16:04   0:00 nginx: master process ./nginx
nobody     21785  0.0  0.0   9664  6264 ?        S    16:06   0:00 nginx: worker process
nobody     21786  0.0  0.0   9760  6476 ?        S    16:06   0:00 nginx: worker process
nobody     21787  0.0  0.0   9664  3436 ?        S    16:06   0:00 nginx: worker process

 

[root@localhost sbin]# ss -an|grep 8443
udp   UNCONN 0      0                                         0.0.0.0:8443              0.0.0.0:*
udp   UNCONN 0      0                                         0.0.0.0:8443              0.0.0.0:*
udp   UNCONN 0      0                                         0.0.0.0:8443              0.0.0.0:*
tcp   LISTEN 0      511                                       0.0.0.0:8443              0.0.0.0:*
tcp   LISTEN 0      511                                       0.0.0.0:8443              0.0.0.0:*
tcp   LISTEN 0      511                                       0.0.0.0:8443              0.0.0.0:*

 

五、编译测试客户端

本文选择curl作为quic测试客户端。curl的QUIC和HTTP/3实现依赖quictls、nghttp3、ngtcp2库,分别对其进行编译和安装。

5.1 编译nghttp3

(1)下载nghttp3源代码

本文使用nghttp3-0.12.0版本,下载链接:https://github.com/ngtcp2/nghttp3/releases/tag/v0.12.0

(2)编译和安装nghttp3库

cd nghttp3-0.12.0

autoreconf –i

./configure --prefix=/usr/local/nghttp3-0.12.0 --enable-lib-only

make -j `nproc`

make install

完成后,nghttp3安装到/usr/local/nghttp3-0.12.0/目录下。

 

5.2 编译ngtcp2

(1)下载ngtcp2源代码

本文使用ngtcp2-0.16.0版本,下载链接:https://github.com/ngtcp2/ngtcp2/releases/tag/v0.16.0

(2)编译和安装ngtcp2库

cd ngtcp2-0.16.0

autoreconf –i

./configure PKG_CONFIG_PATH=/usr/local/OpenSSL_1_1_1u-quic1/lib/pkgconfig:/usr/local/nghttp3-0.12.0/lib/pkgconfig LDFLAGS="-Wl,-rpath,/usr/local/OpenSSL_1_1_1u-quic1/lib" --prefix=/usr/local/ngtcp2-0.16.0

make -j `nproc`

make install

完成后,ngtcp2安装到/usr/local/ngtcp2-0.16.0/目录下。

5.3 编译curl

(1)下载curl源代码

本文使用curl master分支的最新代码(8.2.0-dev版本),下载链接:https://github.com/curl/curl/archive/refs/heads/master.zip

(2)编译和安装curl

cd curl-master

autoreconf -fi

LDFLAGS="-Wl,-rpath,/usr/local/OpenSSL_1_1_1u-quic1/lib" ./configure --with-openssl=/usr/local/OpenSSL_1_1_1u-quic1/ --with-nghttp3=/usr/local/nghttp3-0.12.0/ --with-ngtcp2=/usr/local/ngtcp2-0.16.0/ --prefix=/usr/local/curl-8.2.0-dev

make -j `nproc`

make install

完成后,curl安装到/usr/local/curl-8.2.0-dev/目录下。

六、QUIC功能测试

使用curl客户端测试Nginx 8443端口,命令如下:

cd /usr/local/curl-8.2.0-dev/bin/

# 使用HTTPS发起请求,观察到输出HTTP/1.1 200 OK,说明使用HTTPS协议。
./curl https://127.0.0.1:8443 -kv

# 使用HTTP3发起请求,观察到输出HTTP/3 200,说明使用HTTP/3协议。
./curl --http3 https://127.0.0.1:8443 -kv

# 使用alt-svc发起请求,首次请求使用HTTPS协议,再次请求自动切换为HTTP/3协议。
./curl --alt-svc altsvc.cache https://127.0.0.1:8443 -kv

 

七、抓包分析

使用tcpdump抓包,使用quictls提供的sslkeylog功能导出tls主密钥,使用wireshark观察QUIC报文。

(1)导出tls主密钥

配置SSLKEYLOGFILE环境变量export SSLKEYLOGFILE=quic_keylog_file

再次使用curl客户端访问,会再当前目录生成保存有tls主密钥的quic_keylog_file文件。

(2)使用tcpdump抓包

tcpdump -i lo udp port 8443 -w quic.pcap

(3)将quic.pcap和quic_keylog_file导入wireshark

在wireshark 【Prefences】->【Protocols】->【TLS】->【Master-Secret log filename】导入quic_keylog_file,然后打开quic.pcap。wireshark会自动对流量解密。

八、参考链接

(1)nginx quic介绍 http://nginx.org/en/docs/quic.html

(2)QUIC RFC https://datatracker.ietf.org/doc/html/rfc9000

(3)HTTP/3 RFC https://datatracker.ietf.org/doc/html/rfc9114

(4)curl支持HTTP/3介绍 https://github.com/curl/curl/blob/master/docs/HTTP3.md

0条评论
0 / 1000
唐****枭
1文章数
0粉丝数
唐****枭
1 文章 | 0 粉丝
唐****枭
1文章数
0粉丝数
唐****枭
1 文章 | 0 粉丝
原创

Nginx QUIC模块的编译和测试

2023-06-28 03:08:48
479
0

一、简介

Nginx在1.25.0版本将nginx-quic分支正式合入主线,标志着Nginx主线版本也可以支持IETF QUIC和HTTP/3协议。QUIC和HTTP/3协议的关系如下图所示:

(图片来源:https://en.wikipedia.org/wiki/QUIC

QUIC协议在UDP层之上实现了可靠传输+加密,相当于HTTPS的TCP+TLS层。HTTP/3协议基于QUIC协议,在QUIC层之上实现了HTTP语义。

Nginx在1.25.0新增quic核心模块,用于实现QUIC协议栈、连接管理、事件管理功能。新增ngx_http_v3_module模块,用于实现HTTP/3协议。由于Nginx主要用于HTTP服务器,本文主要测试Nginx HTTP/3协议的功能。

 

二、编译quictls密码库

Nginx实现QUIC协议需要依赖特定TLS库。目前可使用TLS库主要有BoringSSLLibreSSL, QuicTLS等库。QuicTLS库对OpenSSL的兼容性最好、编译相对简单。本文使用QuicTLS作为Nginx的TLS库。

2.1 下载quictls源代码

quictls的项目位于https://github.com/quictls/openssl,quictls对OpenSSL官方各主要发行版做了QUIC API的适配。可根据使用的OpenSSL版本选择quictls版本。本文使用OpenSSL_1_1_1u的quictls版本,下载链接如下:

https://github.com/quictls/openssl/releases/tag/OpenSSL_1_1_1u-quic1

2.2 编译和安装

解压quictls代码,然后执行编译安装:

cd openssl-OpenSSL_1_1_1u-quic1/

./config no-shared --prefix=/usr/local/OpenSSL_1_1_1u-quic1

make -j `nproc`

make install_sw

完成后,quictls安装到/usr/local/OpenSSL_1_1_1u-quic1目录下。

三、编译Nginx

3.1 下载Nginx代码

Nginx的项目位于https://github.com/nginx/nginx,Nginx从1.25.0开始正式支持QUIC和HTTP/3。本文使用1.25.1版本,下载链接如下:

https://github.com/nginx/nginx/releases/tag/release-1.25.1

3.2 编译和安装

解压Nginx代码,然后执行编译安装:

cd nginx-release-1.25.1

auto/configure --prefix=/usr/local/nginx-quic --with-debug --with-http_ssl_module --with-http_v3_module --with-cc-opt=-I/usr/local/OpenSSL_1_1_1u-quic1/include --with-ld-opt='-L/usr/local/OpenSSL_1_1_1u-quic1/lib/'

make -j `nproc`

make install

完成后,Nginx安装到/usr/local/nginx-quic目录下。

四、配置和启动nginx

(1)在/usr/local/nginx-quic/conf/目录下,新建http3_test.conf配置文件。listen 8443 quic表示Nginx监听UDP 8443实现QUIC协议;listen 8443 ssl表示Nginx监听TCP 8443端口实现HTTPS协议。

server {
        # for better compatibility it's recommended
        # to use the same port for quic and https
        listen 8443 quic reuseport;
        listen 8443 ssl reuseport;

        ssl_certificate     certs/test.crt;
        ssl_certificate_key certs/test.key;

        location / {
            # required for browsers to direct them to quic port
            add_header Alt-Svc 'h3=":8443"; ma=86400';
        }
    }

 

(2)修改/usr/local/nginx-quic/conf/nginx.conf文件,在http配置块增加一行配置:

include http3_test.conf;

(3)切换到/usr/local/nginx-quic/sbin目录,启动Nginx

(4)观察Nginx启动进程和监听端口成功

[root@localhost sbin]# ps -aux|grep nginx
root       21743  0.0  0.0   8896  5488 ?        Ss   16:04   0:00 nginx: master process ./nginx
nobody     21785  0.0  0.0   9664  6264 ?        S    16:06   0:00 nginx: worker process
nobody     21786  0.0  0.0   9760  6476 ?        S    16:06   0:00 nginx: worker process
nobody     21787  0.0  0.0   9664  3436 ?        S    16:06   0:00 nginx: worker process

 

[root@localhost sbin]# ss -an|grep 8443
udp   UNCONN 0      0                                         0.0.0.0:8443              0.0.0.0:*
udp   UNCONN 0      0                                         0.0.0.0:8443              0.0.0.0:*
udp   UNCONN 0      0                                         0.0.0.0:8443              0.0.0.0:*
tcp   LISTEN 0      511                                       0.0.0.0:8443              0.0.0.0:*
tcp   LISTEN 0      511                                       0.0.0.0:8443              0.0.0.0:*
tcp   LISTEN 0      511                                       0.0.0.0:8443              0.0.0.0:*

 

五、编译测试客户端

本文选择curl作为quic测试客户端。curl的QUIC和HTTP/3实现依赖quictls、nghttp3、ngtcp2库,分别对其进行编译和安装。

5.1 编译nghttp3

(1)下载nghttp3源代码

本文使用nghttp3-0.12.0版本,下载链接:https://github.com/ngtcp2/nghttp3/releases/tag/v0.12.0

(2)编译和安装nghttp3库

cd nghttp3-0.12.0

autoreconf –i

./configure --prefix=/usr/local/nghttp3-0.12.0 --enable-lib-only

make -j `nproc`

make install

完成后,nghttp3安装到/usr/local/nghttp3-0.12.0/目录下。

 

5.2 编译ngtcp2

(1)下载ngtcp2源代码

本文使用ngtcp2-0.16.0版本,下载链接:https://github.com/ngtcp2/ngtcp2/releases/tag/v0.16.0

(2)编译和安装ngtcp2库

cd ngtcp2-0.16.0

autoreconf –i

./configure PKG_CONFIG_PATH=/usr/local/OpenSSL_1_1_1u-quic1/lib/pkgconfig:/usr/local/nghttp3-0.12.0/lib/pkgconfig LDFLAGS="-Wl,-rpath,/usr/local/OpenSSL_1_1_1u-quic1/lib" --prefix=/usr/local/ngtcp2-0.16.0

make -j `nproc`

make install

完成后,ngtcp2安装到/usr/local/ngtcp2-0.16.0/目录下。

5.3 编译curl

(1)下载curl源代码

本文使用curl master分支的最新代码(8.2.0-dev版本),下载链接:https://github.com/curl/curl/archive/refs/heads/master.zip

(2)编译和安装curl

cd curl-master

autoreconf -fi

LDFLAGS="-Wl,-rpath,/usr/local/OpenSSL_1_1_1u-quic1/lib" ./configure --with-openssl=/usr/local/OpenSSL_1_1_1u-quic1/ --with-nghttp3=/usr/local/nghttp3-0.12.0/ --with-ngtcp2=/usr/local/ngtcp2-0.16.0/ --prefix=/usr/local/curl-8.2.0-dev

make -j `nproc`

make install

完成后,curl安装到/usr/local/curl-8.2.0-dev/目录下。

六、QUIC功能测试

使用curl客户端测试Nginx 8443端口,命令如下:

cd /usr/local/curl-8.2.0-dev/bin/

# 使用HTTPS发起请求,观察到输出HTTP/1.1 200 OK,说明使用HTTPS协议。
./curl https://127.0.0.1:8443 -kv

# 使用HTTP3发起请求,观察到输出HTTP/3 200,说明使用HTTP/3协议。
./curl --http3 https://127.0.0.1:8443 -kv

# 使用alt-svc发起请求,首次请求使用HTTPS协议,再次请求自动切换为HTTP/3协议。
./curl --alt-svc altsvc.cache https://127.0.0.1:8443 -kv

 

七、抓包分析

使用tcpdump抓包,使用quictls提供的sslkeylog功能导出tls主密钥,使用wireshark观察QUIC报文。

(1)导出tls主密钥

配置SSLKEYLOGFILE环境变量export SSLKEYLOGFILE=quic_keylog_file

再次使用curl客户端访问,会再当前目录生成保存有tls主密钥的quic_keylog_file文件。

(2)使用tcpdump抓包

tcpdump -i lo udp port 8443 -w quic.pcap

(3)将quic.pcap和quic_keylog_file导入wireshark

在wireshark 【Prefences】->【Protocols】->【TLS】->【Master-Secret log filename】导入quic_keylog_file,然后打开quic.pcap。wireshark会自动对流量解密。

八、参考链接

(1)nginx quic介绍 http://nginx.org/en/docs/quic.html

(2)QUIC RFC https://datatracker.ietf.org/doc/html/rfc9000

(3)HTTP/3 RFC https://datatracker.ietf.org/doc/html/rfc9114

(4)curl支持HTTP/3介绍 https://github.com/curl/curl/blob/master/docs/HTTP3.md

文章来自个人专栏
文章 | 订阅
0条评论
0 / 1000
请输入你的评论
1
2