Security is a always a balancing act between safety and practicality. If we’re talking about the internet, you can go all the way from something impenetrable and completely useless to something easy to use and also part of a botnet. In the case of the Nextcloud snap’s SSL cipher suite, as with any website, it’s a balance of supporting only the best ciphers while also ensuring that older clients aren’t left out in the cold.

The current cipher suite was selected several years ago, back when most folks were using Windows 7. We of course scan it periodically with SSL Labs and testssl.sh, and nightly with Nessus. We tweak it periodically to ensure it reflects the current security landscape and gets good results from those tools, but it hasn’t really changed that much.

As I mentioned earlier, one can always make the cipher suite more secure, but the side effect is that older clients who don’t support newer/better ciphers will no longer be able to communicate with the server. This is what our config currently looks like:

SSLProtocol all -SSLv3
SSLHonorCipherOrder On
SSLCipherSuite ECDH+AESGCM:DH+AESGCM:ECDH+AES256:DH+AES256:ECDH+AES128:DH+AES:RSA+AESGCM:RSA+AES:!aNULL:!MD5:!DSS;

This supports a lot of clients. Here’s the client simulation from testssl.sh:

Android 2.3.7               No connection
Android 4.1.1               TLSv1.0 ECDHE-RSA-AES256-SHA, 256 bit ECDH (P-256)
Android 4.3                 TLSv1.0 ECDHE-RSA-AES256-SHA, 256 bit ECDH (P-256)
Android 4.4.2               TLSv1.2 ECDHE-RSA-AES256-GCM-SHA384, 256 bit ECDH (P-256)
Android 5.0.0               TLSv1.2 ECDHE-RSA-AES128-GCM-SHA256, 256 bit ECDH (P-256)
Android 6.0                 TLSv1.2 ECDHE-RSA-AES128-GCM-SHA256, 256 bit ECDH (P-256)
Android 7.0                 TLSv1.2 ECDHE-RSA-AES256-GCM-SHA384, 256 bit ECDH (P-256)
Chrome 51 Win 7             TLSv1.2 ECDHE-RSA-AES256-GCM-SHA384, 256 bit ECDH (P-256)
Chrome 57 Win 7             TLSv1.2 ECDHE-RSA-AES256-GCM-SHA384, 256 bit ECDH (P-256)
Firefox 49 Win 7            TLSv1.2 ECDHE-RSA-AES256-GCM-SHA384, 256 bit ECDH (P-256)
Firefox 53 Win 7            TLSv1.2 ECDHE-RSA-AES256-GCM-SHA384, 256 bit ECDH (P-256)
IE 6 XP                     No connection
IE 7 Vista                  TLSv1.0 ECDHE-RSA-AES256-SHA, 256 bit ECDH (P-256)
IE 8 XP                     No connection
IE 8 Win 7                  TLSv1.0 ECDHE-RSA-AES256-SHA, 256 bit ECDH (P-256)
IE 11 Win 7                 TLSv1.2 DHE-RSA-AES256-GCM-SHA384, 4096 bit DH
IE 11 Win 8.1               TLSv1.2 DHE-RSA-AES256-GCM-SHA384, 4096 bit DH
IE 11 Win Phone 8.1 Update  TLSv1.2 DHE-RSA-AES256-GCM-SHA384, 4096 bit DH
IE 11 Win 10                TLSv1.2 ECDHE-RSA-AES256-GCM-SHA384, 256 bit ECDH (P-256)
Edge 13 Win 10              TLSv1.2 ECDHE-RSA-AES256-GCM-SHA384, 256 bit ECDH (P-256)
Edge 13 Win Phone 10        TLSv1.2 ECDHE-RSA-AES256-GCM-SHA384, 256 bit ECDH (P-256)
Opera 17 Win 7              TLSv1.2 ECDHE-RSA-AES256-SHA, 256 bit ECDH (P-256)
Safari 5.1.9 OS X 10.6.8    TLSv1.0 ECDHE-RSA-AES256-SHA, 256 bit ECDH (P-256)
Safari 7 iOS 7.1            TLSv1.2 ECDHE-RSA-AES256-SHA384, 256 bit ECDH (P-256)
Safari 9 OS X 10.11         TLSv1.2 ECDHE-RSA-AES256-GCM-SHA384, 256 bit ECDH (P-256)
Safari 10 OS X 10.12        TLSv1.2 ECDHE-RSA-AES256-GCM-SHA384, 256 bit ECDH (P-256)
Apple ATS 9 iOS 9           TLSv1.2 ECDHE-RSA-AES256-GCM-SHA384, 256 bit ECDH (P-256)
Tor 17.0.9 Win 7            TLSv1.0 ECDHE-RSA-AES256-SHA, 256 bit ECDH (P-256)
Java 6u45                   No connection
Java 7u25                   TLSv1.0 ECDHE-RSA-AES128-SHA, 256 bit ECDH (P-256)
Java 8u31                   TLSv1.2 ECDHE-RSA-AES128-GCM-SHA256, 256 bit ECDH (P-256)
OpenSSL 1.0.1l              TLSv1.2 ECDHE-RSA-AES256-GCM-SHA384, 256 bit ECDH (P-256)
OpenSSL 1.0.2e              TLSv1.2 ECDHE-RSA-AES256-GCM-SHA384, 256 bit ECDH (P-256)

Here’s the same from SSL Labs:

ssl labs result before update

That’s pretty darn good. Windows XP isn’t all that well supported, but heck, Vista is, and 7 and on definitely are. All these clients, and we still were able to get an A+ from SSL Labs.

Nowadays, though, some of these older clients just aren’t as important anymore. XP barely registers, Vista even less, and everyone gets a new phone every year or two (which is silly, by the way). The change in client landscape means it’s time to rebalance our cipher list against the clients we care to support. How do we go about determining that?

I won’t pretend I’m a security expert. I don’t at any one time know which ciphers are best and which are less best, which is why I rely on other folks and tools who do. So I decided to start with the strongest cipher list I could find and see what clients it eliminated. In order to find that list, I went to the Mozilla SSL config generator and turned everything up to 11 (i.e. checked the “modern” radio). It gave me this config:

SSLProtocol all -SSLv3 -TLSv1 -TLSv1.1
SSLHonorCipherOrder on
SSLCipherSuite ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256

It actually supported a pretty good number of clients, but testssl.sh whined about it in the same way it whined about the current config:

LUCKY13 (CVE-2013-0169), experimental    potentially VULNERABLE, uses cipher block chaining (CBC) ciphers with TLS

Okay, so this ISN’T the ultimate locked down config. I scrolled down to testssl.sh’s cipher suite list to determine which ones were problematic:

Hexcode Cipher Suite Name (OpenSSL)      KeyExch.  Encryption Bits    Cipher Suite Name (RFC)
-----------------------------------------------------------------------------------------------------------------------------
 # ...
 xc028  ECDHE-RSA-AES256-SHA384          ECDH 256  AES        256     TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384
 # ...
 xc027  ECDHE-RSA-AES128-SHA256          ECDH 256  AES        128     TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256

I removed the those ciphers from the list, and the config turned into:

SSLProtocol all -SSLv3 -TLSv1 -TLSv1.1
SSLHonorCipherOrder on
SSLCipherSuite ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-ECDSA-AES128-SHA256

And indeed, this got a clean bill of health from testssl.sh, but the number of clients it eliminated was… a lot:

Android 2.3.7               No connection
Android 4.1.1               No connection
Android 4.3                 No connection
Android 4.4.2               TLSv1.2 ECDHE-RSA-AES256-GCM-SHA384, 256 bit ECDH (P-256)
Android 5.0.0               TLSv1.2 ECDHE-RSA-AES128-GCM-SHA256, 256 bit ECDH (P-256)
Android 6.0                 TLSv1.2 ECDHE-RSA-AES128-GCM-SHA256, 256 bit ECDH (P-256)
Android 7.0                 TLSv1.2 ECDHE-RSA-AES256-GCM-SHA384, 256 bit ECDH (P-256)
Chrome 51 Win 7             TLSv1.2 ECDHE-RSA-AES256-GCM-SHA384, 256 bit ECDH (P-256)
Chrome 57 Win 7             TLSv1.2 ECDHE-RSA-AES256-GCM-SHA384, 256 bit ECDH (P-256)
Firefox 49 Win 7            TLSv1.2 ECDHE-RSA-AES256-GCM-SHA384, 256 bit ECDH (P-256)
Firefox 53 Win 7            TLSv1.2 ECDHE-RSA-AES256-GCM-SHA384, 256 bit ECDH (P-256)
IE 6 XP                     No connection
IE 7 Vista                  No connection
IE 8 XP                     No connection
IE 8 Win 7                  No connection
IE 11 Win 7                 No connection
IE 11 Win 8.1               No connection
IE 11 Win Phone 8.1 Update  No connection
IE 11 Win 10                TLSv1.2 ECDHE-RSA-AES256-GCM-SHA384, 256 bit ECDH (P-256)
Edge 13 Win 10              TLSv1.2 ECDHE-RSA-AES256-GCM-SHA384, 256 bit ECDH (P-256)
Edge 13 Win Phone 10        TLSv1.2 ECDHE-RSA-AES256-GCM-SHA384, 256 bit ECDH (P-256)
Opera 17 Win 7              No connection
Safari 5.1.9 OS X 10.6.8    No connection
Safari 7 iOS 7.1            No connection
Safari 9 OS X 10.11         TLSv1.2 ECDHE-RSA-AES256-GCM-SHA384, 256 bit ECDH (P-256)
Safari 10 OS X 10.12        TLSv1.2 ECDHE-RSA-AES256-GCM-SHA384, 256 bit ECDH (P-256)
Apple ATS 9 iOS 9           TLSv1.2 ECDHE-RSA-AES256-GCM-SHA384, 256 bit ECDH (P-256)
Tor 17.0.9 Win 7            No connection
Java 6u45                   No connection
Java 7u25                   No connection
Java 8u31                   TLSv1.2 ECDHE-RSA-AES128-GCM-SHA256, 256 bit ECDH (P-256)
OpenSSL 1.0.1l              TLSv1.2 ECDHE-RSA-AES256-GCM-SHA384, 256 bit ECDH (P-256)
OpenSSL 1.0.2e              TLSv1.2 ECDHE-RSA-AES256-GCM-SHA384, 256 bit ECDH (P-256)

So, it seems I found the most locked-down config, and it was time to walk it back until I was comfortable. I definitely want to still support Internet Explorer on Windows 7 and 8, so I glanced back at the results from the current config and added DHE-RSA-AES256-GCM-SHA384 back to the list of supported ciphers. Still strong, still providing forward secrecy:

SSLProtocol all -SSLv3 -TLSv1 -TLSv1.1
SSLHonorCipherOrder on
SSLCipherSuite ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-ECDSA-AES128-SHA256:DHE-RSA-AES256-GCM-SHA384

And it gave me the following results:

Android 2.3.7               No connection
Android 4.1.1               No connection
Android 4.3                 No connection
Android 4.4.2               TLSv1.2 ECDHE-RSA-AES256-GCM-SHA384, 256 bit ECDH (P-256)
Android 5.0.0               TLSv1.2 ECDHE-RSA-AES128-GCM-SHA256, 256 bit ECDH (P-256)
Android 6.0                 TLSv1.2 ECDHE-RSA-AES128-GCM-SHA256, 256 bit ECDH (P-256)
Android 7.0                 TLSv1.2 ECDHE-RSA-AES256-GCM-SHA384, 256 bit ECDH (P-256)
Chrome 51 Win 7             TLSv1.2 ECDHE-RSA-AES256-GCM-SHA384, 256 bit ECDH (P-256)
Chrome 57 Win 7             TLSv1.2 ECDHE-RSA-AES256-GCM-SHA384, 256 bit ECDH (P-256)
Firefox 49 Win 7            TLSv1.2 ECDHE-RSA-AES256-GCM-SHA384, 256 bit ECDH (P-256)
Firefox 53 Win 7            TLSv1.2 ECDHE-RSA-AES256-GCM-SHA384, 256 bit ECDH (P-256)
IE 6 XP                     No connection
IE 7 Vista                  No connection
IE 8 XP                     No connection
IE 8 Win 7                  No connection
IE 11 Win 7                 TLSv1.2 DHE-RSA-AES256-GCM-SHA384, 4096 bit DH
IE 11 Win 8.1               TLSv1.2 DHE-RSA-AES256-GCM-SHA384, 4096 bit DH
IE 11 Win Phone 8.1 Update  TLSv1.2 DHE-RSA-AES256-GCM-SHA384, 4096 bit DH
IE 11 Win 10                TLSv1.2 ECDHE-RSA-AES256-GCM-SHA384, 256 bit ECDH (P-256)
Edge 13 Win 10              TLSv1.2 ECDHE-RSA-AES256-GCM-SHA384, 256 bit ECDH (P-256)
Edge 13 Win Phone 10        TLSv1.2 ECDHE-RSA-AES256-GCM-SHA384, 256 bit ECDH (P-256)
Opera 17 Win 7              No connection
Safari 5.1.9 OS X 10.6.8    No connection
Safari 7 iOS 7.1            No connection
Safari 9 OS X 10.11         TLSv1.2 ECDHE-RSA-AES256-GCM-SHA384, 256 bit ECDH (P-256)
Safari 10 OS X 10.12        TLSv1.2 ECDHE-RSA-AES256-GCM-SHA384, 256 bit ECDH (P-256)
Apple ATS 9 iOS 9           TLSv1.2 ECDHE-RSA-AES256-GCM-SHA384, 256 bit ECDH (P-256)
Tor 17.0.9 Win 7            No connection
Java 6u45                   No connection
Java 7u25                   No connectionJava 8u31
Java 8u31                   TLSv1.2 ECDHE-RSA-AES128-GCM-SHA256, 256 bit ECDH (P-256)
OpenSSL 1.0.1l              TLSv1.2 ECDHE-RSA-AES256-GCM-SHA384, 256 bit ECDH (P-256)
OpenSSL 1.0.2e              TLSv1.2 ECDHE-RSA-AES256-GCM-SHA384, 256 bit ECDH (P-256)

And from SSL Labs:

ssl labs result after update

That gives me client coverage I’m willing to accept given various usage statistics.