9.8 KiB
title: 【新坑待填】【半生肉】让nginx支持HTTP3.0/QUIC author: lensfrex cover: 'https://res.ciduid.top/blog/covers/cover(13).png' tags: [] categories: [] date: 2022-06-20 20:15:00
Experimental QUIC support for nginx
Nginx对QUIC的实验性支持
-
Introduction | 介绍
-
Installing | 安装
-
Configuration | 配置
-
Clients | 客户端
-
Troubleshooting | 问题排查
-
Contributing | 向该项目贡献
-
Links | 相关链接
Introduction | 介绍
This is an experimental QUIC[1] / HTTP/3[2] support for nginx. The code is developed in a separate "quic" branch available at https://hg.nginx.org/nginx-quic. Currently it is based on nginx mainline 1.21.x.We merge new nginx releases into this branch regularly.
这里是nginx的QUIC/HTTP3实验性支持,作为nginx的独立分支“quic”上开发,其源代码可在https://hg.nginx.org/nginx-quic 上获取。目前nginx-quic代码基于nginx主线1.21.x版本开发,我们会定期将新版本的nginx代码合并到这个分支上。
The project code base is under the same BSD license as nginx. The code is currently at a beta level of quality and should not be used in production.
跟nginx一样,nginx-quic使用BSD许可证作为其开源许可证。由于还处于beta开发阶段,因此并不建议您在生产环境中使用nginx-quic。
We are working on improving HTTP/3 support with the goal of integrating it to the main NGINX codebase. Expect frequent updates of this code and don't rely on it for whatever purpose. We'll be grateful for any feedback and code submissions however we don't bear any responsibilities for any issues with this code.
我们正致力于提高nginx对HTTP/3的支持,并且将其整合进nginx的主线中。需要注意的是,nginx-quic的代码会频繁地更新,不论有什么原因都请不要太依赖这些更新。我们欢迎各种反馈和代码的提交,但是我们不会对这些代码产生的问题负责。
You can always contact us via nginx-devel mailing list [3]. 您当然也可以通过nginx-devel邮件列表来跟我们联系。
What works now: 现在nginx-quic在做什么:
We support IETF QUIC version 1. Internet drafts are no longer supported. nginx-quic支持IEIF quic标准(第一版)。草案版本已经不再受支持。
nginx should be able to respond to HTTP/3 requests over QUIC and it should be possible to upload and download big files without errors. nginx应当支持响应以quic为基础的HTTP/3请求,并且能传输大文件不出错
- The handshake completes successfully
- One endpoint can update keys and its peer responds correctly
- 0-RTT data is being received and acted on
- Connection is established using TLS Resume Ticket
- A handshake that includes a Retry packet completes successfully
- Stream data is being exchanged and ACK'ed
- An H3 transaction succeeded
- One or both endpoints insert entries into dynamic table and subsequently reference them from header blocks
- Version Negotiation packet is sent to client with unknown version
- Lost packets are detected and retransmitted properly
- Clients may migrate to new address
这段可真不好翻...
- 成功握手
- 个端点更新密钥并且它的对端正确响应
- 0-RTT数据被接受并处理
- 使用TLS Resume Ticket(TLS重连票据)建立连接
- 包含Retry数据包的握手成功完成
- 数据流交换和确认
- HTTP3交换完成
- 一个或两个端点在动态表中插入条目,随后在头块中引用它们
- 发送版本协商包到客户端,其使用的版本未知
- 检测丢失的数据包并且正确重传
- 客户端可能会迁移到新地址
Installing | 安装
You will need a BoringSSL [4] library that provides QUIC support 您需要BroingSSL库来获得quic支持
示例:
$ hg clone -b quic https://hg.nginx.org/nginx-quic
$ cd nginx-quic
$ ./auto/configure --with-debug --with-http_v3_module\
--with-cc-opt="-I../boringssl/include"\
--with-ld-opt="-L../boringssl/build/ssl \
-L../boringssl/build/crypto"
$ make
Alternatively, nginx can be configured with QuicTLS [5] 此外,您也可以使用QuicTLS:
$ ./auto/configure --with-debug --with-http_v3_module\
--with-cc-opt="-I../quictls/build/include" \
--with-ld-opt="-L../quictls/build/lib"
When configuring nginx, you can enable QUIC and HTTP/3 using the following new configuration options: 配置nginx-quic的编译选项时,使用以下configure脚本配置选项来使nginx-quic支持quic和HTTP/3:
--with-http_v3_module- enable QUIC and HTTP/3
--with-stream_quic_module - enable QUIC in Stream
Configuration | 配置
The HTTP "listen" directive got a new option "http3" which enables HTTP/3 over QUIC on the specified port. 在HTTP块中,listen指令有一个新的选项“http3”,能使其在指定的端口中支持http3-over-quic。
The Stream "listen" directive got a new option "quic" which enables QUIC as client transport protocol instead of TCP or plain UDP. 在Stream块中,listen指令有一个新的选项“http3”,能用quic作为客户端协议来传输数据而不是TCP或原生UDP。
Along with "http3" or "quic", you also have to specify "reuseport" option [6] to make it work properly with multiple workers. 除了“http3”或“quic”选项,您还要指定“reuseport”选项,使多个worker进程能够正常工作。
To enable address validation:
启用地址验证:
quic_retry on;
To enable 0-RTT:
启用0-RTT:
ssl_early_data on;
Make sure that TLS 1.3 is configured which is required for QUIC:
确保启用quic需要的TLS 1.3:
ssl_protocols TLSv1.3;
To enable GSO (Generic Segmentation Offloading):
quic_gso on;
To limit maximum UDP payload size on receive path:
quic_mtu <size>;
To set host key for various tokens:
quic_host_key <filename>;
By default, GSO Linux-specific optimization [8] is disabled. Enable if your network interface is configured to support GSO.
A number of directives were added that configure HTTP/3:
http3_stream_buffer_size
http3_max_concurrent_pushes
http3_max_concurrent_streams
http3_push
http3_push_preload
http3_hq (requires NGX_HTTP_V3_HQ macro)
In http, an additional variable is available: $http3.
The value of $http3 is "h3" for HTTP/3 connections, "hq" for hq connections, or an empty string otherwise.
In stream, an additional variable is available: $quic.
The value of $quic is "quic" if QUIC connection is used,or an empty string otherwise.
Example configuration:
http {
log_format quic '$remote_addr - $remote_user [$time_local] '
'"$request" $status $body_bytes_sent '
'"$http_referer" "$http_user_agent" "$http3"';
access_log logs/access.log quic;
server {
# for better compatibility it's recommended
# to use the same port for quic and https
listen 8443 http3 reuseport;
listen 8443 ssl;
ssl_certificatecerts/example.com.crt;
ssl_certificate_key certs/example.com.key;
ssl_protocols TLSv1.3;
location / {
# required for browsers to direct them into quic port
add_header Alt-Svc 'h3=":8443"; ma=86400';
}
}
}
Clients
- Browsers
Known to work: Firefox 90+ and Chrome 92+ (QUIC version 1)
Beware of strange issues: sometimes browser may decide to ignore QUIC Cache clearing/restart might help.Always check access.log and error.log to make sure you are using HTTP/3 and not TCP https.
- Console clients
Known to work: ngtcp2, firefox's neqo and chromium's console clients:
$ examples/client 127.0.0.1 8443 https://example.com:8443/index.html
$ ./neqo-client https://127.0.0.1:8443/
$ chromium-build/out/my_build/quic_client http://example.com:8443
If you've got it right, in the access log you should see something like:
127.0.0.1 - - [24/Apr/2020:11:27:29 +0300] "GET / HTTP/3" 200 805 "-" "nghttp3/ngtcp2 client" "quic"
Troubleshooting
Here are some tips that may help you to identify problems:
-
Ensure you are building with proper SSL library that supports QUIC
-
Ensure you are using the proper SSL library in runtime (
nginx -V
will show you what you are using) -
Ensure your client is actually sending requests over QUIC (see "Clients" section about browsers and cache)
We recommend to start with simple console client like ngtcp2 to ensure you've got server configured properly before trying with real browsers that may be very picky with certificates, for example.
-
Build nginx with debug support [7] and check your debug log. It should contain all details about connection and why it failed. All related messages contain "quic " prefix and can be easily filtered out.
-
If you want to investigate deeper, you may want to enable additional debugging in src/event/quic/ngx_event_quic_connection.h:
#define NGX_QUIC_DEBUG_PACKETS
#define NGX_QUIC_DEBUG_FRAMES
#define NGX_QUIC_DEBUG_ALLOC
#define NGX_QUIC_DEBUG_CRYPTO
Contributing
If you are willing to contribute, please refer to http://nginx.org/en/docs/contributing_changes.html
Links
[1] https://datatracker.ietf.org/doc/html/rfc9000 [2] https://datatracker.ietf.org/doc/html/rfc9114 [3] https://mailman.nginx.org/mailman3/lists/nginx-devel.nginx.org/ [4] https://boringssl.googlesource.com/boringssl/ [5] https://github.com/quictls/openssl [6] https://nginx.org/en/docs/http/ngx_http_core_module.html#listen [7] https://nginx.org/en/docs/debugging_log.html [8] http://vger.kernel.org/lpc_net2018_talks/willemdebruijn-lpc2018-udpgso-paper-DRAFT-1.pdf