From 69bfdc11a0d136390fe640b207d47428efa8060a Mon Sep 17 00:00:00 2001 From: Riddhesh Sanghvi Date: Fri, 16 Jan 2026 13:27:12 +0530 Subject: [PATCH] feat(nginx-proxy): Implement ssl_reject_handshake for missing certificates Instead of serving 500 errors with default certificates when a vhost has no valid SSL certificate, nginx now: 1. Uses default certificate (if available) and returns 503 2. Rejects the SSL/TLS handshake entirely (if no default cert) Benefits: - Prevents certificate warning dialogs in browsers - More secure - doesn't expose invalid/default certificates - Cleaner failure mode for unknown hosts - Matches upstream jwilder/nginx-proxy behavior Changes: - Updated fallback HTTPS server block to use ssl_reject_handshake - Added condition to check for default certificate availability - Changed status code from 500 to 503 for better HTTP semantics - Documented SSL certificate handling behavior in README --- nginx-proxy/README.md | 22 ++++++++++++++++++++++ nginx-proxy/nginx.tmpl | 11 +++++++++-- 2 files changed, 31 insertions(+), 2 deletions(-) diff --git a/nginx-proxy/README.md b/nginx-proxy/README.md index 5051c7e..3814d07 100644 --- a/nginx-proxy/README.md +++ b/nginx-proxy/README.md @@ -130,6 +130,28 @@ deny all; --- +## SSL Certificate Handling + +### Certificate Lookup + +The proxy automatically detects SSL certificates from `/etc/nginx/certs/`: + +```bash +/etc/nginx/certs/example.com.crt +/etc/nginx/certs/example.com.key +``` + +### Fallback Certificate Behavior + +When a vhost is accessed via HTTPS but no matching certificate is found: + +1. **If default certificate exists:** Uses `/etc/nginx/certs/default.crt` and returns 503 +2. **If no default certificate:** Rejects the SSL/TLS handshake + +This prevents certificate warning dialogs in browsers and improves security by not exposing invalid certificates. + +--- + ## Environment Variables | Variable | Description | Default | diff --git a/nginx-proxy/nginx.tmpl b/nginx-proxy/nginx.tmpl index 25e9995..62bb7c9 100644 --- a/nginx-proxy/nginx.tmpl +++ b/nginx-proxy/nginx.tmpl @@ -554,7 +554,7 @@ server { {{ end }} } -{{ if (and (not $is_https) (exists "/etc/nginx/certs/default.crt") (exists "/etc/nginx/certs/default.key")) }} +{{ if (and (not $is_https) (ne $https_method "nohttps")) }} server { server_name {{ $host }}; listen 443 ssl {{ $default_server }}; @@ -563,10 +563,17 @@ server { listen [::]:443 ssl {{ $default_server }}; http2 on; {{ end }} - return 500; + {{ if (and (exists "/etc/nginx/certs/default.crt") (exists "/etc/nginx/certs/default.key")) }} + # Use default certificate as fallback ssl_certificate /etc/nginx/certs/default.crt; ssl_certificate_key /etc/nginx/certs/default.key; + {{ else }} + # No valid certificate for this vhost nor default certificate found, so reject SSL handshake + ssl_reject_handshake on; + {{ end }} + + return 503; } {{ end }}