Tune Cipher Suites and Support Forward Secrecy on OS X Server
As of version 5, the Server app still only supports TLS version 1.0 and a handful of suitable ciphers, but even within those constraints, we can improve the situation significantly by shutting off RC4 support and setting a preferred cipher order.
(Update, 25 March 2016: This article includes everything necessary for tuning cipher suites, but also see “Server 5.1 Brings TLS 1.2 at Last” for more on important changes in Server 5.1.)
Partly due to Apple’s deprecation of OpenSSL back in the days of OS X Lion, partly due to its slow pace of introducing its own replacement (Secure Transport) into the Server app’s web service, and partly due to the much quicker pace of just about everyone else in rolling out support for newer TLS technologies, those of us running HTTPS sites with Server start at an instant disadvantage. The situation is so bad that Apple’s own bots won’t even crawl a site provided over HTTPS with Apple’s own Server — because both AppleBot and AppleNewsBot require TLS 1.2! It’s more than a little ironic that Apple has been so quick to embrace more modern technologies in iOS and OS X while leaving the poor Server app to languish with TLS 1.0 and just a handful of suitable ciphers.
Apple’s move to a proxied architecture in version 5 of the Server app may be a first step toward a complete overhaul of the TLS side of how the server interacts with site visitors. I’m hopeful we’ll soon see Apple bring that portion of the server right into the modern age and with it, a whole slew of alphabet soup including both TLS 1.2 and HTTP/2. (It has now fallen so far behind that I’m fairly convinced either this type of radical overhaul is in the pipeline, or we’ll see the web service disappear completely in the next major version of Server.)
But until big changes arrive, we can at least make the best of what is available by tuning the cipher suite for performance, security, and Forward Secrecy, as well as by enabling OCSP stapling, as I described in “Set Up OCSP Stapling on OS X Server”. By default, the Server app doesn’t specify any preferred cipher order — which means that slower or older ones may wind up being used first — and Apple also allows deprecated RC4
ciphers in the list:
SSLCipherSuite "ALL:!aNULL:!ADH:!eNULL:!LOW:!EXP:RC4+RSA:+HIGH:+MEDIUM"
That line comes from the proxy’s custom sites configuration file and indirectly from the .plist
used to build it, as I described in the earlier article “Adjust the Apache Proxy in Server 5 for Higher Performance”:
/Library/Server/Web/Config/Proxy/apache_serviceproxy_customsites.conf /Library/Server/Web/Config/Proxy/servermgr_serviceproxy_customsites.plist
What we can to do is disable RC4
ciphers and also prioritise those ciphers which offer Forward Secrecy and speedier processing times. Although you can easily verify the speed of individual ciphers on your own server from the command line, and that is no doubt the way to go if you want to be very precise about it, in my experience there is only a little performance difference between the main ones we’ll want to support anyway. The easiest route is just to grab the suggested cipher suite — I’d opt for the intermediate compatibility version — straight from the Mozilla OpSec team and use that. Almost all of what is included in that cipher suite is unusable on Server 5 at this point, but it makes no difference, since unavailable ciphers will just be ignored. To specify the cipher suite and tell the server to state its own preferences for connections, we’ll need to replace the SSLCipherSuite
line from above with the following:
SSLCipherSuite "ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:ECDHE-RSA-DES-CBC3-SHA:ECDHE-ECDSA-DES-CBC3-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:AES:CAMELLIA:DES-CBC3-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!aECDH:!EDH-DSS-DES-CBC3-SHA:!EDH-RSA-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA" SSLHonorCipherOrder On
If you’re feeling more conservative and aren’t too worried about forward compatibility with large numbers of ciphers that are not yet supported by Apache on OS X anyway, you could experiment with the following, which still sets the preferred order but also preserves some of the others which Apple enables by default, except for RC4:
SSLCipherSuite "ALL:!aNULL:!ADH:!eNULL:!LOW:!EXP:!RC4:DHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA:AES128-SHA:AES256-SHA:DES-CBC3-SHA:RC4+RSA:+HIGH:+MEDIUM" SSLHonorCipherOrder On
To ensure that changes like these survive the rebuilding of apache_serviceproxy_customsites.conf
from the .plist
file, we need to replace the following line in servermgr_serviceproxy_customsites.plist
:
<string>SSLCipherSuite "ALL:!aNULL:!ADH:!eNULL:!LOW:!EXP:RC4+RSA:+HIGH:+MEDIUM"</string>
(Note that the encoding of double quotes in the .plist
is intentional.) We’ll change that to the following, or to a variation, if you prefer the more conservative cipher suite mentioned above:
<string>SSLCipherSuite "ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:ECDHE-RSA-DES-CBC3-SHA:ECDHE-ECDSA-DES-CBC3-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:AES:CAMELLIA:DES-CBC3-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!aECDH:!EDH-DSS-DES-CBC3-SHA:!EDH-RSA-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA"</string> <string>SSLHonorCipherOrder On</string>
Then restart the proxy service with the usual:
sudo /Applications/Server.app/Contents/ServerRoot/usr/sbin/serviceproxyctl restart
You can then verify with Qualys or another tool that RC4 is now removed, the preferred cipher suite order is in place, and Forward Secrecy is available with far more browsers than when using the default settings. (Unfortunately, that list doesn’t include IE or Edge, or Safari on either iOS 9 or El Capitan.)
Note that disabling RC4
may also reveal what appears to be an obscure bug in the cURL library, or possibly in Apple’s own Secure Transport. In particular, shutting off RC4
ciphers will cause cURL requests from a host back to itself to fail when host verification is disabled — as one might do, for example, when using a self-signed certificate. For WordPress users, this can cause problems with WP Cron
and other loopback-type processes on SSL-enabled hosts. When RC4
is allowed, the normal wp_remote_get()
and wp_remote_post()
functions work fine, but when it is not, they fail with SSLRead() return error -9841
. More details are available in a WordPress ticket on the problem.
All material on this site is carefully reviewed, but its accuracy cannot be guaranteed, and some suggestions offered here might just be silly ideas. For best results, please do your own checking and verifying. This specific article was last reviewed or updated by Greg on .