Add HTTP/3 support#1531
Conversation
|
@swalkinshaw: Using |
|
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 |
|
Mind rebasing @strarsis ? Looks good otherwise and all the notes/documentation is appreciated. |
|
@swalkinshaw: Sure! I also have to test the HTTP/3 specific configuration a bit further. |
415a4de to
fc4239e
Compare
|
@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 |
|
😓 wow they really don't make this easy. I'll try and think of 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:
|
|
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 |
|
@swalkinshaw: Edit: After some real-world testing I noticed that some WordPress sites had redirect issues (on frontend) ( |
|
Apologies, just getting around to testing this myself now.
|
|
|
Plug might make sense, but at least for now we can just implement the 425 for non-GET requests in Nginx right? To keep it simple. I think once we do that the PR should be ready to merge |
|
@swalkinshaw: Added here: d33bbae. Needs some testing by me. I need to resolve the conflicts with main branch. |
|
@swalkinshaw: Thanks for the review, I overhauled some of the PR components, testing it locally before pushing. |
|
@strarsis I had to make these changes to provision successfully with this PR: diff --git a/trellis/roles/wordpress-setup/defaults/main.yml b/trellis/roles/wordpress-setup/defaults/main.yml
index 4eff909..408e627 100644
--- a/trellis/roles/wordpress-setup/defaults/main.yml
+++ b/trellis/roles/wordpress-setup/defaults/main.yml
@@ -1,11 +1,12 @@
site_uses_local_db: "{{ site_env.db_host == 'localhost' }}"
+wordpress_default_site: "{{ wordpress_sites.keys() | first }}"
nginx_wordpress_site_conf: wordpress-site.conf.j2
nginx_ssl_path: "{{ nginx_path }}/ssl"
nginx_sites_confs:
- src: no-default.conf.j2
- src: http3-reuseport.conf.j2
- enabled: "{{ nginx_http3_enabled and (sites_use_ssl | bool) and wordpress_default_site }}"
+ enabled: "{{ nginx_http3_enabled and (sites_use_ssl | bool) and (wordpress_default_site | length > 0) }}"
- src: ssl.no-default.conf.j2
enabled: false
diff --git a/trellis/roles/wordpress-setup/templates/wordpress-site.conf.j2 b/trellis/roles/wordpress-setup/templates/wordpress-site.conf.j2
index 5e0d2ea..b3b7772 100644
--- a/trellis/roles/wordpress-setup/templates/wordpress-site.conf.j2
+++ b/trellis/roles/wordpress-setup/templates/wordpress-site.conf.j2
@@ -9,10 +9,8 @@ server {
{% if nginx_http3_enabled and ssl_enabled -%}
# Listen on UDP for QUIC+HTTP/3
- listen [::]:443 quic{% if is_first_site_use_ssl %} reuseport{% endif -%};
- listen 443 quic{% if is_first_site_use_ssl %} reuseport{% endif -%};
- {% if is_first_site_use_ssl -%}# there has to be one listen quic directive with `reuseport` for working QUIC responses in current nginx version, using the first site.
- {% endif %}
+ listen [::]:443 quic;
+ listen 443 quic;
{% endif %}
http2 {{ nginx_http2_enabled | default(false) | ternary('on', 'off') }};Also should be worth noting at the top of this PR that it must be enabled by updating - nginx_http3_enabled: false
+ nginx_http3_enabled: true |
|
@retlehs: I fixed these issues. There were two mechanisms for satisfying nginx requirement of one single site having And I had to remember allowing UDP/443 through the hoster/hardware firewall... |
|
🙏 I’ve got this branch deployed at https://http3.roots-example-project.com/ for testing – will pull in your changes soon and test a reprovision |
|
I notice that many of these HTTP/3 online checker tools have issues even with established, HTTP/3 supporting sites. I test with curl with HTTP/3 build from Docker image to determine HTTP/3 support: Though Chrome appears to sometimes not using HTTP/3, for whatever heuristics. |
|
@retlehs: Also test with two different sites on same Trellis server. Due to how nginx demands one I also try to test 0-RTT, curl should be able to resume a session: Though there is some discussion how to make a WordPress site more safe against potential 0-RTT replay attacks. |
|
Addendum: RTT0 will not work currently as the @swalkinshaw, @retlehs: 🤔 Is it worth having the RTT0 feature additionally in this PR then? Or re-add it when |
|
Seems out of scope for this HTTP/3 PR. Since it's disabled by default and doesn't affect HTTP/3 functionality, I'd say keep it as-is for now and we can revisit it separately. PS. Pulled in your latest changes and reprovisioned https://http3.roots-example-project.com/ with no issues 🙏 |
|
👍 Alright, PR looks fine to me now. |
Docs updates for roots/trellis#1531 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
|
Got docs updates ready to go once this is merged and tagged: roots/docs#567 |
It may be helpful to note that port UDP/443 is required for HTTP/3/QUIC and that there is often a cloud or hardware firewall in front of and independent from the Trellis server that also needs to be configured to allow the HTTP/3 traffic in. |
|
@strarsis Good call out, thanks! Updated the docs |
|
@strarsis are you still removing RTT0 support? I agree we shouldn't even support it if it won't work with our Nginx which is all Trellis should care about. |
|
@swalkinshaw, @retlehs: Yes, I agree and removed the 0-RTT config from this PR now. 0-RTT support is highly experimental in nginx and also not directly related to HTTP, it is a TLS1.3 optimization feature with HTTP header support on top (Early data). Client support is also lacking: Only Firefox currently supports it as in March 2026. |
* Update Trellis docs for HTTP/3 support Docs updates for roots/trellis#1531 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Add HTTP/3 UDP port 443 firewall note Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
This PR adds the necessary configuration for proper HTTP/3 support (by
nginx) (with HTTP/1/HTTPS/2 co-existence).nginxdocumentation, forum threads (1; 2) are added to the configuration when HTTP/3 support is turned on.fermfirewall is also configured to allow inbound UDP/433 for QUIC (HTTP/3).The approach is also used in the previous PR for HTTPS (Conditionally add HTTPS inbound allow firewall rule #1530).
nginxrequires one (and only one listen quic directive to have thereuseportoption (only one listen quic directive can have thereuseportoption). As the listen quic directive requires a certificate, the first WordPress site ("vhost") that has HTTPS enabled, has thereuseportoption added to its listen quic directive.Additional notes (some may be useful in the documentation):
nginxand underlyingOpenSSLlibrary (March 2026) is required, though. For that reason it is disabled by default for now. 0-RTT can improve performance and is still a very new spec/feature, HTTP/3 works without it.of course it also needs to be configured for allowing inbound UDP/443 traffic for QUIC (HTTP/3) (example for Hetzner Cloud Firewall).
without this HTTP header, HTTP/3 will not work, despite everything else being perfectly configured and running.
443is actually not mandatory for HTTP/3 (to some degree, also depending on browser), but it is recommended to use the same port number443as for HTTPS (TCP),nginxthen listens on443/UDPin parallel to443/TCPfor HTTP/1/HTTPS/2.Protocolcolumn on).curl/wgetHTTP/3 support is not a given in current stable Ubuntu. I used acurl Docker image with HTTP/3 support.Useful resources
nginxHTTP/3 example configurationcurlwith HTTP/3 supportnginxadd_headerinheritance/pitfallsnginxHTTP/3 configurationnginxngx_http_v3HTTP/3 module documentationnginxwith HTTP1.1/2/3 with some encountered issuesGSO