Opened 10 years ago

Closed 10 years ago

Last modified 10 years ago

#719 closed enhancement (wontfix)

Nginx should maintain a better default cipher suite

Reported by: Alex Gaynor Owned by:
Priority: minor Milestone:
Component: nginx-core Version: 1.7.x
Keywords: Cc:
uname -a:
nginx -V: n/a

Description

Nginx's current default is: "HIGH:!aNULL:!MD5"

The problem with this is that the way OpenSSL defines "HIGH" gives a list of cipher suites in a poor order, resulting in suboptimal cipher suites for many common browsers.

The result of this is that many individual pass around their own versions of the ssl_ciphers directive. As things change, these have the potential to go out of date

I propose giving nginx a slightly more explicit cipher suite list for nginx:

ECDH+AESGCM:DH+AESGCM:ECDH+AES256:DH+AES256:ECDH+AES128:DH+AES:ECDH+3DES:DH+3DES:RSA+AESGCM:RSA+AES:RSA+3DES:!aNULL:!MD5:!DSS

The string is from https://hynek.me/articles/hardening-your-web-servers-ssl-ciphers/, which describes the full methodology, but in general:

  • ECDH is prefered
  • AESGCM suites are prefered
  • 3DES is used as a fallback for really old browsers

A simple patch to implement this is attached

Change History (7)

comment:1 by Alex Gaynor, 10 years ago

I'm having difficulty uploading a file, patch included inline:

diff -r f3f25ad09dee src/http/modules/ngx_http_ssl_module.c
--- a/src/http/modules/ngx_http_ssl_module.c	Wed Feb 11 20:18:55 2015 +0300
+++ b/src/http/modules/ngx_http_ssl_module.c	Sat Feb 14 13:57:00 2015 -0500
@@ -14,7 +14,7 @@
     ngx_pool_t *pool, ngx_str_t *s);
 
 
-#define NGX_DEFAULT_CIPHERS     "HIGH:!aNULL:!MD5"
+#define NGX_DEFAULT_CIPHERS     "ECDH+AESGCM:DH+AESGCM:ECDH+AES256:DH+AES256:ECDH+AES128:DH+AES:ECDH+3DES:DH+3DES:RSA+AESGCM:RSA+AES:RSA+3DES:!aNULL:!MD5:!DSS"
 #define NGX_DEFAULT_ECDH_CURVE  "prime256v1"
 
 #define NGX_HTTP_NPN_ADVERTISE  "\x08http/1.1"

in reply to:  description comment:2 by Sergey Budnevitch, 10 years ago

Replying to Alex Gaynor:

but in general:

  • ECDH is prefered
  • AESGCM suites are prefered
  • 3DES is used as a fallback for really old browsers

This is description of HIGH:!aNULL:!MD5, just run openssl ciphers -v 'HIGH:!aNULL:!MD5' and check the order. You actually suggest:

  • GCM suites are prefered
  • ECDH is prefered

i.e. to place GCM algorithms first and then place ECDHE before DHE and this is the only significant difference. On the other hand I do not know any client that knows Galois/Counter Mode and does not know ECDHE. And current default is shorter.

comment:3 by Sergey Budnevitch, 10 years ago

Resolution: wontfix
Status: newclosed

comment:4 by Alex Gaynor, 10 years ago

A major difference between my ordering and OpenSSL's is that OpenSSL will prioritize AES256-CBC above AES128-GCM, which is not correct (IMO), both AES-128 and AES-256 are strong enough that the difference is unimportant, while GCM mode is strongly prefered over CBC.

comment:5 by Sergey Budnevitch, 10 years ago

This is the case if ssl_prefer_server_ciphers is on on nginx side and client supports AES256-CBC and AES128-GCM cipher suits, but does not support AES256-GCM. The later is possible only if other side wants to shot himself in the foot, in practical situations if client supports GCM, it supports both AES128-GCM and AES256-GCM.

BTW your suggestion has the same "problem", it places ECDH (non-ephemeral, without forward secrecy) above DHE (with forward secrecy), but in practice if client knows ECDH, it also knows ECDHE and the later has priority.

comment:6 by Alex Gaynor, 10 years ago

That's not true, Chrome supports AES128-GCM but *not* AES256-GCM. This issue describes it a bit: https://code.google.com/p/chromium/issues/detail?id=442572

comment:7 by Maxim Dounin, 10 years ago

Just to clarify the position in general: we are not going to prioritize ciphers based on which one is considered better at this particular moment. Instead, we enable chiphers that are considered good enough, and let clients to select whatever they prefer. If one wants to force his own cipher preference - either based on cipher strength, or effective key length according to currently known attacks, or forward secrecy, or speed on a particular hardware, or whatever - he may do so using the ssl_prefer_server_ciphers and ssl_ciphers directives.

Note: See TracTickets for help on using tickets.