nginx: fix HTTP/3 reuseport duplicates#5184
Conversation
|
This fix works. Thanks After this adjustment, however, the "HTTP/3 (QUIC)" option had to be set for all HTTP servers. |
|
@psychofaktory so it breaks if not all servers have the flag set? |
|
At least that was my observation. |
|
then it would make only sense as a global option and should not be configured per server or it is not configurable at all. |
|
Thank you for testing this @psychofaktory. Could you also try: curl -I --http3-only https://yourdomainI tested the scenario you described. Where HTTP3/QUIC was not enabled on all HTTP Servers and in my case it still behaved as expected. My output: curl -I --http3-only https://domain1.cz/
curl: (60) SSL: no alternative certificate subject name matches target hostname 'domain1.cz'
More details here: https://curl.se/docs/sslcerts.html
curl failed to verify the legitimacy of the server and therefore could not
establish a secure connection to it. To learn more about this situation and
how to fix it, please visit the webpage mentioned above.
~ ❯ curl -I --http3-only https://domain2.cz/
HTTP/3
...
~ ❯ curl -I --http3-only https://domain3.cz
HTTP/3
...HTTP3/QUIC was enabled on domain2 and domain3. After checking the Nginx config the reuseport was set on domain2. Domain1 was configured with HTTP/2 only. |
|
I have HTTP servers for one domain and for many subdomains of this domain. If the HTTP/3 (QUIC) option is not enabled on any HTTP server, everything works perfectly. Here the result of curl -I --http3-only https://subdomain1.mydomain.com
For testing purposes, I have now disabled HTTP/3 (QUIC) for subdomain1.mydomain.com only. As a result,
I really welcome the option to enable HTTP/3 (QUIC) via the GUI. |
|
Thank you, this is very useful feedback. It is interesting that your result differs from my testing. Maybe it is interfering with something else? If you are interested we can make more tests @psychofaktory. I was also considering whether this should be implemented as a global option instead. However, in the current plugin, HTTP/2 is configured per HTTP server as well. Based on my understanding of nginx, HTTP/3/QUIC should in principle also be possible per site, so I initially followed that model. That said, it seems I am probably not able to make the per-server approach work consistently for everyone. A global option may therefore be the better choice, but that is likely a decision for the maintainers of this repository / @fabianfrz. If the maintainers decide that a global option is more appropriate, I can rework this PR in that direction with their guidance on where and how it should be exposed in the plugin. |
|
If you ask me, I would vote for the global variant if per server is not possible. However this needs a proper documentation especially in the help texts and the changelog that if this is enabled, then all ports need to also whitelisted in the firewall so it is disabled by default and the admin can update the firewall rules before there are issues with the update as some people have auto updates on. If you want to, you can also make a global variant per port (tokenize list) as this might work as well (for example support H3 on 443 but not on 8443). @fichtner, @AdSchellevis: If this gets released, it probably needs a special mention in the release notes of the update. @psychofaktory What do you think about this approch? I guess that is the most optimal solution. |
|
This proposal sounds perfect to me. Basically, I would prefer a per-server approach, as settings could be selected more granularly. As far as I understand the specification, this should also be possible. However, one must also question the extent to which it makes sense to provide HTTP2 and then, in addition, HTTP3 only for other subdomains. At least in my setup, I see no reason not to provide HTTP3 for all HTTP servers. Therefore, a global option would be perfectly sufficient. Translated with DeepL.com (free version) |
Fix HTTP/3 reuseport duplicates
This PR fixes an Nginx config-generation issue introduced while adding optional HTTP/3 (QUIC) support in nginx: add optional HTTP/3 #5071.
When multiple server blocks ended up emitting
reuseportfor the samelisten(sameaddress:port), Nginx failed to start.Reference PR: nginx: add optional HTTP/3 (#5071)
Problem
With HTTP/3 enabled on more than one server for the same
address:port, the generated configuration could containreuseportmultiple times for the same socket.reuseportis a socket option and must be applied consistently for a givenaddress:port. When duplicated across multiple server blocks for the same listener, Nginx reports an error and refuses to start.Fix
We now emit
reuseportexactly once peraddress:portfor HTTP/3:listenfor a givenaddress:portgets:quic reuseportlistendirectives for the sameaddress:portget:quic(withoutreuseport)This guarantees that the socket option is not duplicated and prevents Nginx from failing due to conflicting listen parameters.
Testing
Tested on a local OPNsense instance with multiple server blocks sharing the same
address:portand HTTP/3 enabled on more than one of them.If you have a different setup (especially more complex listener/server combinations), please give it a quick try — there may still be edge cases I did not cover.