3 nghttpx - HTTP/2 proxy - HOW-TO
4 ===============================
6 :doc:`nghttpx.1` is a proxy translating protocols between HTTP/2 and
7 other protocols (e.g., HTTP/1). It operates in several modes and each
8 mode may require additional programs to work with. This article
9 describes each operation mode and explains the intended use-cases. It
10 also covers some useful options later.
15 If nghttpx is invoked without :option:`--http2-proxy`, it operates in
16 default mode. In this mode, it works as reverse proxy (gateway) for
17 both HTTP/2 and HTTP/1 clients to backend servers. This is also known
20 By default, frontend connection is encrypted using SSL/TLS. So
21 server's private key and certificate must be supplied to the command
22 line (or through configuration file). In this case, the frontend
23 protocol selection will be done via ALPN or NPN.
25 To turn off encryption on frontend connection, use ``no-tls`` keyword
26 in :option:`--frontend` option. HTTP/2 and HTTP/1 are available on
27 the frontend, and an HTTP/1 connection can be upgraded to HTTP/2 using
28 HTTP Upgrade. Starting HTTP/2 connection by sending HTTP/2 connection
29 preface is also supported.
31 nghttpx can listen on multiple frontend addresses. This is achieved
32 by using multiple :option:`--frontend` options. For each frontend
33 address, TLS can be enabled or disabled.
35 By default, backend connections are not encrypted. To enable TLS
36 encryption on backend connections, use ``tls`` keyword in
37 :option:`--backend` option. Using patterns and ``proto`` keyword in
38 :option:`--backend` option, backend application protocol can be
39 specified per host/request path pattern. It means that you can use
40 both HTTP/2 and HTTP/1 in backend connections at the same time. Note
41 that default backend protocol is HTTP/1.1. To use HTTP/2 in backend,
42 you have to specify ``h2`` in ``proto`` keyword in :option:`--backend`
45 The backend is supposed to be a Web server. For example, to make
46 nghttpx listen to encrypted HTTP/2 requests at port 8443, and a
47 backend Web server is configured to listen to HTTP requests at port
48 8080 on the same host, run nghttpx command-line like this:
52 $ nghttpx -f0.0.0.0,8443 -b127.0.0.1,8080 /path/to/server.key /path/to/server.crt
54 Then an HTTP/2 enabled client can access the nghttpx server using HTTP/2. For
55 example, you can send a GET request using nghttp:
59 $ nghttp -nv https://localhost:8443/
64 If nghttpx is invoked with :option:`--http2-proxy` (or its shorthand
65 :option:`-s`) option, it operates in HTTP/2 proxy mode. The supported
66 protocols in frontend and backend connections are the same as in `default
67 mode`_. The difference is that this mode acts like a forward proxy and
68 assumes the backend is an HTTP proxy server (e.g., Squid, Apache Traffic
69 Server). HTTP/1 requests must include an absolute URI in request line.
71 By default, the frontend connection is encrypted. So this mode is
72 also called secure proxy.
74 To turn off encryption on the frontend connection, use ``no-tls`` keyword
75 in :option:`--frontend` option.
77 The backend must be an HTTP proxy server. nghttpx supports multiple
78 backend server addresses. It translates incoming requests to HTTP
79 request to backend server. The backend server performs real proxy
80 work for each request, for example, dispatching requests to the origin
81 server and caching contents.
83 The backend connection is not encrypted by default. To enable
84 encryption, use ``tls`` keyword in :option:`--backend` option. The
85 default backend protocol is HTTP/1.1. To use HTTP/2 in backend
86 connection, use :option:`--backend` option, and specify ``h2`` in
87 ``proto`` keyword explicitly.
89 For example, to make nghttpx listen to encrypted HTTP/2 requests at
90 port 8443, and a backend HTTP proxy server is configured to listen to
91 HTTP/1 requests at port 8080 on the same host, run nghttpx command-line
96 $ nghttpx -s -f'*,8443' -b127.0.0.1,8080 /path/to/server.key /path/to/server.crt
98 At the time of this writing, Firefox 41 and Chromium v46 can use
99 nghttpx as HTTP/2 proxy.
101 To make Firefox or Chromium use nghttpx as HTTP/2 proxy, user has to
102 create proxy.pac script file like this:
104 .. code-block:: javascript
106 function FindProxyForURL(url, host) {
107 return "HTTPS SERVERADDR:PORT";
110 ``SERVERADDR`` and ``PORT`` is the hostname/address and port of the
111 machine nghttpx is running. Please note that both Firefox and
112 Chromium require valid certificate for secure proxy.
114 For Firefox, open Preference window and select Advanced then click
115 Network tab. Clicking Connection Settings button will show the
116 dialog. Select "Automatic proxy configuration URL" and enter the path
117 to proxy.pac file, something like this:
121 file:///path/to/proxy.pac
123 For Chromium, use following command-line:
127 $ google-chrome --proxy-pac-url=file:///path/to/proxy.pac --use-npn
129 As HTTP/1 proxy server, Squid may work as out-of-box. Traffic server
130 requires to be configured as forward proxy. Here is the minimum
131 configuration items to edit:
135 CONFIG proxy.config.reverse_proxy.enabled INT 0
136 CONFIG proxy.config.url_remap.remap_required INT 0
138 Consult Traffic server `documentation
139 <http://trafficserver.readthedocs.org/en/latest/admin-guide/configuration/transparent-forward-proxying.en.html>`_
140 to know how to configure traffic server as forward proxy and its
141 security implications.
146 ALPN support requires OpenSSL >= 1.0.2.
148 Disable frontend SSL/TLS
149 ------------------------
151 The frontend connections are encrypted with SSL/TLS by default. To
152 turn off SSL/TLS, use ``no-tls`` keyword in :option:`--frontend`
153 option. If this option is used, the private key and certificate are
154 not required to run nghttpx.
156 Enable backend SSL/TLS
157 ----------------------
159 The backend connections are not encrypted by default. To enable
160 SSL/TLS encryption, use ``tls`` keyword in :option:`--backend` option.
162 Enable SSL/TLS on memcached connection
163 --------------------------------------
165 By default, memcached connection is not encrypted. To enable
166 encryption, use ``tls`` keyword in
167 :option:`--tls-ticket-key-memcached` for TLS ticket key, and
168 :option:`--tls-session-cache-memcached` for TLS session cache.
170 Specifying additional server certificates
171 -----------------------------------------
173 nghttpx accepts additional server private key and certificate pairs
174 using :option:`--subcert` option. It can be used multiple times.
176 Specifying additional CA certificate
177 ------------------------------------
179 By default, nghttpx tries to read CA certificate from system. But
180 depending on the system you use, this may fail or is not supported.
181 To specify CA certificate manually, use :option:`--cacert` option.
182 The specified file must be PEM format and can contain multiple
185 By default, nghttpx validates server's certificate. If you want to
186 turn off this validation, knowing this is really insecure and what you
187 are doing, you can use :option:`--insecure` option to disable
188 certificate validation.
190 Read/write rate limit
191 ---------------------
193 nghttpx supports transfer rate limiting on frontend connections. You
194 can do rate limit per frontend connection for reading and writing
197 To perform rate limit for reading, use :option:`--read-rate` and
198 :option:`--read-burst` options. For writing, use
199 :option:`--write-rate` and :option:`--write-burst`.
201 Please note that rate limit is performed on top of TCP and nothing to
202 do with HTTP/2 flow control.
204 Rewriting location header field
205 -------------------------------
207 nghttpx automatically rewrites location response header field if the
208 following all conditions satisfy:
210 * In the default mode (:option:`--http2-proxy` is not used)
211 * :option:`--no-location-rewrite` is not used
212 * URI in location header field is an absolute URI
213 * URI in location header field includes non empty host component.
214 * host (without port) in URI in location header field must match the
215 host appearing in ``:authority`` or ``host`` header field.
217 When rewrite happens, URI scheme is replaced with the ones used in
218 frontend, and authority is replaced with which appears in
219 ``:authority``, or ``host`` request header field. ``:authority``
220 header field has precedence over ``host``.
225 nghttpx supports hot swapping using signals. The hot swapping in
226 nghttpx is multi step process. First send USR2 signal to nghttpx
227 process. It will do fork and execute new executable, using same
228 command-line arguments and environment variables.
230 As of nghttpx version 1.20.0, that is all you have to do. The new
231 master process sends QUIT signal to the original process, when it is
232 ready to serve requests, to shut it down gracefully.
234 For earlier versions of nghttpx, you have to do one more thing. At
235 this point, both current and new processes can accept requests. To
236 gracefully shutdown current process, send QUIT signal to current
237 nghttpx process. When all existing frontend connections are done, the
238 current process will exit. At this point, only new nghttpx process
239 exists and serves incoming requests.
241 If you want to just reload configuration file without executing new
242 binary, send SIGHUP to nghttpx master process.
247 When rotating log files, it is desirable to re-open log files after
248 log rotation daemon renamed existing log files. To tell nghttpx to
249 re-open log files, send USR1 signal to nghttpx process. It will
250 re-open files specified by :option:`--accesslog-file` and
251 :option:`--errorlog-file` options.
253 Multiple frontend addresses
254 ---------------------------
256 nghttpx can listen on multiple frontend addresses. To specify them,
257 just use :option:`--frontend` (or its shorthand :option:`-f`) option
258 repeatedly. TLS can be enabled or disabled per frontend address
259 basis. For example, to listen on port 443 with TLS enabled, and on
268 Multiple backend addresses
269 --------------------------
271 nghttpx supports multiple backend addresses. To specify them, just
272 use :option:`--backend` (or its shorthand :option:`-b`) option
273 repeatedly. For example, to use ``192.168.0.10:8080`` and
274 ``192.168.0.11:8080``, use command-line like this:
275 ``-b192.168.0.10,8080 -b192.168.0.11,8080``. In configuration file,
280 backend=192.168.0.10,8080
281 backend=192.168.0.11,8008
283 nghttpx can route request to different backend according to request
284 host and path. For example, to route request destined to host
285 ``doc.example.com`` to backend server ``docserv:3000``, you can write
290 backend=docserv,3000;doc.example.com/
292 When you write this option in command-line, you should enclose
293 argument with single or double quotes, since the character ``;`` has a
294 special meaning in shell.
296 To route, request to request path ``/foo`` to backend server
297 ``[::1]:8080``, you can write like so:
301 backend=::1,8080;/foo
303 If the last character of path pattern is ``/``, all request paths
304 which start with that pattern match:
308 backend=::1,8080;/bar/
310 The request path ``/bar/buzz`` matches the ``/bar/``.
312 You can use ``*`` at the end of the path pattern to make it wildcard
313 pattern. ``*`` must match at least one character:
317 backend=::1,8080;/sample*
319 The request path ``/sample1/foo`` matches the ``/sample*`` pattern.
321 Of course, you can specify both host and request path at the same
326 backend=192.168.0.10,8080;example.com/foo
328 We can use ``*`` in the left most position of host to achieve wildcard
329 suffix match. If ``*`` is the left most character, then the remaining
330 string should match the request host suffix. ``*`` must match at
331 least one character. For example, ``*.example.com`` matches
332 ``www.example.com`` and ``dev.example.com``, and does not match
333 ``example.com`` and ``nghttp2.org``. The exact match (without ``*``)
334 always takes precedence over wildcard match.
336 One important thing you have to remember is that we have to specify
337 default routing pattern for so called "catch all" pattern. To write
338 "catch all" pattern, just specify backend server address, without
341 Usually, host is the value of ``Host`` header field. In HTTP/2, the
342 value of ``:authority`` pseudo header field is used.
344 When you write multiple backend addresses sharing the same routing
345 pattern, they are used as load balancing. For example, to use 2
346 servers ``serv1:3000`` and ``serv2:3000`` for request host
347 ``example.com`` and path ``/myservice``, you can write like so:
351 backend=serv1,3000;example.com/myservice
352 backend=serv2,3000;example.com/myservice
354 You can also specify backend application protocol in
355 :option:`--backend` option using ``proto`` keyword after pattern.
356 Utilizing this allows ngttpx to route certain request to HTTP/2, other
357 requests to HTTP/1. For example, to route requests to ``/ws/`` in
358 backend HTTP/1.1 connection, and use backend HTTP/2 for other
363 backend=serv1,3000;/;proto=h2
364 backend=serv1,3000;/ws/;proto=http/1.1
366 The default backend protocol is HTTP/1.1.
368 TLS can be enabled per pattern basis:
372 backend=serv1,8443;/;proto=h2;tls
373 backend=serv2,8080;/ws/;proto=http/1.1
375 In the above case, connection to serv1 will be encrypted by TLS. On
376 the other hand, connection to serv2 will not be encrypted by TLS.
378 Dynamic hostname lookup
379 -----------------------
381 By default, nghttpx performs backend hostname lookup at start up, or
382 configuration reload, and keeps using them in its entire session. To
383 make nghttpx perform hostname lookup dynamically, use ``dns``
384 parameter in :option:`--backend` option, like so:
388 backend=foo.example.com,80;;dns
390 nghttpx will cache resolved addresses for certain period of time. To
391 change this cache period, use :option:`--dns-cache-timeout`.
393 Enable PROXY protocol
394 ---------------------
396 PROXY protocol can be enabled per frontend. In order to enable PROXY
397 protocol, use ``proxyproto`` parameter in :option:`--frontend` option,
402 frontend=*,443;proxyproto
404 nghttpx supports both PROXY protocol v1 and v2. AF_UNIX in PROXY
405 protocol version 2 is ignored.
410 Two kinds of session affinity are available: client IP, and HTTP
413 To enable client IP based affinity, specify ``affinity=ip`` parameter
414 in :option:`--backend` option. If PROXY protocol is enabled, then an
415 address obtained from PROXY protocol is taken into consideration.
417 To enable HTTP Cookie based affinity, specify ``affinity=cookie``
418 parameter, and specify a name of cookie in ``affinity-cookie-name``
419 parameter. Optionally, a Path attribute can be specified in
420 ``affinity-cookie-path`` parameter:
424 backend=127.0.0.1,3000;;affinity=cookie;affinity-cookie-name=nghttpxlb;affinity-cookie-path=/
426 Secure attribute of cookie is set if client connection is protected by
432 nghttpx supports pre-shared key (PSK) cipher suites for both frontend
433 and backend TLS connections. For frontend connection, use
434 :option:`--psk-secrets` option to specify a file which contains PSK
435 identity and secrets. The format of the file is
436 ``<identity>:<hex-secret>``, where ``<identity>`` is PSK identity, and
437 ``<hex-secret>`` is PSK secret in hex, like so:
441 client1:9567800e065e078085c241d54a01c6c3f24b3bab71a606600f4c6ad2c134f3b9
442 client2:b1376c3f8f6dcf7c886c5bdcceecd1e6f1d708622b6ddd21bda26ebd0c0bca99
444 nghttpx server accepts any of the identity and secret pairs in the
445 file. The default cipher suite list does not contain PSK cipher
446 suites. In order to use PSK, PSK cipher suite must be enabled by
447 using :option:`--ciphers` option. The desired PSK cipher suite may be
448 listed in `HTTP/2 cipher black list
449 <https://tools.ietf.org/html/rfc7540#appendix-A>`_. In order to use
450 such PSK cipher suite with HTTP/2, disable HTTP/2 cipher black list by
451 using :option:`--no-http2-cipher-black-list` option. But you should
452 understand its implications.
454 At the time of writing, even if only PSK cipher suites are specified
455 in :option:`--ciphers` option, certificate and private key are still
458 For backend connection, use :option:`--client-psk-secrets` option to
459 specify a file which contains single PSK identity and secret. The
460 format is the same as the file used by :option:`--psk-secrets`
461 described above, but only first identity and secret pair is solely
466 client2:b1376c3f8f6dcf7c886c5bdcceecd1e6f1d708622b6ddd21bda26ebd0c0bca99
468 The default cipher suite list does not contain PSK cipher suites. In
469 order to use PSK, PSK cipher suite must be enabled by using
470 :option:`--client-ciphers` option. The desired PSK cipher suite may
471 be listed in `HTTP/2 cipher black list
472 <https://tools.ietf.org/html/rfc7540#appendix-A>`_. In order to use
473 such PSK cipher suite with HTTP/2, disable HTTP/2 cipher black list by
474 using :option:`--client-no-http2-cipher-black-list` option. But you
475 should understand its implications.
480 As of nghttpx v1.34.0, if it is built with OpenSSL 1.1.1 or later, it
481 supports TLSv1.3. 0-RTT data is supported, but by default its
482 processing is postponed until TLS handshake completes to mitigate
483 replay attack. This costs extra round trip and reduces effectiveness
484 of 0-RTT data. :option:`--tls-no-postpone-early-data` makes nghttpx
485 not wait for handshake to complete before forwarding request included
486 in 0-RTT to get full potential of 0-RTT data. In this case, nghttpx
487 adds ``Early-Data: 1`` header field when forwarding a request to a
488 backend server. All backend servers should recognize this header
489 field and understand that there is a risk for replay attack. See `RFC
490 8470 <https://tools.ietf.org/html/rfc8470>`_ for ``Early-Data`` header
493 nghttpx disables anti replay protection provided by OpenSSL. The anti
494 replay protection of OpenSSL requires that a resumed request must hit
495 the same server which generates the session ticket. Therefore it
496 might not work nicely in a deployment where there are multiple nghttpx
497 instances sharing ticket encryption keys via memcached.
499 Because TLSv1.3 completely changes the semantics of cipher suite
500 naming scheme and structure, nghttpx provides the new option
501 :option:`--tls13-ciphers` and :option:`--tls13-client-ciphers` to
502 change preferred cipher list for TLSv1.3.
504 WebSockets over HTTP/2
505 ----------------------
507 nghttpx supports `RFC 8441 <https://tools.ietf.org/html/rfc8441>`_
508 Bootstrapping WebSockets with HTTP/2 for both frontend and backend
509 connections. This feature is enabled by default and no configuration
512 Migration from nghttpx v1.18.x or earlier
513 -----------------------------------------
515 As of nghttpx v1.19.0, :option:`--ciphers` option only changes cipher
516 list for frontend TLS connection. In order to change cipher list for
517 backend connection, use :option:`--client-ciphers` option.
519 Similarly, :option:`--no-http2-cipher-black-list` option only disables
520 HTTP/2 cipher black list for frontend connection. In order to disable
521 HTTP/2 cipher black list for backend connection, use
522 :option:`--client-no-http2-cipher-black-list` option.
524 ``--accept-proxy-protocol`` option was deprecated. Instead, use
525 ``proxyproto`` parameter in :option:`--frontend` option to enable
526 PROXY protocol support per frontend.
528 Migration from nghttpx v1.8.0 or earlier
529 ----------------------------------------
531 As of nghttpx 1.9.0, ``--frontend-no-tls`` and ``--backend-no-tls``
534 To disable encryption on frontend connection, use ``no-tls`` keyword
535 in :option:`--frontend` potion:
539 frontend=*,3000;no-tls
541 The TLS encryption is now disabled on backend connection in all modes
542 by default. To enable encryption on backend connection, use ``tls``
543 keyword in :option:`--backend` option:
547 backend=127.0.0.1,8080;tls
549 As of nghttpx 1.9.0, ``--http2-bridge``, ``--client`` and
550 ``--client-proxy`` options have been removed. These functionality can
551 be used using combinations of options.
553 Use following option instead of ``--http2-bridge``:
557 backend=<ADDR>,<PORT>;;proto=h2;tls
559 Use following options instead of ``--client``:
563 frontend=<ADDR>,<PORT>;no-tls
564 backend=<ADDR>,<PORT>;;proto=h2;tls
566 Use following options instead of ``--client-proxy``:
571 frontend=<ADDR>,<PORT>;no-tls
572 backend=<ADDR>,<PORT>;;proto=h2;tls
574 We also removed ``--backend-http2-connections-per-worker`` option. It
575 was present because previously the number of backend h2 connection was
576 statically configured, and defaulted to 1. Now the number of backend
577 h2 connection is increased on demand. We know the maximum number of
578 concurrent streams per connection. When we push as many request as
579 the maximum concurrency to the one connection, we create another new
580 connection so that we can distribute load and avoid delay the request
581 processing. This is done automatically without any configuration.