7

I'm trying to setup a hostname to demonstrate a poor SSL config and I'm having some issues. I can specify some bad cipher suites, but nginx seems to ignore the protocol selection.

server {
    listen 443 spdy ssl;
    keepalive_timeout 70;
    server_name example.co.uk;
    client_max_body_size 10M;

    ssl_certificate /path/to/ssl.crt;
    ssl_certificate_key /path/to/ssl.key;
    ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
    ...
}

server {
    listen 443 spdy ssl;
    keepalive_timeout 70;
    server_name weak.example.co.uk;
    client_max_body_size 10M;

    ssl_certificate /path/to/weakssl.crt;
    ssl_certificate_key /path/to/weakssl.key;
    ssl_protocols SSLv3;
    ...
}

Nginx can use the different cipher suites I have specified, but seems to use the protocols from the first server block across the board such that weak.example.co.uk has TLSv1/1.1/1.2 and no SSLv3 support.

Is it possible to specify different protocols for each server block?

Reverend Tim
  • 799
  • 7
  • 14
Scott Helme
  • 171
  • 1
  • 4
  • 1
    Have you checked that there isn't any other `ssl_protocols` definitions anywhere in nginx config? – Tero Kilkanen Sep 10 '14 at 22:58
  • Yep, It's possible ro specify different protocols for each server block. I can't replicate your problem. I recently tested your scenario nginx and it's working. As other says, please checks whether there isn't any other `ssl_protocols`. – masegaloeh Sep 10 '14 at 23:20
  • I've checked /etc/nginx/nginx.conf and /etc/sites-available/default.conf, these are the only 2 config files present and match the scenario above. – Scott Helme Sep 11 '14 at 12:44
  • @masegaloeh Interesting, what version of nginx are you using? I'm running nginx 1.7.4 with openssl 1.0.1 on this box. – Scott Helme Sep 11 '14 at 12:46
  • Scott and I worked on this yesterday and I can confirm my NGINX 1.6.1 version does exactly the same. NGINX uses only the protocols from the first block, but the ciphers from the correct block. –  Sep 11 '14 at 12:05
  • I use nginx 1.7.3 with openssl-1.0.1 on Freebsd 8.4 box. Installed using ports – masegaloeh Sep 11 '14 at 13:11
  • @masegaloeh So you can specify different ports for each virtual host and nginx respects that? Can you use the Qualys SSL test to see if it agrees? – Scott Helme Sep 11 '14 at 13:29
  • Umm sorry. Looks like I made a mistakes when interpreting ssllabs result :(. Yes, I can reproduce your case in my box. Nginx uses only the protocols from the first block. – masegaloeh Sep 11 '14 at 13:46
  • @masegaloeh Darn! I was hoping we were onto something there! Thanks for taking the time to check it. – Scott Helme Sep 11 '14 at 13:47
  • I see the same behaviour when trying to define only TLSv1 for the second host too. I thought maybe something to do with SNI but it seems not. – Scott Helme Sep 11 '14 at 14:08
  • This may sound silly but, have you tried defining them in separate virtual host files and then activating each one? – Rohan Durve Sep 30 '14 at 12:09
  • No actually I haven't. I thought all nginx did was concatenate them into one large file anyway. I will try it out tonight, thanks. – Scott Helme Sep 30 '14 at 12:36
  • @RohanDurve-Decode141 doesn't help, I still have the same issue even with separate virtual host files. – Scott Helme Sep 30 '14 at 18:55
  • it seems this is at least patched in 1.6.7, because it worked on a 1.2.x nginx very well, now i updated to 1.6.7 to use ocsp stapling i have to enable all tls versions for all servers. before i had tls1.2 only servers and all tls version servers. – reox Oct 19 '14 at 09:29
  • it's been a while since your discussion here, but I'm using nginx 1.10.2 with openssl 1.0.2j and I'm seeing exactly the same behavior. it only looks at the first `server` block to determine the `ssl_protocols`, and ignores the directive in following blocks. – peedee Jan 22 '17 at 04:10
  • 1
    I added an answer so that people don't have to read through all these comments. – peedee Jan 22 '17 at 04:24

2 Answers2

3

This seems to be a bug in nginx. I just had this now, took me a while to figure it out.

It's always only using the ssl_protocols directive from the first server block. In my case I have many virtual servers running on the same instance, so I used the nginx -T command to display the full combined config to figure out which server block was the "first" since I have split it up into many separate config files.

At time of writing I'm trying this on Ubuntu 14.04.5 with nginx installed from the ondrej/nginx PPA. Specifically I'm running nginx 1.10.2 built with OpenSSL 1.0.2j.

Output of nginx -V

nginx version: nginx/1.10.2
built with OpenSSL 1.0.2j  26 Sep 2016
TLS SNI support enabled
configure arguments: --with-cc-opt='-g -O2 -fstack-protector --param=ssp-buffer-size=4 -Wformat -Werror=format-security -D_FORTIFY_SOURCE=2' --with-ld-opt='-Wl,-Bsymbolic-functions -Wl,-z,relro -Wl,-z,now' --prefix=/usr/share/nginx --conf-path=/etc/nginx/nginx.conf --http-log-path=/var/log/nginx/access.log --error-log-path=/var/log/nginx/error.log --lock-path=/var/lock/nginx.lock --pid-path=/run/nginx.pid --modules-path=/usr/lib/nginx/modules --http-client-body-temp-path=/var/lib/nginx/body --http-fastcgi-temp-path=/var/lib/nginx/fastcgi --http-proxy-temp-path=/var/lib/nginx/proxy --http-scgi-temp-path=/var/lib/nginx/scgi --http-uwsgi-temp-path=/var/lib/nginx/uwsgi --with-debug --with-pcre-jit --with-ipv6 --with-http_ssl_module --with-http_stub_status_module --with-http_realip_module --with-http_auth_request_module --with-http_v2_module --with-http_spdy_module --with-http_dav_module --with-http_slice_module --with-threads --with-http_addition_module --with-http_geoip_module=dynamic --with-http_gunzip_module --with-http_gzip_static_module --with-http_image_filter_module=dynamic --with-http_sub_module --with-http_xslt_module=dynamic --with-stream=dynamic --with-stream_ssl_module --with-mail=dynamic --with-mail_ssl_module --add-dynamic-module=/build/nginx-8xB1_y/nginx-1.10.2/debian/modules/nginx-auth-pam --add-dynamic-module=/build/nginx-8xB1_y/nginx-1.10.2/debian/modules/nginx-dav-ext-module --add-dynamic-module=/build/nginx-8xB1_y/nginx-1.10.2/debian/modules/nginx-echo --add-dynamic-module=/build/nginx-8xB1_y/nginx-1.10.2/debian/modules/nginx-upstream-fair --add-dynamic-module=/build/nginx-8xB1_y/nginx-1.10.2/debian/modules/ngx_http_substitutions_filter_module
peedee
  • 381
  • 4
  • 12
1
  1. Check your configuration is statically validated with nginx -t
  2. Check your configuration is dynamically validated by monitoring an error log defined at main level while issuing a reload (either service nginx reload or kill -SIGHUP <nginx master PID>)
  3. Create a test location in each server (see below)
  4. Ensure your nginx is built with the SNI extension (normally yes if yo uuse a pre-built package)
  5. Ensure the right server is being used: if the domain name selection through SNI fails or if SNI is not available, nginx will fall back to the default server to serve content. Default server is, unless explicitely specified otherwise, the first found in the configuration file.
  6. Ensure browser cache is cleaned-up (and that any cache whatsoever in-between server and browser gets updated/is purged)

If a wrong certificate was to be presented (no SNI or wrong server selection), you would normally get a certificate warning since there would be a mismatch between the requested domain name and the one set for the certificate.

This will display the protocol being used by the current connection:

location /SSLProtocol {
    return 200 $ssl_protocol;
}
Bernard Rosset
  • 1,323
  • 12
  • 24