1.. program:: nghttpx 2 3nghttpx - HTTP/2 proxy - HOW-TO 4=============================== 5 6:doc:`nghttpx.1` is a proxy translating protocols between HTTP/2 and 7other protocols (e.g., HTTP/1). It operates in several modes and each 8mode may require additional programs to work with. This article 9describes each operation mode and explains the intended use-cases. It 10also covers some useful options later. 11 12Default mode 13------------ 14 15If nghttpx is invoked without :option:`--http2-proxy`, it operates in 16default mode. In this mode, it works as reverse proxy (gateway) for 17both HTTP/2 and HTTP/1 clients to backend servers. This is also known 18as "HTTP/2 router". 19 20By default, frontend connection is encrypted using SSL/TLS. So 21server's private key and certificate must be supplied to the command 22line (or through configuration file). In this case, the frontend 23protocol selection will be done via ALPN or NPN. 24 25To turn off encryption on frontend connection, use ``no-tls`` keyword 26in :option:`--frontend` option. HTTP/2 and HTTP/1 are available on 27the frontend, and an HTTP/1 connection can be upgraded to HTTP/2 using 28HTTP Upgrade. Starting HTTP/2 connection by sending HTTP/2 connection 29preface is also supported. 30 31nghttpx can listen on multiple frontend addresses. This is achieved 32by using multiple :option:`--frontend` options. For each frontend 33address, TLS can be enabled or disabled. 34 35By default, backend connections are not encrypted. To enable TLS 36encryption 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 39specified per host/request path pattern. It means that you can use 40both HTTP/2 and HTTP/1 in backend connections at the same time. Note 41that default backend protocol is HTTP/1.1. To use HTTP/2 in backend, 42you have to specify ``h2`` in ``proto`` keyword in :option:`--backend` 43explicitly. 44 45The backend is supposed to be a Web server. For example, to make 46nghttpx listen to encrypted HTTP/2 requests at port 8443, and a 47backend Web server is configured to listen to HTTP requests at port 488080 on the same host, run nghttpx command-line like this: 49 50.. code-block:: text 51 52 $ nghttpx -f0.0.0.0,8443 -b127.0.0.1,8080 /path/to/server.key /path/to/server.crt 53 54Then an HTTP/2 enabled client can access the nghttpx server using HTTP/2. For 55example, you can send a GET request using nghttp: 56 57.. code-block:: text 58 59 $ nghttp -nv https://localhost:8443/ 60 61HTTP/2 proxy mode 62----------------- 63 64If nghttpx is invoked with :option:`--http2-proxy` (or its shorthand 65:option:`-s`) option, it operates in HTTP/2 proxy mode. The supported 66protocols in frontend and backend connections are the same as in `default 67mode`_. The difference is that this mode acts like a forward proxy and 68assumes the backend is an HTTP proxy server (e.g., Squid, Apache Traffic 69Server). HTTP/1 requests must include an absolute URI in request line. 70 71By default, the frontend connection is encrypted. So this mode is 72also called secure proxy. 73 74To turn off encryption on the frontend connection, use ``no-tls`` keyword 75in :option:`--frontend` option. 76 77The backend must be an HTTP proxy server. nghttpx supports multiple 78backend server addresses. It translates incoming requests to HTTP 79request to backend server. The backend server performs real proxy 80work for each request, for example, dispatching requests to the origin 81server and caching contents. 82 83The backend connection is not encrypted by default. To enable 84encryption, use ``tls`` keyword in :option:`--backend` option. The 85default backend protocol is HTTP/1.1. To use HTTP/2 in backend 86connection, use :option:`--backend` option, and specify ``h2`` in 87``proto`` keyword explicitly. 88 89For example, to make nghttpx listen to encrypted HTTP/2 requests at 90port 8443, and a backend HTTP proxy server is configured to listen to 91HTTP/1 requests at port 8080 on the same host, run nghttpx command-line 92like this: 93 94.. code-block:: text 95 96 $ nghttpx -s -f'*,8443' -b127.0.0.1,8080 /path/to/server.key /path/to/server.crt 97 98At the time of this writing, Firefox 41 and Chromium v46 can use 99nghttpx as HTTP/2 proxy. 100 101To make Firefox or Chromium use nghttpx as HTTP/2 proxy, user has to 102create proxy.pac script file like this: 103 104.. code-block:: javascript 105 106 function FindProxyForURL(url, host) { 107 return "HTTPS SERVERADDR:PORT"; 108 } 109 110``SERVERADDR`` and ``PORT`` is the hostname/address and port of the 111machine nghttpx is running. Please note that both Firefox and 112Chromium require valid certificate for secure proxy. 113 114For Firefox, open Preference window and select Advanced then click 115Network tab. Clicking Connection Settings button will show the 116dialog. Select "Automatic proxy configuration URL" and enter the path 117to proxy.pac file, something like this: 118 119.. code-block:: text 120 121 file:///path/to/proxy.pac 122 123For Chromium, use following command-line: 124 125.. code-block:: text 126 127 $ google-chrome --proxy-pac-url=file:///path/to/proxy.pac --use-npn 128 129As HTTP/1 proxy server, Squid may work as out-of-box. Traffic server 130requires to be configured as forward proxy. Here is the minimum 131configuration items to edit: 132 133.. code-block:: text 134 135 CONFIG proxy.config.reverse_proxy.enabled INT 0 136 CONFIG proxy.config.url_remap.remap_required INT 0 137 138Consult Traffic server `documentation 139<http://trafficserver.readthedocs.org/en/latest/admin-guide/configuration/transparent-forward-proxying.en.html>`_ 140to know how to configure traffic server as forward proxy and its 141security implications. 142 143ALPN support 144------------ 145 146ALPN support requires OpenSSL >= 1.0.2. 147 148Disable frontend SSL/TLS 149------------------------ 150 151The frontend connections are encrypted with SSL/TLS by default. To 152turn off SSL/TLS, use ``no-tls`` keyword in :option:`--frontend` 153option. If this option is used, the private key and certificate are 154not required to run nghttpx. 155 156Enable backend SSL/TLS 157---------------------- 158 159The backend connections are not encrypted by default. To enable 160SSL/TLS encryption, use ``tls`` keyword in :option:`--backend` option. 161 162Enable SSL/TLS on memcached connection 163-------------------------------------- 164 165By default, memcached connection is not encrypted. To enable 166encryption, 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. 169 170Specifying additional server certificates 171----------------------------------------- 172 173nghttpx accepts additional server private key and certificate pairs 174using :option:`--subcert` option. It can be used multiple times. 175 176Specifying additional CA certificate 177------------------------------------ 178 179By default, nghttpx tries to read CA certificate from system. But 180depending on the system you use, this may fail or is not supported. 181To specify CA certificate manually, use :option:`--cacert` option. 182The specified file must be PEM format and can contain multiple 183certificates. 184 185By default, nghttpx validates server's certificate. If you want to 186turn off this validation, knowing this is really insecure and what you 187are doing, you can use :option:`--insecure` option to disable 188certificate validation. 189 190Read/write rate limit 191--------------------- 192 193nghttpx supports transfer rate limiting on frontend connections. You 194can do rate limit per frontend connection for reading and writing 195individually. 196 197To 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`. 200 201Please note that rate limit is performed on top of TCP and nothing to 202do with HTTP/2 flow control. 203 204Rewriting location header field 205------------------------------- 206 207nghttpx automatically rewrites location response header field if the 208following all conditions satisfy: 209 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. 216 217When rewrite happens, URI scheme is replaced with the ones used in 218frontend, and authority is replaced with which appears in 219``:authority``, or ``host`` request header field. ``:authority`` 220header field has precedence over ``host``. 221 222Hot swapping 223------------ 224 225nghttpx supports hot swapping using signals. The hot swapping in 226nghttpx is multi step process. First send USR2 signal to nghttpx 227process. It will do fork and execute new executable, using same 228command-line arguments and environment variables. 229 230As of nghttpx version 1.20.0, that is all you have to do. The new 231master process sends QUIT signal to the original process, when it is 232ready to serve requests, to shut it down gracefully. 233 234For earlier versions of nghttpx, you have to do one more thing. At 235this point, both current and new processes can accept requests. To 236gracefully shutdown current process, send QUIT signal to current 237nghttpx process. When all existing frontend connections are done, the 238current process will exit. At this point, only new nghttpx process 239exists and serves incoming requests. 240 241If you want to just reload configuration file without executing new 242binary, send SIGHUP to nghttpx master process. 243 244Re-opening log files 245-------------------- 246 247When rotating log files, it is desirable to re-open log files after 248log rotation daemon renamed existing log files. To tell nghttpx to 249re-open log files, send USR1 signal to nghttpx process. It will 250re-open files specified by :option:`--accesslog-file` and 251:option:`--errorlog-file` options. 252 253Multiple frontend addresses 254--------------------------- 255 256nghttpx can listen on multiple frontend addresses. To specify them, 257just use :option:`--frontend` (or its shorthand :option:`-f`) option 258repeatedly. TLS can be enabled or disabled per frontend address 259basis. For example, to listen on port 443 with TLS enabled, and on 260port 80 without TLS: 261 262.. code-block:: text 263 264 frontend=*,443 265 frontend=*,80;no-tls 266 267 268Multiple backend addresses 269-------------------------- 270 271nghttpx supports multiple backend addresses. To specify them, just 272use :option:`--backend` (or its shorthand :option:`-b`) option 273repeatedly. 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, 276this looks like: 277 278.. code-block:: text 279 280 backend=192.168.0.10,8080 281 backend=192.168.0.11,8008 282 283nghttpx can route request to different backend according to request 284host and path. For example, to route request destined to host 285``doc.example.com`` to backend server ``docserv:3000``, you can write 286like so: 287 288.. code-block:: text 289 290 backend=docserv,3000;doc.example.com/ 291 292When you write this option in command-line, you should enclose 293argument with single or double quotes, since the character ``;`` has a 294special meaning in shell. 295 296To route, request to request path ``/foo`` to backend server 297``[::1]:8080``, you can write like so: 298 299.. code-block:: text 300 301 backend=::1,8080;/foo 302 303If the last character of path pattern is ``/``, all request paths 304which start with that pattern match: 305 306.. code-block:: text 307 308 backend=::1,8080;/bar/ 309 310The request path ``/bar/buzz`` matches the ``/bar/``. 311 312You can use ``*`` at the end of the path pattern to make it wildcard 313pattern. ``*`` must match at least one character: 314 315.. code-block:: text 316 317 backend=::1,8080;/sample* 318 319The request path ``/sample1/foo`` matches the ``/sample*`` pattern. 320 321Of course, you can specify both host and request path at the same 322time: 323 324.. code-block:: text 325 326 backend=192.168.0.10,8080;example.com/foo 327 328We can use ``*`` in the left most position of host to achieve wildcard 329suffix match. If ``*`` is the left most character, then the remaining 330string should match the request host suffix. ``*`` must match at 331least 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 ``*``) 334always takes precedence over wildcard match. 335 336One important thing you have to remember is that we have to specify 337default routing pattern for so called "catch all" pattern. To write 338"catch all" pattern, just specify backend server address, without 339pattern. 340 341Usually, host is the value of ``Host`` header field. In HTTP/2, the 342value of ``:authority`` pseudo header field is used. 343 344When you write multiple backend addresses sharing the same routing 345pattern, they are used as load balancing. For example, to use 2 346servers ``serv1:3000`` and ``serv2:3000`` for request host 347``example.com`` and path ``/myservice``, you can write like so: 348 349.. code-block:: text 350 351 backend=serv1,3000;example.com/myservice 352 backend=serv2,3000;example.com/myservice 353 354You can also specify backend application protocol in 355:option:`--backend` option using ``proto`` keyword after pattern. 356Utilizing this allows ngttpx to route certain request to HTTP/2, other 357requests to HTTP/1. For example, to route requests to ``/ws/`` in 358backend HTTP/1.1 connection, and use backend HTTP/2 for other 359requests, do this: 360 361.. code-block:: text 362 363 backend=serv1,3000;/;proto=h2 364 backend=serv1,3000;/ws/;proto=http/1.1 365 366The default backend protocol is HTTP/1.1. 367 368TLS can be enabled per pattern basis: 369 370.. code-block:: text 371 372 backend=serv1,8443;/;proto=h2;tls 373 backend=serv2,8080;/ws/;proto=http/1.1 374 375In the above case, connection to serv1 will be encrypted by TLS. On 376the other hand, connection to serv2 will not be encrypted by TLS. 377 378Dynamic hostname lookup 379----------------------- 380 381By default, nghttpx performs backend hostname lookup at start up, or 382configuration reload, and keeps using them in its entire session. To 383make nghttpx perform hostname lookup dynamically, use ``dns`` 384parameter in :option:`--backend` option, like so: 385 386.. code-block:: text 387 388 backend=foo.example.com,80;;dns 389 390nghttpx will cache resolved addresses for certain period of time. To 391change this cache period, use :option:`--dns-cache-timeout`. 392 393Enable PROXY protocol 394--------------------- 395 396PROXY protocol can be enabled per frontend. In order to enable PROXY 397protocol, use ``proxyproto`` parameter in :option:`--frontend` option, 398like so: 399 400.. code-block:: text 401 402 frontend=*,443;proxyproto 403 404nghttpx supports both PROXY protocol v1 and v2. AF_UNIX in PROXY 405protocol version 2 is ignored. 406 407Session affinity 408---------------- 409 410Two kinds of session affinity are available: client IP, and HTTP 411Cookie. 412 413To enable client IP based affinity, specify ``affinity=ip`` parameter 414in :option:`--backend` option. If PROXY protocol is enabled, then an 415address obtained from PROXY protocol is taken into consideration. 416 417To enable HTTP Cookie based affinity, specify ``affinity=cookie`` 418parameter, and specify a name of cookie in ``affinity-cookie-name`` 419parameter. Optionally, a Path attribute can be specified in 420``affinity-cookie-path`` parameter: 421 422.. code-block:: text 423 424 backend=127.0.0.1,3000;;affinity=cookie;affinity-cookie-name=nghttpxlb;affinity-cookie-path=/ 425 426Secure attribute of cookie is set if client connection is protected by 427TLS. 428 429PSK cipher suites 430----------------- 431 432nghttpx supports pre-shared key (PSK) cipher suites for both frontend 433and backend TLS connections. For frontend connection, use 434:option:`--psk-secrets` option to specify a file which contains PSK 435identity 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: 438 439.. code-block:: text 440 441 client1:9567800e065e078085c241d54a01c6c3f24b3bab71a606600f4c6ad2c134f3b9 442 client2:b1376c3f8f6dcf7c886c5bdcceecd1e6f1d708622b6ddd21bda26ebd0c0bca99 443 444nghttpx server accepts any of the identity and secret pairs in the 445file. The default cipher suite list does not contain PSK cipher 446suites. In order to use PSK, PSK cipher suite must be enabled by 447using :option:`--ciphers` option. The desired PSK cipher suite may be 448listed in `HTTP/2 cipher black list 449<https://tools.ietf.org/html/rfc7540#appendix-A>`_. In order to use 450such PSK cipher suite with HTTP/2, disable HTTP/2 cipher black list by 451using :option:`--no-http2-cipher-black-list` option. But you should 452understand its implications. 453 454At the time of writing, even if only PSK cipher suites are specified 455in :option:`--ciphers` option, certificate and private key are still 456required. 457 458For backend connection, use :option:`--client-psk-secrets` option to 459specify a file which contains single PSK identity and secret. The 460format is the same as the file used by :option:`--psk-secrets` 461described above, but only first identity and secret pair is solely 462used, like so: 463 464.. code-block:: text 465 466 client2:b1376c3f8f6dcf7c886c5bdcceecd1e6f1d708622b6ddd21bda26ebd0c0bca99 467 468The default cipher suite list does not contain PSK cipher suites. In 469order to use PSK, PSK cipher suite must be enabled by using 470:option:`--client-ciphers` option. The desired PSK cipher suite may 471be listed in `HTTP/2 cipher black list 472<https://tools.ietf.org/html/rfc7540#appendix-A>`_. In order to use 473such PSK cipher suite with HTTP/2, disable HTTP/2 cipher black list by 474using :option:`--client-no-http2-cipher-black-list` option. But you 475should understand its implications. 476 477TLSv1.3 478------- 479 480As of nghttpx v1.34.0, if it is built with OpenSSL 1.1.1 or later, it 481supports TLSv1.3. 0-RTT data is supported, but by default its 482processing is postponed until TLS handshake completes to mitigate 483replay attack. This costs extra round trip and reduces effectiveness 484of 0-RTT data. :option:`--tls-no-postpone-early-data` makes nghttpx 485not wait for handshake to complete before forwarding request included 486in 0-RTT to get full potential of 0-RTT data. In this case, nghttpx 487adds ``Early-Data: 1`` header field when forwarding a request to a 488backend server. All backend servers should recognize this header 489field and understand that there is a risk for replay attack. See `RFC 4908470 <https://tools.ietf.org/html/rfc8470>`_ for ``Early-Data`` header 491field. 492 493nghttpx disables anti replay protection provided by OpenSSL. The anti 494replay protection of OpenSSL requires that a resumed request must hit 495the same server which generates the session ticket. Therefore it 496might not work nicely in a deployment where there are multiple nghttpx 497instances sharing ticket encryption keys via memcached. 498 499Because TLSv1.3 completely changes the semantics of cipher suite 500naming scheme and structure, nghttpx provides the new option 501:option:`--tls13-ciphers` and :option:`--tls13-client-ciphers` to 502change preferred cipher list for TLSv1.3. 503 504WebSockets over HTTP/2 505---------------------- 506 507nghttpx supports `RFC 8441 <https://tools.ietf.org/html/rfc8441>`_ 508Bootstrapping WebSockets with HTTP/2 for both frontend and backend 509connections. This feature is enabled by default and no configuration 510is required. 511 512Migration from nghttpx v1.18.x or earlier 513----------------------------------------- 514 515As of nghttpx v1.19.0, :option:`--ciphers` option only changes cipher 516list for frontend TLS connection. In order to change cipher list for 517backend connection, use :option:`--client-ciphers` option. 518 519Similarly, :option:`--no-http2-cipher-black-list` option only disables 520HTTP/2 cipher black list for frontend connection. In order to disable 521HTTP/2 cipher black list for backend connection, use 522:option:`--client-no-http2-cipher-black-list` option. 523 524``--accept-proxy-protocol`` option was deprecated. Instead, use 525``proxyproto`` parameter in :option:`--frontend` option to enable 526PROXY protocol support per frontend. 527 528Migration from nghttpx v1.8.0 or earlier 529---------------------------------------- 530 531As of nghttpx 1.9.0, ``--frontend-no-tls`` and ``--backend-no-tls`` 532have been removed. 533 534To disable encryption on frontend connection, use ``no-tls`` keyword 535in :option:`--frontend` potion: 536 537.. code-block:: text 538 539 frontend=*,3000;no-tls 540 541The TLS encryption is now disabled on backend connection in all modes 542by default. To enable encryption on backend connection, use ``tls`` 543keyword in :option:`--backend` option: 544 545.. code-block:: text 546 547 backend=127.0.0.1,8080;tls 548 549As of nghttpx 1.9.0, ``--http2-bridge``, ``--client`` and 550``--client-proxy`` options have been removed. These functionality can 551be used using combinations of options. 552 553Use following option instead of ``--http2-bridge``: 554 555.. code-block:: text 556 557 backend=<ADDR>,<PORT>;;proto=h2;tls 558 559Use following options instead of ``--client``: 560 561.. code-block:: text 562 563 frontend=<ADDR>,<PORT>;no-tls 564 backend=<ADDR>,<PORT>;;proto=h2;tls 565 566Use following options instead of ``--client-proxy``: 567 568.. code-block:: text 569 570 http2-proxy=yes 571 frontend=<ADDR>,<PORT>;no-tls 572 backend=<ADDR>,<PORT>;;proto=h2;tls 573 574We also removed ``--backend-http2-connections-per-worker`` option. It 575was present because previously the number of backend h2 connection was 576statically configured, and defaulted to 1. Now the number of backend 577h2 connection is increased on demand. We know the maximum number of 578concurrent streams per connection. When we push as many request as 579the maximum concurrency to the one connection, we create another new 580connection so that we can distribute load and avoid delay the request 581processing. This is done automatically without any configuration. 582