<div dir="ltr"><div class="gmail_quote"><div dir="ltr"><div>Hello,</div><div><br></div><div>Observed nginx's 
version 1.22.1 questionable behaviour with two virtual hosts, one with H2 - enabled, second without http2 support.</div><div>Both on the same IP and port, with different domain names/server names.</div><div>When browsers make requests to a second domain, h2 being ALPN-negotiated, and data transferred via HTTP/2, in spite of http2 was not configured on that virtual host.<br></div><div></div><div><br></div><div>Sample config snippet:</div><div><br></div><div>http {</div><div>
...

</div><div>    server {<br>        listen          1985 http2 ssl;<br>        server_name     '<a href="http://mavr.cp.eu" target="_blank">mavr.cp.eu</a>';<br><br>        ssl_certificate     domain.cer;<br>        ssl_certificate_key domain.key;<br><br>        location / {<br>            return 302 https://zavr.cp.eu:1985$request_uri;<br>        }<br>    }<br><br>    server {<br>        listen          1985 ssl; # NO h2!<br>        server_name     '<a href="http://zavr.cp.eu" target="_blank">zavr.cp.eu</a>';<br><br>        ssl_certificate     domain.cer;<br>        ssl_certificate_key domain.key;<br><br>        location / {</div><div>            # Doesn't really matter what's here, for simplicity I've used ngx_lua_module.<br></div><div>            echo "Server protocol: $server_protocol H2 connection: $http2 .";<br>        }<br>    }<br></div><div>...<br></div><div>}</div><div><br></div><div>When I type <a href="https://mavr.cp.eu:1985" target="_blank">https://mavr.cp.eu:1985</a> in browser I see:</div><div><br></div><div>1. Browser negotiates h2 ALPN with the server 
with SNI <a href="http://mavr.cp.eu" target="_blank">mavr.cp.eu</a>



;</div><div>2. Server replied with 302 redirect to 
<a href="https://zavr.cp.eu:1985" target="_blank">https://zavr.cp.eu:1985</a> (expected)<br></div><div>3. Browser makes NEW TCP-connection with the server with SNI 
<a href="http://zavr.cp.eu" target="_blank">zavr.cp.eu</a>; 
(expected)

</div><div>4. Server replied with 
h2 ALPN (unexpected)<br></div><div>5. Browser shows "Server protocol: HTTP/2.0 H2 connection: h2 ." 
<br> 

</div><div><br></div><div>When I browsed source code, I spotted following line:<br></div><div><a href="http://hg.nginx.org/nginx/file/tip/src/http/modules/ngx_http_ssl_module.c#l460" target="_blank">http://hg.nginx.org/nginx/file/tip/src/http/modules/ngx_http_ssl_module.c#l460</a></div><div></div><div></div><div>
<pre><span id="m_3098087802274048526gmail-l459">#if (NGX_HTTP_V2)</span><a href="http://hg.nginx.org/nginx/file/tip/src/http/modules/ngx_http_ssl_module.c#l459" target="_blank"></a>
<span id="m_3098087802274048526gmail-l460">    if (hc->addr_conf->http2) {</span><a href="http://hg.nginx.org/nginx/file/tip/src/http/modules/ngx_http_ssl_module.c#l460" target="_blank"></a>
<span id="m_3098087802274048526gmail-l461">        srv = (unsigned char *) NGX_HTTP_V2_ALPN_PROTO NGX_HTTP_ALPN_PROTOS;</span><a href="http://hg.nginx.org/nginx/file/tip/src/http/modules/ngx_http_ssl_module.c#l461" target="_blank"></a>
<span id="m_3098087802274048526gmail-l462">        srvlen = sizeof(NGX_HTTP_V2_ALPN_PROTO NGX_HTTP_ALPN_PROTOS) - 1;</span><a href="http://hg.nginx.org/nginx/file/tip/src/http/modules/ngx_http_ssl_module.c#l462" target="_blank"></a>
<span id="m_3098087802274048526gmail-l463">    } else</span><a href="http://hg.nginx.org/nginx/file/tip/src/http/modules/ngx_http_ssl_module.c#l463" target="_blank"></a>
<span id="m_3098087802274048526gmail-l464">#endif</span></pre>

</div><div><br></div><div>My assumption (could be wrong) that it means, when http2 is enabled on the address, related to (possibly) many virtual hosts, we always add h2 ALPN.</div><div>Regardless of negotiated SNI.</div><div></div><div>At least I see that <span id="m_3098087802274048526gmail-l2236">ngx_http_find_virtual_server()</span> being called here:<br></div><div><a href="http://hg.nginx.org/nginx/file/tip/src/http/ngx_http_request.c#l2236" target="_blank">http://hg.nginx.org/nginx/file/tip/src/http/ngx_http_request.c#l2236</a></div><div>on already established http(s) connection, not during TLS handshake.<br></div><div><br></div><div>This behaviour caused some pain in my neck today, so could please someone <span><span>be so kind to enlighten</span></span>

 me, is it like it supposed to be, or is it possible to change this in the way, so http1 and http2 virtual hosts could be served on the same IP:port?</div><div>Is it a bug, feature, my misconfiguration or just not needed by anyone?</div><div>Quick Googling did not reveal that anyone had complained about it too much.</div><div><br></div><div>If one will manage to implement a patch, correcting this behaviour, will it be even considered to review?<br></div><div>
<div><br></div><div>--</div><div>Andrey</div>

</div><div><br></div><div>P.S. Under "Browser" here I meant Chrome, Chromium, and Firefox on Windows.</div><div>
But, according to unconfirmed information, "some", yet unidentified, versions of browsers do NOT make a second TCP-connection to another domain after redirection in the provided example.</div><div>And put a second request to the same h2 connection, despite the fact that it was negotiated for different SNI.</div><div>Shame on them.<br></div><br></div>
</div></div>