Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for QUIC and HTTP/3 #230

Open
charescape opened this issue Jan 10, 2024 · 10 comments
Open

Add support for QUIC and HTTP/3 #230

charescape opened this issue Jan 10, 2024 · 10 comments
Labels
enhancement New feature or request help wanted Extra attention is needed

Comments

@charescape
Copy link

Is there any plan to add support for HTTP/3 since it is now supported in all major browsers?

@gene1wood
Copy link
Collaborator

No, but PRs are welcome to add this.

@janbrasna
Copy link
Collaborator

The complicated part is not client support, but rather server support.

Nowadays it's still mostly experimental, behind forked modules, custom OpenSSL 3.2+QUIC builds etc. — so at the moment it's not a matter of a config flag to enable — it usually means some elbow grease to manually build your complete environment with the h3-enabled TLS stack in mind, often via BoringSSL or alternatives like QuicTLS. One of the main advantages of QUIC design is that it's not deeply tied to the host OSes and kernels and is mostly designed to live in the userspace to be more easily updated for new features etc., so there's a paradigm shift the traditional crypto/TLS provides can't seem to navigate effectively. It's slowly getting implemented at clients, APIs for servers are further down the roadmaps to stabilize… and we're barely out of draft revision and incompatibilities like when TLSv1.3 gradually made its way to final RFC version. Even cURL don't want to make any stability promises until any of the libraries needed exit experimental stage. Most products need to implement QUIC in a custom fashion to benefit from the likes of UDP connectionlessness, QPACK streams, 0-RTT, CID, BBR and other HTTP/3 changes so general use in server software without close ties to the actual application level is rather slow, and many wait for OpenSSL to build their own stack (since the way to just enable API integration from a few years ago hit a wall when OpenSSL clearly stated they won't integrate with existing QUIC stacks: openssl/openssl#8797 (comment) …)

Further reading to get the idea:

From the perspective of @mozilla/ssl-config-generator or @mozilla/server-side-tls there's currently no need to tweak the TLS settings and turn configuration knobs, not unlike with TLSv1.3 "modern" config using basically the defaults, as it was designed to use only the better parts of the TLS world from "lessons learned". I don't think (and honestly only hope!) we won't need to fine tune any TLSv1.3 or HTTP/3 configuration outputs in the near future.
(And on the other hand adding the rulesets for protocols, APIs and ports and headers needed for h3 upgrades might be too specific to the stacks used with great variability right now, to provide one-liner config flags — we're probably not there yet either, if that's ever the scope of the config tool.)

Then, when you have some lovely h3 support like in Caddy, it's just there by default; nothing to configure. 🚀

@janbrasna
Copy link
Collaborator

@charescape TL;DR right now it's slightly painful to provide config lines for h3 upgrades when you need to compile experimental features hidden behind flags or in non-mainline binaries and link against alternative TLS implementations outside of main distros to get any meaningful QUIC support in the first place. 🤷

(I can imagine the h3 upgrade lines inactive behind # comments for sure, it's the documentation overhead needed to explain it just doesn't work out of the box that sounds like a nightmare to present to the generated config consumers right now.)

@janbrasna janbrasna added enhancement New feature or request help wanted Extra attention is needed labels Oct 4, 2024
@charescape
Copy link
Author

One more further reading to get the idea: https://nginx.org/en/docs/http/ngx_http_v3_module.html

@Lordfirespeed
Copy link

Lordfirespeed commented Oct 26, 2024

My two cents: as @charescape has pointed out, nginx on Ubuntu (actually, most Linux distributions) does not require any compilation from sources to enable http3, provided you have a recent version of openssl (I am using 3.0.13)

Assuming you already have a working https configuration, the steps are (roughly)

  • Allow UDP traffic through port 443 on your firewall
  • advertise that your server supports http3:
    add_header Alt-Svc 'h3=":443"; ma=86400';
  • prepend the following to your existing listen directives
    listen [::]:443 quic reuseport;
    listen 443 quic reuseport;
    
  • (Optionally, but ideally) prepend the TLS1.3-specific ciphers to ssl-ciphers see comment from @janbrasna below
    ssl-ciphers "TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256:TLS_AES_128_GCM_SHA256:...`
    
    

Would contributions be accepted that add http3 support solely for nginx? or is this the kind of thing maintainers would prefer not to adopt incrementally?

@gstrauss
Copy link
Collaborator

Would contributions be accepted that add http3 support solely for nginx? or is this the kind of thing maintainers would prefer not to adopt incrementally?

I think we would accept support incrementally, though I would prefer entries in js/configs.js with version number supporting http3, similar to what is now done with tls13 to indicate support for TLSv1.3. Since nginx ngx_http_v3_module is not currently built by default and requires that distro packagers provide it, perhaps config directives to enable http3 in nginx should be provided, but commented out, when nginx and openssl versions support it.

@janbrasna
Copy link
Collaborator

Generally h3 config is out of scope here, unless it's relevant to the guidelines. If/when battle tested enough, it can be added as part of the boilerplate, similar to h2 additions here, preferably relative to tls13 presence in the outputs — but unless real world usage shows otherwise, the authors still treat it as experimental:

https://nginx.org/en/docs/http/ngx_http_v3_module.html

The ngx_http_v3_module module (1.25.0) provides experimental support for HTTP/3.

This module is not built by default, it should be enabled with the --with-http_v3_module configuration parameter.

An SSL library that provides QUIC support such as BoringSSL, LibreSSL, or QuicTLS is recommended to build and run this module. Otherwise, when using the OpenSSL library, OpenSSL compatibility layer will be used that does not support early data. Known Issues: The module is experimental, caveat emptor applies.

(Once again, this would be a nice addition if the necessary rules were simple, neat and universal; but right now there's a lot of ifs and whens needed, and that's hard to convey inside a config template output without long explanations and commented-out variants, esp. with different listen directives — that sounds more like a UI checkbox to opt-in into a h3–enabled config, when you know you can support the necessary prerequisites.)

The compat layer is a great effort from the nginx folks, so it would be worth supporting it here as the most straightforward path, but it still sounds like a lot explainers would need to be added to the output config though.

There's no equivalent of Apache's ifmodule to place the extras behind a feature check unfortunately.

https://github.com/digitalocean/nginxconfig.io has it opt-in, too:

Screen Shot 2024-10-28 at 13 59 13

(NB: I don't see them a) add the alt-svc header, b) use the present day style of h2 config instead of the listen directive, so that may not be even up to date for current syntax fwiw…)

@gstrauss Feature support that doesn't have impact on config output feasibility is only in the conditional logic inside hbs version checks. But if the addition of reuseport may or may not be relevant to the consumer based on h3 interest/feasibility or not, that's not something to easily just comment out or provide based on server version, that's something based on an extra decision — and if we should introduce this extra decision (as compared to h2 rules scattered around, that have basically no compatibility impact, and can be included always) — is it worth the extra layers of complexity added, right now, when it can't really be used by folks who don't have the necessary background to actually make sure such config would work for them out of the box and not just error out? (Or worse, wholesale advertise h3 alt-svc and then not really provide it…)

I think the most important bit that's out of our config scope is the UDP support necessary, besides verifying the module is actually available.

FYI @Lordfirespeed, TLSv1.3 cipher suites are not configured there, see #124.

That said, it would be a welcome addition if the configs don't cease to work for some consumers thanks to such change. Feel free to chime in with more real world experience, I think we'd be happy to start adding h3 support on per-server basis if the change is simple enough not to warrant an app-wide impact first, and/or if it turns out to be feasible without an explicit opt-in feature switch to make sure we're not breaking anyone downstream to start with.

@Lordfirespeed
Copy link

Lordfirespeed commented Oct 28, 2024

Since nginx ngx_http_v3_module is not currently built by default and requires that distro packagers provide it

Perhaps I didn't quite communicate my point: ngx_http_v3_module is currently included by default in all Linux binary packages [hosted at http://nginx.org/packages] starting from version 1.25.0. Reference

OpenSSL has supported the TLS1.3-specific ciphersuites since version 1.1.1, 2018.

OpenSSL includes features necessary for making QUIC connections 'as a client' since version 3.2, 2023 - it's not obvious to me which version is sufficient for making connections as a server, though.

@Lordfirespeed
Copy link

Lordfirespeed commented Oct 28, 2024

@janbrasna Thankyou for the comprehensive write-up :)

Yes, I see what you're getting at - even if the module is included by default, it's still advertised experimental, so not ideal from that standpoint.

Re lack of ifmodule - that could be worked around by adding an input for users to provide their nginx -V output, from which the included compiled modules can be inferred. I'll be the first to admit that might be a bit too clunky, though.

The reuseport thing is a bit quirky

  • you must specify reuseport at least once for each address:port combination using HTTP3, or the configuration is deemed invalid as a single server block declares multiple listen directives on the same address:port combination
  • you must specify reuseport at most once for an address:port combination in any scenario, or the configuration is deemed invalid as the reuseport directive cannot be used multiple times

in practise, this means that you must select one 'special' server block that includes the reuseport directives, and the rest must omit them.

That's obviously not ideal for a config template that people expect to 'just work' in any scenario; whether or not it works is dependent on their existing configuration.

@qwerty199369
Copy link

qwerty199369 commented Nov 15, 2024

Since Sept 2024, HTTP3 is enabled for all users of Safari 16 and newer. Before then, it was enabled for a subset of users.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request help wanted Extra attention is needed
Projects
None yet
Development

No branches or pull requests

6 participants