Welcome! Log In Create A New Profile

Advanced

Fwd: Q: http2 and http1 virtual hosts both works via HTTP/2 - bug of feature?

Andrey Kulikov
May 25, 2023 03:26PM
Hello,

Observed nginx's version 1.22.1 questionable behaviour with two virtual
hosts, one with H2 - enabled, second without http2 support.
Both on the same IP and port, with different domain names/server names.
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.

Sample config snippet:

http {
....
server {
listen 1985 http2 ssl;
server_name 'mavr.cp.eu';

ssl_certificate domain.cer;
ssl_certificate_key domain.key;

location / {
return 302 https://zavr.cp.eu:1985$request_uri;
}
}

server {
listen 1985 ssl; # NO h2!
server_name 'zavr.cp.eu';

ssl_certificate domain.cer;
ssl_certificate_key domain.key;

location / {
# Doesn't really matter what's here, for simplicity I've used
ngx_lua_module.
echo "Server protocol: $server_protocol H2 connection: $http2
..";
}
}
....
}

When I type https://mavr.cp.eu:1985 in browser I see:

1. Browser negotiates h2 ALPN with the server with SNI mavr.cp.eu ;
2. Server replied with 302 redirect to https://zavr.cp.eu:1985 (expected)
3. Browser makes NEW TCP-connection with the server with SNI zavr.cp.eu;
(expected)
4. Server replied with h2 ALPN (unexpected)
5. Browser shows "Server protocol: HTTP/2.0 H2 connection: h2 ."

When I browsed source code, I spotted following line:
http://hg.nginx.org/nginx/file/tip/src/http/modules/ngx_http_ssl_module.c#l460

#if (NGX_HTTP_V2)
<http://hg.nginx.org/nginx/file/tip/src/http/modules/ngx_http_ssl_module.c#l459>
if (hc->addr_conf->http2) {
<http://hg.nginx.org/nginx/file/tip/src/http/modules/ngx_http_ssl_module.c#l460>
srv = (unsigned char *) NGX_HTTP_V2_ALPN_PROTO
NGX_HTTP_ALPN_PROTOS;
<http://hg.nginx.org/nginx/file/tip/src/http/modules/ngx_http_ssl_module.c#l461>
srvlen = sizeof(NGX_HTTP_V2_ALPN_PROTO NGX_HTTP_ALPN_PROTOS) -
1; <http://hg.nginx.org/nginx/file/tip/src/http/modules/ngx_http_ssl_module.c#l462>
} else <http://hg.nginx.org/nginx/file/tip/src/http/modules/ngx_http_ssl_module.c#l463>#endif


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.
Regardless of negotiated SNI.
At least I see that ngx_http_find_virtual_server() being called here:
http://hg.nginx.org/nginx/file/tip/src/http/ngx_http_request.c#l2236
on already established http(s) connection, not during TLS handshake.

This behaviour caused some pain in my neck today, so could please someone be
so kind to enlighten 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?
Is it a bug, feature, my misconfiguration or just not needed by anyone?
Quick Googling did not reveal that anyone had complained about it too much.

If one will manage to implement a patch, correcting this behaviour, will it
be even considered to review?

--
Andrey

P.S. Under "Browser" here I meant Chrome, Chromium, and Firefox on Windows.
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.
And put a second request to the same h2 connection, despite the fact that
it was negotiated for different SNI.
Shame on them.
_______________________________________________
nginx mailing list
nginx@nginx.org
https://mailman.nginx.org/mailman/listinfo/nginx
Subject Author Posted

Fwd: Q: http2 and http1 virtual hosts both works via HTTP/2 - bug of feature?

Andrey Kulikov May 25, 2023 03:26PM

RE: Q: http2 and http1 virtual hosts both works via HTTP/2 - bug of feature?

Reinis Rozitis May 26, 2023 07:06AM



Sorry, only registered users may post in this forum.

Click here to login

Online Users

Guests: 87
Record Number of Users: 8 on April 13, 2023
Record Number of Guests: 421 on December 02, 2018
Powered by nginx      Powered by FreeBSD      PHP Powered      Powered by MariaDB      ipv6 ready