[PATCH 00 of 12] HTTP/3 proxying to upstreams

Vladimir Homutov vl at inspert.ru
Mon Dec 25 16:52:41 UTC 2023


Hello, everyone,

and Merry Christmas to all!

I'm a developer of an nginx fork Angie.  Recently we implemented
an HTTP/3 proxy support in our fork [1].

We'd like to contribute this functionality to nginx OSS community.
Hence here is a patch series backported from Angie to the current
head of nginx mainline branch (1.25.3)

If you find patching and building nginx from source irritating in order
to test the feature, you can use the prebuilt packages of Angie [2]

[1] https://angie.software/en/http_proxy/#proxy-http-version
[2] https://angie.software/en/install/

Your feedback is welcome!

                                                    __.  .--,
*-/___,  ,-/___,-/___,-/___,-/___,           _.-.=,{\/ _/  /`)
 `\ _ ),-/___,-/___,-/___,-/___, )     _..-'`-(`._(_.;`   /
  /< \\=`\ _ )`\ _ )`\ _ )`\ _ )<`--''`     (__\_________/___,
         /< <\ </ /< /< /< </ /<           (_____Y_____Y___,


 *** CONFIGURATION ***

    The following configuration is minimally required to proxy to your
    HTTP/3-enabled server:

    http {
        server {
        ...

        location /foo {
            proxy_http_version 3;
            proxy_pass https://http3-server.example.com:4433;
        }
    }

    You may also need to configure SNI using the appropriate values
    for the "proxy_ssl_name" and "proxy_ssl_server_name" directives
    as well as certificates and other related things.

    There is a number of proxy_http3_<quic_foo> directives is available that
    configure quic settings.  For the interop testing purposes, HQ support
    is available.


    Below are technical details about the current state of the patch set.

 *** TESTS ***

    The patchset includes tests which are added to the "t" directory for
    convenience. Copy them to nginx-tests and run them as usual.
    Most of them are proxy tests adapted for use with HTTP/3.

 *** LIMITATIONS ***

    The following features are NOT implemented:

     * Trailers: it requires full trailers support in nginx first
     * Connection migration: does not seem necessary for proxying scenarios
     * 0RTT: currently not supported

    The SSL library requirements are the same as for the server-side support.
    There are some interoperability issues when using different libraries on
    client and server: the combination of  client + openssl/compat
    and server + boringssl leads to a handshake failure with an error:

    >> SSL_do_handshake() failed (SSL: error:10000132:SSL routines:
    >>                          OPENSSL_internal:UNEXPECTED_COMPATIBILITY_MODE)


 *** MULTIPLEXING ***

    With keepalive disabled, the HTTP/3 connection to backend is very similar
    to a normal TCP SSL connection: the connection is established, handshake
    is performed, the request stream is created and everything is closed
    when the request is completed.

    With keepalive enabled, the underlying QUIC connection is cached,
    and can be reused by another client. Each client is using its own
    QUIC connection.

    Theoretically, it is possible to use only one quic connection to each
    backend and use separate HTTP/3 streams to make requests. This is NOT
    currently implemented, as it requires more changes to the upstream
    and keepalive modules and has security implications.


 *** INTERNALS ***

    This is a first attempt to integrating the HTTP/3 proxy into nginx,
    so all currently exposed interfaces are not final.

    Probably, the HTTP/3 proxy should be implemented in a separate module.
    Currently it is a patch to the HTTP proxy module to minimize boilerplate.

    Things that need improvement:
        - client interface: the way to create client, start handshake and
          create first stream to use for request;
          The way SSL sessions are supported doesn't look good.

        - upstreams interface: one way is to hide quic details and make it
           feel more SSL-like, maybe even kind of SSL module.
           Probably need a separate keepalive module for HTTP/3 to
           allow some controlled level of multiplexing.

        - connection termination is quite tricky due to the handling of
          the underlying quic UDP connection and stream requests.
          Closing an HTTP/3 connection may be incorrect in some cases.

        - Some interop tests still fail. This is partly due to the nature
          of the tests. This part requires more work with hard-to-reproduce
          cases.



More information about the nginx-devel mailing list