<div dir="ltr"><div>Thank you Jordan for the response.</div><div><br></div><div>Including the SNI information in cURL works, thank you. I wasn't aware this was so very different from TCP/HTTP2.</div><div><br></div><div>The point I was trying to make about the ssl_certificate options to be mandatory, is that HTTP/2 also requires SSL but recognizes that when ssl_reject_handshake=on it doesn't need the certificate. For HTTP/3 it doesn't seem to recognize that it doesn't need the certificate since it will reject handshakes anyways.<br></div><div><br></div><div>Kind regards,<div>Taco de Wolff</div></div><div><br></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">Op vr 1 mrt 2024 om 05:20 schreef J Carter <<a href="mailto:jordanc.carter@outlook.com" target="_blank">jordanc.carter@outlook.com</a>>:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">Hello,<br>
<br>
On Wed, 28 Feb 2024 21:45:37 -0300<br>
Taco de Wolff <<a href="mailto:tacodewolff@gmail.com" target="_blank">tacodewolff@gmail.com</a>> wrote:<br>
<br>
> Hi,<br>
> <br>
> I've noticed at least in 1.24.0 and 1.25.4 that adding an<br>
> ssl_reject_handshake to the default server breaks SNI for other<br>
> servers. Example:<br>
> <br>
> ```<br>
> server {<br>
> server_name _;<br>
> listen 80 default_server;<br>
> listen 443 default_server ssl;<br>
> listen 443 default_server quic reuseport;<br>
> listen [::]:80 default_server;<br>
> listen [::]:443 default_server ssl;<br>
> listen [::]:443 default_server quic reuseport;<br>
> <br>
> http2 on;<br>
> <br>
> # SSL<br>
> ssl_certificate /etc/pki/lego/certificates/server.crt;<br>
> ssl_certificate_key /etc/pki/lego/certificates/server.key;<br>
> ssl_trusted_certificate /etc/pki/lego/certificates/server.crt;<br>
> ssl_reject_handshake on;<br>
> <br>
> return 444;<br>
> }<br>
> <br>
> server {<br>
> server_name <a href="http://domain.com" rel="noreferrer" target="_blank">domain.com</a>;<br>
> listen 443 ssl;<br>
> listen 443 quic;<br>
> listen [::]:443 ssl;<br>
> listen [::]:443 quic;<br>
> <br>
> http2 on;<br>
> <br>
> root /srv/www/html;<br>
> <br>
> # SSL<br>
> ssl_certificate /etc/pki/lego/certificates/server.crt;<br>
> ssl_certificate_key /etc/pki/lego/certificates/server.key;<br>
> ssl_trusted_certificate /etc/pki/lego/certificates/server.crt;<br>
> <br>
> location / {<br>
> try_files /index.html =404;<br>
> }<br>
> }<br>
> ```<br>
> <br>
> There are two remarks for this example:<br>
> - While enabling HTTP/3 I had to add the ssl_certificate lines to the<br>
> default server, while using solely HTTP/2 this wasn't necessary. It<br>
> will throw an error on trying to start Nginx, is that a bug?<br>
<br>
TLS is mandatory for HTTP/3 (well, more accurately for QUIC).<br>
<br>
<a href="https://stackoverflow.com/questions/72826710/quic-transfer-protocol-need-not-tls" rel="noreferrer" target="_blank">https://stackoverflow.com/questions/72826710/quic-transfer-protocol-need-not-tls</a><br>
<br>
> - The ssl_reject_handshake in the default server will prevent proper<br>
> SNI matching for <a href="http://domain.com" rel="noreferrer" target="_blank">domain.com</a>. If I run `curl <a href="https://domain.com/" rel="noreferrer" target="_blank">https://domain.com/`</a> it<br>
> works fine, but `curl -k -H 'Host: <a href="http://domain.com" rel="noreferrer" target="_blank">domain.com</a>'<br>
> <a href="https://ipaddress-of-server/" rel="noreferrer" target="_blank">https://ipaddress-of-server/`</a> does not. When I remove<br>
> ssl_reject_handshake it works as expected<br>
> <br>
<br>
If you curl an IP Address rather than an FQDN, curl will not include<br>
SNI extension in client hello at all.<br>
<br>
ssl_reject_handshake, as the name suggests, rejects TLS handshakes prior<br>
to completion. Nginx cannot perform secondary search for correct server<br>
block using host/authority header, as that would require first<br>
completing handshake, and then parsing host/authority header.<br>
<br>
> My intent is to have a default server that responds to non-existing<br>
> domain names. Preferably it responds with 444, but requests over TLS<br>
> (such as old domains names with HTST) will throw a security warning<br>
> that the server's certificates don't match the request's virtual<br>
> host's domain name (as expected).<br>
> <br>
<br>
return 444; just a special return value that causes nginx to terminate<br>
connection, nothing get's sent back to the client at all. return<br>
directives (rewrite module more accurately) runs post TLS handshake<br>
though. For default server TLS connections with your present<br>
configuration - it will never get to that point.<br>
<br>
Generally ssl_reject_hanshake is preferable for terminating connections<br>
anyway, as it saves performing heavy TLS handshake.<br>
<br>
The return 444 is still relevant for plain text connections that reach<br>
your default server though, so I'd recommend still keeping it.<br>
<br>
> Instead of showing a security warning in the browser I prefer a<br>
> connection error, which is why I want to employ ssl_reject_handshake.<br>
<br>
Your present configuration should work fine then.<br>
<br>
> Kind regards,<br>
> Taco de Wolff<br>
_______________________________________________<br>
nginx mailing list<br>
<a href="mailto:nginx@nginx.org" target="_blank">nginx@nginx.org</a><br>
<a href="https://mailman.nginx.org/mailman/listinfo/nginx" rel="noreferrer" target="_blank">https://mailman.nginx.org/mailman/listinfo/nginx</a><br>
</blockquote></div></div>