Repository navigation
feat(nginx-proxy): Implement ssl_reject_handshake for missing certificates - #300
Merged
Merged
Conversation
…cates 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
There was a problem hiding this comment.
Pull request overview
This pull request implements the ssl_reject_handshake directive for vhosts without valid SSL certificates, improving security and user experience when accessing non-existent vhosts over HTTPS.
Changes:
- Modified the fallback HTTPS server block to conditionally use
ssl_reject_handshakewhen no default certificate is available - Changed the outer condition from checking default certificate existence to checking HTTPS method configuration
- Updated error response from 500 to 503 for vhosts without certificates
- Added comprehensive documentation about SSL certificate handling behavior
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.
| File | Description |
|---|---|
| nginx-proxy/nginx.tmpl | Updated fallback HTTPS server block logic to use ssl_reject_handshake when no default certificate exists, and changed condition logic to create the server block based on HTTPS method rather than certificate existence |
| nginx-proxy/README.md | Added new "SSL Certificate Handling" section documenting certificate lookup and fallback behavior |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Without it, an HTTPS request for a nohttps vhost matches a wildcard HTTPS vhost (e.g. sub.example.com against *.example.com) and is proxied to that site's backend. EasyEngine sets HTTPS_METHOD=nohttps on every site without SSL.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.

Summary
Changes the per-vhost HTTPS fallback in
nginx-proxy/nginx.tmplfor vhosts that have no certificate of their own, includingHTTPS_METHOD=nohttpsvhosts (EasyEngine sets that on every site without SSL).Problem
On develop, an HTTPS request for a vhost without its own certificate:
500when/etc/nginx/certs/default.crtand.keyexist;listen 443 sslserver).Change
The fallback server block is now rendered for every vhost without a certificate, whether or not a default certificate exists:
503(same status as the default server).ssl_reject_handshake on;, so the client gets a TLS alert instead of another site's certificate. This directive needs no certificate (nginx 1.19.4+).Keeping the block for
nohttpsvhosts matters: without an exact-name block, HTTPS for anohttpssub.example.comwould match an HTTPS*.example.comvhost and reach its backend.README: new "SSL Certificate Handling" section.
Testing
Built
nginx-proxyfrom this branch (jwilder/nginx-proxy 1.11.6, nginx 1.31.3) and ran it with docker-gen against test backends in a throwaway Docker-in-Docker container, compared with develop's template:nohttpsvhost, default cert presentnohttpssub.ms.testnext to an HTTPSms.test,*.ms.testvhost, default cert presentnginx -tpasses in every combination. Unknown hosts are unchanged: without a default certificate they still reach the first HTTPS vhost (EasyEngine always has one, so its default server answers 503). EasyEngine always createsdefault.crtwhen it starts the proxy, so on EE hosts the visible change is 500 → 503.Release
Needs a dockerfiles tag and an
nginx-proxybump in coreimg-versions.jsonto reach users.