30

I have a NGINX acting as a reverse proxy for our sites and is working very well. For the sites that need ssl I followed raymii.org to make sure to have as strong of a SSLLabs score as possible. One of the sites needs to be PCI DSS compliant but based on the latest TrustWave scan is now failing because of TLS 1.0 being enabled.

On the http level in nginx.conf I have:

ssl_protocols TLSv1 TLSv1.1 TLSv1.2;

For the specific server I have:

ssl_protocols TLSv1.1 TLSv1.2;

I have changed ciphers, moved things out of the http level and to each ssl site server but no matter what when I run:

openssl s_client -connect www.example.com:443 -tls1

I get a valid connection for TLS 1.0. SSLLabs puts the nginx setup for the site as an A but with TLS 1.0 so I believe the rest of my setup is correct it just will not turn off TLS 1.0.

Thoughts on what I could be missing?

openssl version -a
OpenSSL 1.0.1f 6 Jan 2014
built on: Thu Jun 11 15:28:12 UTC 2015
platform: debian-amd64

nginx -v
nginx version: nginx/1.8.0
1
  • 1
    Note that it isn't mandatory to remove TLS 1.0 until June 30, 2016. Jul 8, 2015 at 15:48

3 Answers 3

15

The problem here is that the Server name indication part of TLS negotiation is done after the connection itself has been negotiated. And the protocol is negotiated during connection negotiation.

It might be possible to enforce no TLS v1.0 for that virtual host if you configure that virtual host to an IP address on the server that has no other virtual hosts associated with it. Therefore nginx would know based on the IP address that no TLS v 1.0 is allowed.

4
  • Thanks. I am assuming no way around this as we don't have a spare IP at the moment to test that.
    – Shawn C.
    Jul 8, 2015 at 16:50
  • 2
    Server Name Indication is part of the TLS ClientHello. It is in the first message sent by the client, and not negotiated later. It sounds more like Nginx has a design flaw. it sounds like it accepts the connection, and then forwards to the Virtual Host whether its right or wrong. Instead, nginx should parse the server name, consult the Virtual Host, and then reject the connection if it fails to meet the Virtual Host's requirements. The design flaw is probably CVE worthy since TLS 1.0 is questionable at times. Its clearly a C&A violation in some circumstances.
    – user145545
    Nov 2, 2016 at 2:05
  • Thanks for the comment. This is interesting if it really is a real design flaw. Nov 2, 2016 at 5:28
  • 1
    Is this unchanged in 2019 with newer nginx versions?
    – robsch
    Feb 18, 2019 at 11:07
22

Go find a server block you want to use as your "default" ssl negotiation template. Find your listen line

server {
    ...
    listen 443 ssl;
    ssl_protocols TLSv1.1 TLSv1.2;
    ...
}

and add default_server to the end of the line

server {
    ...
    listen 443 ssl default_server;
    ssl_protocols TLSv1.1 TLSv1.2;
    ...
}

This allows nginx to have a configuration when it's negotiating which TLS version to use. The downside is that you can only have one default server per port. So having some virtual domains with TLSv1 enabled and others with it disabled is a no go.

1
  • Does that mean that there is only a single place where ssl_protocolls has an effect? Within the server configuration that has the default_server declaration? When this configuration is used during negotiation, the ssl_protocolls setting within another configuration does not have an effect?
    – robsch
    Feb 18, 2019 at 11:02
6

I disabled TLSv1 on nginx version 1.8.1. You need to update openssl to 1.0.1g or 1.0.1h versions. Then simply remove 'TLSv1' from ssl_protocols directive:

ssl_protocols TLSv1.1 TLSv1.2

Then check the connection via TLSv1 by command:

openssl s_client -tls1 -connect example.com:443 < /dev/null

You should get something like that:

CONNECTED(00000003)
write:errno=104
---
no peer certificate available
---
No client certificate CA names sent
---
SSL handshake has read 0 bytes and written 0 bytes
---
New, (NONE), Cipher is (NONE)
Secure Renegotiation IS NOT supported
Compression: NONE
Expansion: NONE
No ALPN negotiated
SSL-Session:
    Protocol  : TLSv1
    Cipher    : 0000
    Session-ID: 
    Session-ID-ctx: 
    Master-Key: 
    Key-Arg   : None
    Krb5 Principal: None
    PSK identity: None
    PSK identity hint: None
    Start Time: 1474531027
    Timeout   : 7200 (sec)
    Verify return code: 0 (ok)
---
1
  • 1
    Folks usually cannot replace the version of OpenSSL when they are in a hosted environment. The server operator controls the server's configuration; not the website operator who is renting the virtual server.
    – user145545
    Nov 2, 2016 at 2:18

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .