Mercurial > hg > nginx
annotate README @ 8405:d2759e4cc437 quic
HTTP/3: split header parser in two functions.
The first one parses pseudo-headers and is analagous to the request line
parser in HTTP/1. The second one parses regular headers and is analogous to
the header parser in HTTP/1.
Additionally, error handling of client passing malformed uri is now fixed.
author | Roman Arutyunyan <arut@nginx.com> |
---|---|
date | Tue, 19 May 2020 15:29:10 +0300 |
parents | af22b60a905b |
children | c7d1b500bd0a |
rev | line source |
---|---|
8366 | 1 Experimental QUIC support for nginx |
2 ----------------------------------- | |
3 | |
4 1. Introduction | |
5 2. Installing | |
6 3. Configuration | |
7 4. Clients | |
8 5. Troubleshooting | |
9 6. Links | |
10 | |
11 1. Introduction | |
12 | |
13 This is an experimental QUIC [1] / HTTP/3 [2] support for nginx. | |
14 | |
15 The code is developed in a separate "quic" branch available | |
16 at https://hg.nginx.org/nginx-quic. Currently it is based | |
17 on nginx mainline 1.17.10. We are planning to merge new nginx | |
18 releases into this branch regularly. | |
19 | |
20 The project code base is under the same BSD license as nginx. | |
21 | |
22 The code is at an early alpha level of quality and should not | |
23 be used in production. | |
24 | |
25 We are working on improving HTTP/3 support with the goal of | |
26 integrating it to the main NGINX codebase. Expect frequent | |
27 updates of this code and don't rely on it for whatever purpose. | |
28 | |
29 We'll be grateful for any feedback and code submissions however | |
30 we don't bear any responsibilities for any issues with this code. | |
31 | |
32 You can always contact us via nginx-devel mailing list [3]. | |
33 | |
34 What works now: | |
35 | |
36 Currently we support IETF-QUIC draft 27 | |
37 Earlier drafts are NOT supported as they have incompatible wire format; | |
38 | |
39 nginx should be able to respond to simple HTTP/3 requests over QUIC and | |
40 it should be possible to upload and download big files without errors. | |
41 | |
42 + The handshake completes successfully | |
43 + One endpoint can update keys and its peer responds correctly | |
8390 | 44 + 0-RTT data is being received and acted on |
8366 | 45 + Connection is established using TLS Resume Ticket |
8389
2b580ac17a47
README: Retry support, protocol error messages implemented.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8373
diff
changeset
|
46 + A handshake that includes a Retry packet completes successfully |
8366 | 47 + Stream data is being exchanged and ACK'ed |
48 + An H3 transaction succeeded | |
49 + One or both endpoints insert entries into dynamic table and | |
50 subsequently reference them from header blocks | |
51 | |
52 Not (yet) supported features: | |
53 | |
54 - Version negotiation | |
55 - ECN, Congestion control and friends as specified in quic-recovery [5] | |
56 - A connection with the spin bit succeeds and the bit is spinning | |
57 - Structured Logging | |
58 - QUIC recovery (proper congestion and flow control) | |
59 - NAT Rebinding | |
60 - Address Mobility | |
61 - Server push | |
62 - HTTP/3 trailers | |
63 | |
64 Since the code is experimental and still under development, | |
65 a lot of things may not work as expected, for example: | |
66 | |
67 - ACK handling is basic: every received ack-eliciting packet | |
68 is acknowledged, no ack ranges are used | |
69 | |
70 - Flow control mechanism is basic and intended to avoid CPU hog and make | |
71 simple interactions possible | |
72 | |
73 - Not all draft requirements are strictly followed; some of checks are | |
74 omitted for the sake of simplicity of initial implementation | |
75 | |
76 2. Installing | |
77 | |
78 You will need a BoringSSL [4] library that provides QUIC support | |
79 | |
8373
796b5b6c43cd
Mention quic branch in README.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8372
diff
changeset
|
80 $ hg clone -b quic https://hg.nginx.org/nginx-quic |
8366 | 81 $ cd nginx-quic |
8372
0e6528551f26
Configure: unbreak with old OpenSSL, --with-http_v3_module added.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8366
diff
changeset
|
82 $ ./auto/configure --with-debug --with-http_v3_module \ |
0e6528551f26
Configure: unbreak with old OpenSSL, --with-http_v3_module added.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8366
diff
changeset
|
83 --with-cc-opt="-I../boringssl/include" \ |
0e6528551f26
Configure: unbreak with old OpenSSL, --with-http_v3_module added.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8366
diff
changeset
|
84 --with-ld-opt="-L../boringssl/build/ssl \ |
0e6528551f26
Configure: unbreak with old OpenSSL, --with-http_v3_module added.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8366
diff
changeset
|
85 -L../boringssl/build/crypto" |
8366 | 86 $ make |
87 | |
88 3. Configuration | |
89 | |
90 The "listen" directive got a new option: "http3" | |
91 which enables HTTP/3 over QUIC on the specified port. | |
92 | |
93 Along with "http3", you also have to specify "reuseport" option [6] | |
94 to make it work properly with multiple workers. | |
95 | |
96 A number of directives were added that specify transport parameter values: | |
97 | |
98 quic_max_idle_timeout | |
99 quic_max_ack_delay | |
100 quic_max_packet_size | |
101 quic_initial_max_data | |
102 quic_initial_max_stream_data_bidi_local | |
103 quic_initial_max_stream_data_bidi_remote | |
104 quic_initial_max_stream_data_uni | |
105 quic_initial_max_streams_bidi | |
106 quic_initial_max_streams_uni | |
107 quic_ack_delay_exponent | |
108 quic_active_migration | |
109 quic_active_connection_id_limit | |
110 | |
8402
af22b60a905b
README: documented Retry, 0-RTT, TLSv1.3 configuration.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8396
diff
changeset
|
111 To enable address validation: |
af22b60a905b
README: documented Retry, 0-RTT, TLSv1.3 configuration.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8396
diff
changeset
|
112 |
af22b60a905b
README: documented Retry, 0-RTT, TLSv1.3 configuration.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8396
diff
changeset
|
113 quic_retry on; |
af22b60a905b
README: documented Retry, 0-RTT, TLSv1.3 configuration.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8396
diff
changeset
|
114 |
af22b60a905b
README: documented Retry, 0-RTT, TLSv1.3 configuration.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8396
diff
changeset
|
115 To enable 0-RTT: |
af22b60a905b
README: documented Retry, 0-RTT, TLSv1.3 configuration.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8396
diff
changeset
|
116 |
af22b60a905b
README: documented Retry, 0-RTT, TLSv1.3 configuration.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8396
diff
changeset
|
117 ssl_early_data on; |
af22b60a905b
README: documented Retry, 0-RTT, TLSv1.3 configuration.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8396
diff
changeset
|
118 |
af22b60a905b
README: documented Retry, 0-RTT, TLSv1.3 configuration.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8396
diff
changeset
|
119 Make sure that TLS 1.3 is configured which is required for QUIC: |
af22b60a905b
README: documented Retry, 0-RTT, TLSv1.3 configuration.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8396
diff
changeset
|
120 |
af22b60a905b
README: documented Retry, 0-RTT, TLSv1.3 configuration.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8396
diff
changeset
|
121 ssl_protocols TLSv1.3; |
af22b60a905b
README: documented Retry, 0-RTT, TLSv1.3 configuration.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8396
diff
changeset
|
122 |
8366 | 123 Two additional variables are available: $quic and $http3. |
124 The value of $quic is "quic" if QUIC connection is used, | |
125 and empty string otherwise. The value of $http3 is a string | |
126 "h3-xx" where "xx" is the supported draft number. | |
127 | |
128 Example configuration: | |
129 | |
130 http { | |
131 log_format quic '$remote_addr - $remote_user [$time_local] ' | |
132 '"$request" $status $body_bytes_sent ' | |
133 '"$http_referer" "$http_user_agent" "$quic" "$http3"'; | |
134 | |
135 access_log logs/access.log quic; | |
136 | |
137 server { | |
138 # for better compatibility it's recommended | |
139 # to use the same port for quic and https | |
140 listen 8443 http3 reuseport; | |
141 listen 8443 ssl; | |
142 | |
143 ssl_certificate certs/example.com.crt; | |
144 ssl_certificate_key certs/example.com.key; | |
145 ssl_protocols TLSv1.3; | |
146 | |
147 location / { | |
148 # required for browsers to direct them into quic port | |
8396
94c06fe6e159
README: pointed out Alt-Svc "ma" parameter useful with curl.
Sergey Kandaurov <pluknet@nginx.com>
parents:
8395
diff
changeset
|
149 add_header Alt-Svc '$http3=":8443"; ma=86400'; |
8366 | 150 } |
151 } | |
152 } | |
153 | |
154 4. Clients | |
155 | |
156 * Browsers | |
157 | |
158 Known to work: Firefox 75+ and Chrome 83+ | |
159 | |
160 Beware of strange issues: sometimes browser may decide to ignore QUIC | |
161 Cache clearing/restart might help. Always check access.log and | |
162 error.log to make sure you are using HTTP/3 and not TCP https. | |
163 | |
164 + to enable QUIC in Firefox, set the following in 'about:config': | |
165 network.http.http3.enabled = true | |
166 | |
167 + to enable QUIC in Chrome, enable it on command line and force it | |
168 on your site: | |
169 | |
170 $ ./chrome --enable-quic --quic-version=h3-27 \ | |
171 --origin-to-force-quic-on=example.com:8443 | |
172 | |
173 * Console clients | |
174 | |
175 Known to work: ngtcp2, firefox's neqo and chromium's console clients: | |
176 | |
177 $ examples/client 127.0.0.1 8443 https://example.com:8443/index.html | |
178 | |
179 $ ./neqo-client https://127.0.0.1:8443/ | |
180 | |
181 $ chromium-build/out/my_build/quic_client http://example.com:8443 \ | |
182 --quic_version=h3-27 \ | |
183 --allow_unknown_root_cert \ | |
184 --disable_certificate_verification | |
185 | |
186 | |
187 If you've got it right, in the access log you should see something like: | |
188 | |
189 127.0.0.1 - - [24/Apr/2020:11:27:29 +0300] "GET / HTTP/3" 200 805 "-" | |
190 "nghttp3/ngtcp2 client" "quic" "h3-27" | |
191 | |
192 | |
193 5. Troubleshooting | |
194 | |
195 Here are some tips that may help you to identify problems: | |
196 | |
197 + Ensure you are building with proper SSL library that | |
198 implements draft 27 | |
199 | |
200 + Ensure you are using the proper SSL library in runtime | |
201 (`nginx -V` will show you what you are using) | |
202 | |
203 + Ensure your client is actually sending QUIC requests | |
204 (see "Clients" section about browsers and cache) | |
205 | |
206 We recommend to start with simple console client like ngtcp2 | |
207 to ensure you've got server configured properly before trying | |
8395 | 208 with real browsers that may be very picky with certificates, |
8366 | 209 for example. |
210 | |
211 + Build nginx with debug support [7] and check your debug log. | |
212 It should contain all details about connection and why it | |
213 failed. All related messages contain "quic " prefix and can | |
214 be easily filtered out. | |
215 | |
216 + If you want to investigate deeper, you may want to enable | |
217 additional debugging in src/event/ngx_event_quic.h: | |
218 | |
219 #define NGX_QUIC_DEBUG_PACKETS | |
220 #define NGX_QUIC_DEBUG_FRAMES | |
221 #define NGX_QUIC_DEBUG_FRAMES_ALLOC | |
222 #define NGX_QUIC_DEBUG_CRYPTO | |
223 | |
224 6. Links | |
225 | |
226 [1] https://tools.ietf.org/html/draft-ietf-quic-transport-27 | |
227 [2] https://tools.ietf.org/html/draft-ietf-quic-http-27 | |
228 [3] https://mailman.nginx.org/mailman/listinfo/nginx-devel | |
229 [4] https://boringssl.googlesource.com/boringssl/ | |
230 [5] https://tools.ietf.org/html/draft-ietf-quic-recovery-27 | |
231 [6] https://nginx.org/en/docs/http/ngx_http_core_module.html#listen | |
232 [7] https://nginx.org/en/docs/debugging_log.html |