<html xmlns:v="urn:schemas-microsoft-com:vml" xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:w="urn:schemas-microsoft-com:office:word" xmlns:m="http://schemas.microsoft.com/office/2004/12/omml" xmlns="http://www.w3.org/TR/REC-html40">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=us-ascii">
<meta name="Generator" content="Microsoft Word 14 (filtered medium)">
<style><!--
/* Font Definitions */
@font-face
{font-family:Calibri;
panose-1:2 15 5 2 2 2 4 3 2 4;}
@font-face
{font-family:Tahoma;
panose-1:2 11 6 4 3 5 4 4 2 4;}
/* Style Definitions */
p.MsoNormal, li.MsoNormal, div.MsoNormal
{margin:0cm;
margin-bottom:.0001pt;
font-size:11.0pt;
font-family:"Calibri","sans-serif";}
a:link, span.MsoHyperlink
{mso-style-priority:99;
color:blue;
text-decoration:underline;}
a:visited, span.MsoHyperlinkFollowed
{mso-style-priority:99;
color:purple;
text-decoration:underline;}
p.MsoAcetate, li.MsoAcetate, div.MsoAcetate
{mso-style-priority:99;
mso-style-link:"Balloon Text Char";
margin:0cm;
margin-bottom:.0001pt;
font-size:8.0pt;
font-family:"Tahoma","sans-serif";
mso-fareast-language:EN-US;}
span.EmailStyle17
{mso-style-type:personal-compose;
font-family:"Calibri","sans-serif";
color:windowtext;}
span.BalloonTextChar
{mso-style-name:"Balloon Text Char";
mso-style-priority:99;
mso-style-link:"Balloon Text";
font-family:"Tahoma","sans-serif";}
.MsoChpDefault
{mso-style-type:export-only;
font-family:"Calibri","sans-serif";
mso-fareast-language:EN-US;}
@page WordSection1
{size:612.0pt 792.0pt;
margin:72.0pt 72.0pt 72.0pt 72.0pt;}
div.WordSection1
{page:WordSection1;}
--></style><!--[if gte mso 9]><xml>
<o:shapedefaults v:ext="edit" spidmax="1026" />
</xml><![endif]--><!--[if gte mso 9]><xml>
<o:shapelayout v:ext="edit">
<o:idmap v:ext="edit" data="1" />
</o:shapelayout></xml><![endif]-->
</head>
<body lang="EN-GB" link="blue" vlink="purple">
<div class="WordSection1">
<p class="MsoNormal">Hello!<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">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 handled.<o:p></o:p></p>
<p class="MsoNormal">However, the ‘ssl_protocols’ directive doesn’t work as expected in this scenario.<o:p></o:p></p>
<p class="MsoNormal">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.<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">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 callback.<o:p></o:p></p>
<p class="MsoNormal">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).<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">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 server.<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">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.<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">Nginx development team (e.g. Maxim, Igor), I’d love to hear your thoughts about this.<o:p></o:p></p>
<p class="MsoNormal">Below is an example of this scenario.<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">Best regards,<o:p></o:p></p>
<p class="MsoNormal">Aviram<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">The following is an example configuration:<o:p></o:p></p>
<p class="MsoNormal"><span style="font-family:"Courier New""> server {<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-family:"Courier New""> listen 443 ssl;<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-family:"Courier New""> server_name server1;<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-family:"Courier New""> ssl_protocols TLSv1 TLSv1.1;<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-family:"Courier New""> ...<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-family:"Courier New""> }<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-family:"Courier New""><o:p> </o:p></span></p>
<p class="MsoNormal"><span style="font-family:"Courier New""> server {<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-family:"Courier New""> listen 443 ssl;<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-family:"Courier New""> server_name server2;<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-family:"Courier New""> ssl_protocols TLSv1 TLSv1.1 TLSv1.2;<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-family:"Courier New""> ...<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-family:"Courier New""> }<o:p></o:p></span></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">The following would occur when trying to connect (should succeed as server2 allows for TLSv1.2, but fails):<o:p></o:p></p>
<p class="MsoNormal"><span style="font-family:"Courier New"">$ openssl s_client -connect localhost:443 -servername server2 -tls1_2<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-family:"Courier New"">CONNECTED(00000003)<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-family:"Courier New"">140495355434656:error:1408F10B:SSL routines:SSL3_GET_RECORD:wrong version number:s3_pkt.c:339:<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-family:"Courier New"">---<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-family:"Courier New"">no peer certificate available<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-family:"Courier New"">---<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-family:"Courier New"">No client certificate CA names sent<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-family:"Courier New"">---<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-family:"Courier New"">SSL handshake has read 5 bytes and written 7 bytes<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-family:"Courier New"">---<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-family:"Courier New"">New, (NONE), Cipher is (NONE)<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-family:"Courier New"">Secure Renegotiation IS NOT supported<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-family:"Courier New"">Compression: NONE<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-family:"Courier New"">Expansion: NONE<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-family:"Courier New"">SSL-Session:<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-family:"Courier New""> Protocol : TLSv1.2<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-family:"Courier New""> Cipher : 0000<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-family:"Courier New""> Session-ID: <o:p>
</o:p></span></p>
<p class="MsoNormal"><span style="font-family:"Courier New""> Session-ID-ctx: <o:p>
</o:p></span></p>
<p class="MsoNormal"><span style="font-family:"Courier New""> Master-Key: <o:p>
</o:p></span></p>
<p class="MsoNormal"><span style="font-family:"Courier New""> Key-Arg : None<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-family:"Courier New""> PSK identity: None<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-family:"Courier New""> PSK identity hint: None<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-family:"Courier New""> SRP username: None<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-family:"Courier New""> Start Time: 1430229239<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-family:"Courier New""> Timeout : 7200 (sec)<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-family:"Courier New""> Verify return code: 0 (ok)<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-family:"Courier New"">---<o:p></o:p></span></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">And Nginx would show the error:<o:p></o:p></p>
<p class="MsoNormal"><span style="font-family:"Courier New"">SSL_do_handshake() failed (SSL: error:1409442E:SSL routines:ssl3_read_bytes:tlsv1 alert protocol version:SSL alert number 70) while SSL handshaking<o:p></o:p></span></p>
<p class="MsoNormal"><o:p> </o:p></p>
</div>
</body>
</html>