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
|
|
44 + 00-RTT data is being received and acted on
|
|
45 + Connection is established using TLS Resume Ticket
|
|
46 + Stream data is being exchanged and ACK'ed
|
|
47 + An H3 transaction succeeded
|
|
48 + One or both endpoints insert entries into dynamic table and
|
|
49 subsequently reference them from header blocks
|
|
50
|
|
51 Not (yet) supported features:
|
|
52
|
|
53 - Version negotiation
|
|
54 - Stateless Retry
|
|
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 - Protocol error messages are not implemented, in case of error connection
|
|
68 closes silently for peer
|
|
69
|
|
70 - ACK handling is basic: every received ack-eliciting packet
|
|
71 is acknowledged, no ack ranges are used
|
|
72
|
|
73 - Flow control mechanism is basic and intended to avoid CPU hog and make
|
|
74 simple interactions possible
|
|
75
|
|
76 - Not all draft requirements are strictly followed; some of checks are
|
|
77 omitted for the sake of simplicity of initial implementation
|
|
78
|
|
79 2. Installing
|
|
80
|
|
81 You will need a BoringSSL [4] library that provides QUIC support
|
|
82
|
|
83 $ hg clone https://hg.nginx.org/nginx-quic
|
|
84 $ cd nginx-quic
|
|
85 $ ./auto/configure --with-debug --with-cc-opt="-I../boringssl/include" \
|
|
86 --with-ld-opt="-L../boringssl/build/ssl \
|
|
87 -L../boringssl/build/crypto"
|
|
88 $ make
|
|
89
|
|
90 3. Configuration
|
|
91
|
|
92 The "listen" directive got a new option: "http3"
|
|
93 which enables HTTP/3 over QUIC on the specified port.
|
|
94
|
|
95 Along with "http3", you also have to specify "reuseport" option [6]
|
|
96 to make it work properly with multiple workers.
|
|
97
|
|
98 A number of directives were added that specify transport parameter values:
|
|
99
|
|
100 quic_max_idle_timeout
|
|
101 quic_max_ack_delay
|
|
102 quic_max_packet_size
|
|
103 quic_initial_max_data
|
|
104 quic_initial_max_stream_data_bidi_local
|
|
105 quic_initial_max_stream_data_bidi_remote
|
|
106 quic_initial_max_stream_data_uni
|
|
107 quic_initial_max_streams_bidi
|
|
108 quic_initial_max_streams_uni
|
|
109 quic_ack_delay_exponent
|
|
110 quic_active_migration
|
|
111 quic_active_connection_id_limit
|
|
112
|
|
113 Two additional variables are available: $quic and $http3.
|
|
114 The value of $quic is "quic" if QUIC connection is used,
|
|
115 and empty string otherwise. The value of $http3 is a string
|
|
116 "h3-xx" where "xx" is the supported draft number.
|
|
117
|
|
118 Example configuration:
|
|
119
|
|
120 http {
|
|
121 log_format quic '$remote_addr - $remote_user [$time_local] '
|
|
122 '"$request" $status $body_bytes_sent '
|
|
123 '"$http_referer" "$http_user_agent" "$quic" "$http3"';
|
|
124
|
|
125 access_log logs/access.log quic;
|
|
126
|
|
127 server {
|
|
128 # for better compatibility it's recommended
|
|
129 # to use the same port for quic and https
|
|
130 listen 8443 http3 reuseport;
|
|
131 listen 8443 ssl;
|
|
132
|
|
133 ssl_certificate certs/example.com.crt;
|
|
134 ssl_certificate_key certs/example.com.key;
|
|
135 ssl_protocols TLSv1.3;
|
|
136
|
|
137 location / {
|
|
138 # required for browsers to direct them into quic port
|
|
139 add_header Alt-Svc $http3=":8443";
|
|
140 }
|
|
141 }
|
|
142 }
|
|
143
|
|
144 4. Clients
|
|
145
|
|
146 * Browsers
|
|
147
|
|
148 Known to work: Firefox 75+ and Chrome 83+
|
|
149
|
|
150 Beware of strange issues: sometimes browser may decide to ignore QUIC
|
|
151 Cache clearing/restart might help. Always check access.log and
|
|
152 error.log to make sure you are using HTTP/3 and not TCP https.
|
|
153
|
|
154 + to enable QUIC in Firefox, set the following in 'about:config':
|
|
155 network.http.http3.enabled = true
|
|
156
|
|
157 + to enable QUIC in Chrome, enable it on command line and force it
|
|
158 on your site:
|
|
159
|
|
160 $ ./chrome --enable-quic --quic-version=h3-27 \
|
|
161 --origin-to-force-quic-on=example.com:8443
|
|
162
|
|
163 * Console clients
|
|
164
|
|
165 Known to work: ngtcp2, firefox's neqo and chromium's console clients:
|
|
166
|
|
167 $ examples/client 127.0.0.1 8443 https://example.com:8443/index.html
|
|
168
|
|
169 $ ./neqo-client https://127.0.0.1:8443/
|
|
170
|
|
171 $ chromium-build/out/my_build/quic_client http://example.com:8443 \
|
|
172 --quic_version=h3-27 \
|
|
173 --allow_unknown_root_cert \
|
|
174 --disable_certificate_verification
|
|
175
|
|
176
|
|
177 If you've got it right, in the access log you should see something like:
|
|
178
|
|
179 127.0.0.1 - - [24/Apr/2020:11:27:29 +0300] "GET / HTTP/3" 200 805 "-"
|
|
180 "nghttp3/ngtcp2 client" "quic" "h3-27"
|
|
181
|
|
182
|
|
183 5. Troubleshooting
|
|
184
|
|
185 Here are some tips that may help you to identify problems:
|
|
186
|
|
187 + Ensure you are building with proper SSL library that
|
|
188 implements draft 27
|
|
189
|
|
190 + Ensure you are using the proper SSL library in runtime
|
|
191 (`nginx -V` will show you what you are using)
|
|
192
|
|
193 + Ensure your client is actually sending QUIC requests
|
|
194 (see "Clients" section about browsers and cache)
|
|
195
|
|
196 We recommend to start with simple console client like ngtcp2
|
|
197 to ensure you've got server configured properly before trying
|
|
198 with real browsers that may be very peaky with certificates,
|
|
199 for example.
|
|
200
|
|
201 + Build nginx with debug support [7] and check your debug log.
|
|
202 It should contain all details about connection and why it
|
|
203 failed. All related messages contain "quic " prefix and can
|
|
204 be easily filtered out.
|
|
205
|
|
206 + If you want to investigate deeper, you may want to enable
|
|
207 additional debugging in src/event/ngx_event_quic.h:
|
|
208
|
|
209 #define NGX_QUIC_DEBUG_PACKETS
|
|
210 #define NGX_QUIC_DEBUG_FRAMES
|
|
211 #define NGX_QUIC_DEBUG_FRAMES_ALLOC
|
|
212 #define NGX_QUIC_DEBUG_CRYPTO
|
|
213
|
|
214 6. Links
|
|
215
|
|
216 [1] https://tools.ietf.org/html/draft-ietf-quic-transport-27
|
|
217 [2] https://tools.ietf.org/html/draft-ietf-quic-http-27
|
|
218 [3] https://mailman.nginx.org/mailman/listinfo/nginx-devel
|
|
219 [4] https://boringssl.googlesource.com/boringssl/
|
|
220 [5] https://tools.ietf.org/html/draft-ietf-quic-recovery-27
|
|
221 [6] https://nginx.org/en/docs/http/ngx_http_core_module.html#listen
|
|
222 [7] https://nginx.org/en/docs/debugging_log.html
|