-
Notifications
You must be signed in to change notification settings - Fork 7.4k
Description
Environment
Include the result of the following commands:
nginx version: nginx/1.28.0 built with OpenSSL 3.5.0 8 Apr 2025 (running with OpenSSL 3.5.1 1 Jul 2025) TLS SNI support enabled configure arguments: --prefix=/var/lib/nginx --sbin-path=/usr/sbin/nginx --modules-path=/usr/lib/nginx/modules --conf-path=/etc/nginx/nginx.conf --pid-path=/run/nginx/nginx.pid --lock-path=/run/nginx/nginx.lock --http-client-body-temp-path=/var/lib/nginx/tmp/client_body --http-proxy-temp-path=/var/lib/nginx/tmp/proxy --http-fastcgi-temp-path=/var/lib/nginx/tmp/fastcgi --http-uwsgi-temp-path=/var/lib/nginx/tmp/uwsgi --http-scgi-temp-path=/var/lib/nginx/tmp/scgi --with-perl_modules_path=/usr/lib/perl5/vendor_perl --user=nginx --group=nginx --with-threads --with-file-aio --with-http_ssl_module --with-http_v2_module --with-http_v3_module --with-http_realip_module --with-http_addition_module --with-http_xslt_module=dynamic --with-http_image_filter_module=dynamic --with-http_geoip_module=dynamic --with-http_sub_module --with-http_dav_module --with-http_flv_module --with-http_mp4_module --with-http_gunzip_module --with-http_gzip_static_module --with-http_auth_request_module --with-http_random_index_module --with-http_secure_link_module --with-http_degradation_module --with-http_slice_module --with-http_stub_status_module --with-http_perl_module=dynamic --with-mail=dynamic --with-mail_ssl_module --with-stream=dynamic --with-stream_ssl_module --with-stream_realip_module --with-stream_geoip_module=dynamic --with-stream_ssl_preread_module --add-dynamic-module=/home/buildozer/aports/main/nginx/src/njs-0.9.0/nginx --add-dynamic-module=/home/buildozer/aports/main/nginx/src/ngx_devel_kit-0.3.3/ --add-dynamic-module=/home/buildozer/aports/main/nginx/src/ngx_dynamic_healthcheck-1.3.8/ --add-dynamic-module=/home/buildozer/aports/main/nginx/src/ngx_dynamic_upstream-2.3.4/ --add-dynamic-module=/home/buildozer/aports/main/nginx/src/traffic-accounting-nginx-module-2.0/ --add-dynamic-module=/home/buildozer/aports/main/nginx/src/array-var-nginx-module-0.06/ --add-dynamic-module=/home/buildozer/aports/main/nginx/src/nginx-auth-jwt-0.9.0/ --add-dynamic-module=/home/buildozer/aports/main/nginx/src/ngx_brotli-1.0.0rc/ --add-dynamic-module=/home/buildozer/aports/main/nginx/src/ngx_cache_purge-2.5.3/ --add-dynamic-module=/home/buildozer/aports/main/nginx/src/nginx_cookie_flag_module-1.1.0/ --add-dynamic-module=/home/buildozer/aports/main/nginx/src/nginx-dav-ext-module-3.0.0/ --add-dynamic-module=/home/buildozer/aports/main/nginx/src/echo-nginx-module-0.63/ --add-dynamic-module=/home/buildozer/aports/main/nginx/src/encrypted-session-nginx-module-0.09/ --add-dynamic-module=/home/buildozer/aports/main/nginx/src/ngx-fancyindex-0.5.2/ --add-dynamic-module=/home/buildozer/aports/main/nginx/src/ngx_http_geoip2_module-3.4/ --add-dynamic-module=/home/buildozer/aports/main/nginx/src/headers-more-nginx-module-0.38/ --add-dynamic-module=/home/buildozer/aports/main/nginx/src/nginx-keyval-0.3.0/ --add-dynamic-module=/home/buildozer/aports/main/nginx/src/nginx-log-zmq-1.0.0/ --add-dynamic-module=/home/buildozer/aports/main/nginx/src/lua-nginx-module-0.10.28/ --add-dynamic-module=/home/buildozer/aports/main/nginx/src/lua-upstream-nginx-module-0.07/ --add-dynamic-module=/home/buildozer/aports/main/nginx/src/naxsi-1.7/naxsi_src --add-dynamic-module=/home/buildozer/aports/main/nginx/src/nchan-1.3.7/ --add-dynamic-module=/home/buildozer/aports/main/nginx/src/redis2-nginx-module-0.15/ --add-dynamic-module=/home/buildozer/aports/main/nginx/src/set-misc-nginx-module-0.33/ --add-dynamic-module=/home/buildozer/aports/main/nginx/src/nginx-http-shibboleth-2.0.2/ --add-dynamic-module=/home/buildozer/aports/main/nginx/src/ngx_slowfs_cache-1.11/ --add-dynamic-module=/home/buildozer/aports/main/nginx/src/ngx_http_untar_module-1.1/ --add-dynamic-module=/home/buildozer/aports/main/nginx/src/nginx-upload-module-2.3.0/ --add-dynamic-module=/home/buildozer/aports/main/nginx/src/nginx-upload-progress-module-0.9.4/ --add-dynamic-module=/home/buildozer/aports/main/nginx/src/nginx-upstream-fair-0.1.3/ --add-dynamic-module=/home/buildozer/aports/main/nginx/src/ngx_upstream_jdomain-1.5.2/ --add-dynamic-module=/home/buildozer/aports/main/nginx/src/nginx-vod-module-1.33/ --add-dynamic-module=/home/buildozer/aports/main/nginx/src/nginx-module-vts-0.2.4/ --add-dynamic-module=/home/buildozer/aports/main/nginx/src/mod_zip-1.3.0/ --add-dynamic-module=/home/buildozer/aports/main/nginx/src/zstd-nginx-module-0.1.1/ --add-dynamic-module=/home/buildozer/aports/main/nginx/src/nginx-rtmp-module-1.2.2/
Linux 19a7edd96782 6.12.24-Unraid #1 SMP PREEMPT_DYNAMIC Sat May 3 00:12:52 PDT 2025 x86_64 GNU/Linux
Description
I successfully use mTLS based authentication with NGINX to protect my sites.
After activating http3 in my nginx.conf and enabling it for my site confs, all sites where mTLS is configured stopped working. When http3 was disabled either in nginx.conf or the site conf it started working again. Also when mTLS was disabled for a specific site the site loaded with http3.
This is a known issue reported before but not fixed yet:
- After enabling mTLS, the HTTP3 protocol fails to take effect. #394
- https://trac.nginx.org/nginx/ticket/2626
Following config changes were used to activate http3:
-
nginx.conf: http3 on;
-
site.conf: listen 443 quic;
-
The bug is reproducible with the latest version of nginx
-
The nginx configuration is minimized to the smallest possible
to reproduce the issue and doesn't contain third-party modules
nginx configuration
## Version 2025/05/31 - Changelog: https://github.com/linuxserver/docker-baseimage-alpine-nginx/commits/3.22/root/defaults/nginx/nginx.conf.sample
### Based on alpine defaults
# https://git.alpinelinux.org/aports/tree/main/nginx/nginx.conf?h=3.22-stable
user abc;
# Set number of worker processes automatically based on number of CPU cores.
include /config/nginx/worker_processes.conf;
# Enables the use of JIT for regular expressions to speed-up their processing.
pcre_jit on;
# Configures default error logger.
####error_log /config/log/nginx/error.log;
#### Disable NGINX error log
error_log /dev/null;
# Includes files with directives to load dynamic modules.
include /etc/nginx/modules/*.conf;
# Include files with config snippets into the root context.
include /etc/nginx/conf.d/*.conf;
events {
# The maximum number of simultaneous connections that can be opened by
# a worker process.
worker_connections 1024;
}
http {
# Includes mapping of file name extensions to MIME types of responses
# and defines the default type.
include /etc/nginx/mime.types;
default_type application/octet-stream;
# Name servers used to resolve names of upstream servers into addresses.
# It's also needed when using tcpsocket and udpsocket in Lua modules.
#resolver 1.1.1.1 1.0.0.1 2606:4700:4700::1111 2606:4700:4700::1001;
include /config/nginx/resolver.conf;
# Don't tell nginx version to the clients. Default is 'on'.
server_tokens off;
# Specifies the maximum accepted body size of a client request, as
# indicated by the request header Content-Length. If the stated content
# length is greater than this size, then the client receives the HTTP
# error code 413. Set to 0 to disable. Default is '1m'.
client_max_body_size 0;
# Sendfile copies data between one FD and other from within the kernel,
# which is more efficient than read() + write(). Default is off.
sendfile on;
# Causes nginx to attempt to send its HTTP response head in one packet,
# instead of using partial frames. Default is 'off'.
tcp_nopush on;
# all ssl related config moved to ssl.conf
# included in server blocks where listen 443 is defined
# Enable gzipping of responses.
#gzip on;
# Set the Vary HTTP header as defined in the RFC 2616. Default is 'off'.
gzip_vary on;
# Helper variable for proxying websockets.
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}
# Enable http2 by default for all servers
http2 on;
http3 on;
quic_retry on;
# Sets the path, format, and configuration for a buffered log write.
access_log /config/log/nginx/access.log;
client_body_temp_path /tmp/nginx 1 2;
proxy_temp_path /tmp/nginx-proxy;
fastcgi_temp_path /tmp/nginx-fastcgi;
uwsgi_temp_path /tmp/nginx-uwsgi;
scgi_temp_path /tmp/nginx-scgi;
proxy_cache_path /tmp/nginx-proxy-cache keys_zone=lsio-proxy:10m;
fastcgi_cache_path /tmp/nginx-fcgi-cache keys_zone=lsio-fcgi:10m;
scgi_cache_path /tmp/nginx-scgi-cache keys_zone=lsio-scgi:10m;
uwsgi_cache_path /tmp/nginx-uwsgi-cache keys_zone=lsio-uwsgi:10m;
# Includes virtual hosts configs.
include /etc/nginx/http.d/*.conf;
include /config/nginx/site-confs/*.conf;
#### Conditional mTLS - Direct access in LAN and Forced mTLS Auth over WAN
geo $intranet {
default 0;
192.168.1.0/24 1;
}
}
daemon off;
pid /run/nginx.pid;
site configuration with working mTLS (http3 disabled)
server {
listen 443 ssl;
# listen 443 quic;
server_name tn.*;
include /config/nginx/ssl.conf;
client_max_body_size 0;
ssl_client_certificate /config/custom_ssl/ca.crt;
ssl_verify_client optional;
set $verify $intranet$ssl_client_verify;
if ($verify ~ (0NONE|0FAILED)) {
return 444;
}
location / {
include /config/nginx/proxy.conf;
include /config/nginx/resolver.conf;
set $upstream_app triliumnext;
set $upstream_port 8080;
set $upstream_proto http;
proxy_pass $upstream_proto://$upstream_app:$upstream_port;
}
site configuration with non-working mTLS (http3 enabled)
server {
listen 443 ssl;
listen 443 quic;
server_name tn.*;
include /config/nginx/ssl.conf;
client_max_body_size 0;
ssl_client_certificate /config/custom_ssl/ca.crt;
ssl_verify_client optional;
set $verify $intranet$ssl_client_verify;
if ($verify ~ (0NONE|0FAILED)) {
return 444;
}
location / {
include /config/nginx/proxy.conf;
include /config/nginx/resolver.conf;
set $upstream_app triliumnext;
set $upstream_port 8080;
set $upstream_proto http;
proxy_pass $upstream_proto://$upstream_app:$upstream_port;
}