Possible bug http2 module

Jim Ohlstein jim at ohlste.in
Sat Feb 6 19:51:30 UTC 2016

On 2/6/16 1:00 PM, Валентин Бартенев wrote:


So if I write:
>> listen 443 ssl http2;
>> in a server directive anywhere as dosumneted in
>> http://nginx.org/en/docs/http/ngx_http_v2_module.html#example, then
>> http2 is enabled in all servers on all IP's even if it's not
>> specifically enabled in a listen directive in a particular server? That
>> seems wrong, intuitively. There are (more and more) times when shared
>> IPv4's are necessary, and dictating this behavior for all servers on a
>> given IPv4 is probably less than optimal. If it's technically a
>> necessity it could perhaps be more explicitly documented.
> It's pretty much the same as "ssl" parameter works.

I thought of that but there's a fundamental difference from the point of 
view of the server admin. If I enable SSL on one or more vhosts sharing 
an IP address and choose not to use SSL in another vhost sharing that 
same IP, I simply do not write an ssl server configuration for that 
vhost. There's no certificate for it so pretty much any client will 
throw an error if a request is made for that vhost on 443. The user then 
can use http instead of https or s/he can choose to use an incorrect 
certificate. Most choose the former. With the advent of free certificate 
services like Letsencrypt, StartSSL and Wotan, I, like many server 
admins, am shifting more and more to https (and http2). But as we've 
seen, there are times when http2 cannot be used (or is undesirable) but 
we still prefer SSL, or we've long ago enabled HSTS and pretty much can 
no longer back out, at least not without significant disruption.

In my use case, the server in question is a FreeBSD KVM in a large Linux 
machine that hosts many other KVM's and LXC's. Each of my customers 
needs at least one IPv4 and most want more than one. The host will only 
provide me with a finite number of IPv4 addresses per physical server. 
If IPv6 were ubiquitous I would not have a problem as I have a /64 on 
each machine. I try to limit my own use of IPv4's so as to have them 
available. With SNI that really isn't a problem. I no longer worry 
whether my sites support ancient clients, so I host many SSL domains on 
the same IP. If I want to use http2 on all but one, and I _cannot_ use 
http2 on that one, then I cannot use http2 on any, as I have come to 
find out.

> Ones connected an HTTP/2 client is able to request any host over the HTTP/2
> connection, and in fact browsers do.  So there's no proper way to disable
> HTTP/2 for one virtual server while keeping enable for others.

The most elegant solution (if it's possible - my programming skills 
start and end with shell scripts) would be a programmatic one where a 
directive is optionally turned on in the http context of the nginx 
configuation file. Something like:

check_http2 (on|off);

with a default of "off". Such a directive could check for explicit http2 
enabling in a vhost where SSL is also enabled, and downgrade connections 
to those where it is not enabled. Of course this would probably violate 
half a dozen RFC's, but it would be helpful in the use case I just 
described, which is in fact a real world situation. A server admin who 
does not want to spend the CPU cycles on such a check simply does not 
enable it, but one who needs it can use it.

> Could you suggest a good phrase to improve the docs?

Something like the following in the http2 and core module documentation:

NOTE: Enabling http2 globally (via "listen 443 ssl http2;" in ANY server 
block), or on any single IP (via "listen ssl http2;"), 
enables http2 on ALL vhosts using SSL, either globally or on that 
specific IP. If this is not the desired behavior use one IP for vhosts 
using http2 and a different IP for vhosts using SSL but for which you do 
not want to enable http2. Enable http2 only for the IP's where it is 

Jim Ohlstein

"Never argue with a fool, onlookers may not be able to tell the 
difference." - Mark Twain

More information about the nginx mailing list