From dcaf201b0c9b6e81239bb732ee6b5d0be9c54450 Mon Sep 17 00:00:00 2001 From: Jan Chlouba Date: Wed, 17 Dec 2025 10:30:41 +0100 Subject: [PATCH] nginx: add optional HTTP/3 support with dynamic Alt-Svc (#5071) --- .../OPNsense/Nginx/forms/httpserver.xml | 7 +++++++ .../mvc/app/models/OPNsense/Nginx/Nginx.xml | 4 ++++ .../service/templates/OPNsense/Nginx/http.conf | 14 ++++++++++++++ 3 files changed, 25 insertions(+) diff --git a/www/nginx/src/opnsense/mvc/app/controllers/OPNsense/Nginx/forms/httpserver.xml b/www/nginx/src/opnsense/mvc/app/controllers/OPNsense/Nginx/forms/httpserver.xml index 21f8b4a28..cc441d1a1 100644 --- a/www/nginx/src/opnsense/mvc/app/controllers/OPNsense/Nginx/forms/httpserver.xml +++ b/www/nginx/src/opnsense/mvc/app/controllers/OPNsense/Nginx/forms/httpserver.xml @@ -173,6 +173,13 @@ Enable the HTTP/2 protocol. true + + httpserver.enable_http3 + + checkbox + Enable HTTP/3/QUIC for this server (adds QUIC listeners and Alt-Svc header). + true + httpserver.tls_protocols diff --git a/www/nginx/src/opnsense/mvc/app/models/OPNsense/Nginx/Nginx.xml b/www/nginx/src/opnsense/mvc/app/models/OPNsense/Nginx/Nginx.xml index 88d65ee88..58c73dd62 100644 --- a/www/nginx/src/opnsense/mvc/app/models/OPNsense/Nginx/Nginx.xml +++ b/www/nginx/src/opnsense/mvc/app/models/OPNsense/Nginx/Nginx.xml @@ -801,6 +801,10 @@ 1 Y + + 0 + Y + Y Y diff --git a/www/nginx/src/opnsense/service/templates/OPNsense/Nginx/http.conf b/www/nginx/src/opnsense/service/templates/OPNsense/Nginx/http.conf index f787eff2c..cc316538a 100644 --- a/www/nginx/src/opnsense/service/templates/OPNsense/Nginx/http.conf +++ b/www/nginx/src/opnsense/service/templates/OPNsense/Nginx/http.conf @@ -120,8 +120,19 @@ server { {% endif %} {% if server.listen_https_address is defined and server.listen_https_address != '' %} +{% set http3_alt_svc_ports = [] %} {% for listen_address in server.listen_https_address.split(',') %} listen {{ listen_address }} ssl{% if server.proxy_protocol is defined and server.proxy_protocol == '1' %} proxy_protocol{% endif %}{% if server.default_server is defined and server.default_server == '1' %} default_server{% endif %}; +{% if server.enable_http3|default("0") == "1" %} + listen {{ listen_address }} quic reuseport{% if server.default_server is defined and server.default_server == '1' %} default_server{% endif %}; +{% set listen_address_clean = listen_address.replace(' ', '') %} +{% if listen_address_clean != '' %} +{% set listen_port = listen_address_clean.split(':')[-1] %} +{% if listen_port not in http3_alt_svc_ports %} +{% do http3_alt_svc_ports.append(listen_port) %} +{% endif %} +{% endif %} +{% endif %} {% endfor %} http2 {% if server.http2|default("1") == "1" %}on{% else %}off{% endif %}; {% if server.tls_reject_handshake is defined and server.tls_reject_handshake == '1'%} @@ -155,6 +166,9 @@ server { {% else %} ssl_stapling off; {% endif %} +{% if server.enable_http3|default("0") == "1" and http3_alt_svc_ports|length > 0 %} + add_header Alt-Svc '{% for listen_port in http3_alt_svc_ports %}h3=":{{ listen_port }}"; ma=86400{% if not loop.last %}, {% endif %}{% endfor %}' always; +{% endif %} {% endif %} {% endif %} {% if server.resolver is defined and server.resolver != '' %}