roots / trellis

WordPress LEMP stack with PHP 8.2, Composer, WP-CLI and more
https://roots.io/trellis/
MIT License
2.5k stars 608 forks source link

Add `HTTP/3` support #1531

Open strarsis opened 3 months ago

strarsis commented 3 months ago

This PR adds the necessary configuration for proper HTTP/3 support (by nginx) (with HTTP/1/HTTPS/2 co-existence).

Additional notes (some may be useful in the documentation):

Useful resources

strarsis commented 3 months ago

@swalkinshaw: Using nginx includes makes the configuration much readable now.

strarsis commented 3 months ago

The SSL early data option allows for RTT-0 requests (zero round-trip time), however, it comes with security implications (possibility of replay attacks), the application layer (so the PHP WordPress app here) gets a HTTP Header Early-Data passed from the reverse proxy (nginx), and for risky operations (as authentication/login) the app has to terminate requests with HTTP 425 Too Early. I was not able to find any occurrence of this logic in WordPress code or plugins or discussions about this, hence I commented out this optimization until it is deemed safe for WordPress applications.

swalkinshaw commented 2 months ago

Mind rebasing @strarsis ? Looks good otherwise and all the notes/documentation is appreciated.

strarsis commented 2 months ago

@swalkinshaw: Sure! I also have to test the HTTP/3 specific configuration a bit further.

strarsis commented 2 months ago

@swalkinshaw: Well, I "rebased" it somehow. If necessary, I create a new branch/PR.

So it turned out that a global listen for QUIC with reuseport is necessary for working QUIC responses. For a QUIC listen is also a SSL certificate required, it does not matter which one. So for providing such a SSL certificate, one of the sites have to be specified as the "default site".

swalkinshaw commented 2 months ago

😓 wow they really don't make this easy. I'll try and think of another solution for the default site/SSL cert 🤔

strarsis commented 2 months ago

another solution for the default site/SSL cert

That listen quic is only needed for reuseport (apparently required by the nginx worker processes for correctly responding to QUIC requests). With listen quic nginx requires a SSL cert and key, but that listen and SSL would not be used otherwise.

Working, confirmed alternatives:

strarsis commented 2 months ago

Edit: jinja namespaces probably do not scope beyond the iteration of ansible template loops, so a different approach is used.

Now simply the first site that uses HTTPS will have the reuseports option added to its quic listen directive. For this a helper variable is added that contains all sites that use SSL (not the boolean one), and then just the item key is compared to determine whether the current config in jinja is the one for the first HTTPS using site.

strarsis commented 2 months ago

@swalkinshaw: Edit: After some real-world testing I noticed that some WordPress sites had redirect issues (on frontend) (ERR_TOO_MANY_REDIRECTS). I am not sure whether this has been caused by http/3. Still testing and observing the behavior with http/3 enabled. Possible related issue. This appears to be caused by the redirects, when HTTP/3 is advertised/used there.