Different SSL protocols for different server blocks on the same port
mdounin at mdounin.ru
Tue Apr 28 14:24:30 UTC 2015
On Tue, Apr 28, 2015 at 02:00:07PM +0000, Aviram Cohen wrote:
> The Nginx configuration allows you to define different server
> blocks that have different server names but listen on the same
> port in SSL. For an incoming connection, Nginx uses SNI in order
> to know under which server block the connection should be
> However, the 'ssl_protocols' directive doesn't work as expected
> in this scenario.
> Let's say that we have two servers blocks - the first allows
> TLSv1, TLSv1.1 and TLSv1.2, and the second allows only TLSv1
> connections ('ssl_protocols TLSv1;' directive). From what I've
> seen, in this case, the second server will still accept incoming
> TLSv1.1 and TLSv1.2 connections.
> I've debugged it a bit, and wrote some independent code that
> uses OpenSSL, and it seems that OpenSSL doesn't allow you to
> change the supported TLS versions of a connection during the SNI
> The following may occur - an incoming connection to the second
> server starts, and it gets the default SSL CTX object (in Nginx,
> that would be the context of the first server block). When the
> SNI callback (ngx_http_ssl_servername) is called, the context is
> replaced for the connection (with the context of the second
> server block), along with the SSL options of the connections
> (SSL_set_options is called with the new CTX's options). These
> options contain the second server's allowed protocols. Even
> though the correct options are set, when the handshake
> continues, it would succeed even for TLSv1.1 and TLSv1.2 (which
> are enabled for the first server, but not for the second one).
> A similar problem can occur as well; for example, if the first
> server allows only for TLSv1 connections and the second one
> allows for TLSv1.1, then TLSv1.1 connections will be rejected by
> OpenSSL, even if their SNI name is the name of the second
> This seems like an OpenSSL issue (I've reproduced it on both
> v1.0.1 and v1.0.2), but I think that this should at least be
> documented in Nginx's SSL documentation, as the 'ssl_protocols'
> directive doesn't behave as expected for different server blocks
> with the same port - you'd expect that one server block would
> not affect the other, but it does.
> Nginx development team (e.g. Maxim, Igor), I'd love to hear your
> thoughts about this.
> Below is an example of this scenario.
This was discussed a while ago, see here and previous messages:
In short: there are some cases which should work IMHO, but don't
due to OpenSSL behaviour. There are other cases which aren't
expected to work at all, even theorethically.
I don't think that OpenSSL behaviour here is a bug - the SNI
callback can only happen once OpenSSL started processing of a
ClientHello message, and it basically means that it already chosen
a protocol to use. While in theory it can be possible to choose
another protocol - it will seriously complicate things.
I also think that people trying to do such things with SNI
are utterly wrong.
More information about the nginx-devel