Cipher Suite

This is the web server's openssl cipher configuration:

SSLCipherSuite "HIGH+EDH+AESGCM:HIGH+EECDH+AESGCM:HIGH+EDH:HIGH+EECDH:+SHA256:-TLSv1:-SHA:!SEED:!aNULL:!eNULL:!LOW:!3DES:!MD5:!EXP:!PSK:!SRP:!DSS:@STRENGTH:+TLSv1:+SSLv3:+SSLv2:EDH+RC4:EECDH+RC4"
My goals are to only support cipher suites incorporating ephemeral key agreement, give a strong preference to TLSv1.2 (and higher), and offer RC4 for TLSv1.0 and SSLv3 clients (also as long as they support ephemeral key agreement). I was inspired to dig into OpenSSL's cipher list from this other page.

Explanation

The list of cipher suites starts off empty, and the SSLCipherSuite string is interpretted left-to-right to add, remove, and rearrange the list.

  1. HIGH+EDH+AESGCM
    Start the list with only cipher suites that OpenSSL considers "high", use authenticated ephemeral Diffie Hellman (DH) key agreement, and incorporate AES-GCM.
  2. HIGH+EECDH+AESGCM
    Next, append cipher suites that OpenSSL considers "high", use authenticated ephemeral Elliptic Curve Diffie Hellman (ECDH) key agreement, and incorporate AES-GCM.
  3. HIGH+EDH
    Now append the rest of the "high" suites using ephemeral DH that weren't already pulled in via HIGH+EDH+AESGCM.
  4. HIGH+EECDH
    And append the rest of the "high" suites using ephemeral ECDH that weren't already pulled in via HIGH+EECDH+AESGCM.
  5. +SHA256
    Move cipher suites using SHA256 to the end of the list (least preferred). (At this point, the list only includes suites incorporating SHA384 and SHA256.)
  6. -TLSv1
    BEAST countermeasure: Remove any TLSv1 (or older) suites, but don't ban them completely. Later, we'll pull in RC4 suites (with ephemeral DH and ECDH key agreement) for TLSv1 & SSLv3 clients.
  7. -SHA
  8. !SEED:!aNULL:!eNULL:!LOW:!3DES:!MD5:!EXP:!PSK:!SRP:!DSS
    Ban these, and don't let them come back in. In theory, we could put these ! rules anywhere in the SSLCipherSuite string.
  9. @STRENGTH
    Sort the current cipher suites by their encryption key sizes, with the biggest keys first.
  10. +TLSv1:+SSLv3:+SSLv2
    Then move TLSv1 suites to the end. And after that, move SSLv3 suites. And after those, move the SSLv2 suites. (Actually at this point, we don't have any TLSv1 or lesser suites, because of the -TLSv1 and -SHA rules above. But I leave this rule in so that if I ever did want to include older suites, these rules will ensure they're placed at the end.) Note: In my current version of OpenSSL, the TLSv1 and SSLv3 lists are identical. Also, while SSLv2 is listed in "man ciphers", running "openssl ciphers -V 'SSLv2'" returns nothing.
  11. EDH+RC4:EECDH+RC4
    Begrudgingly include RC4 suites, but only those suites that include ephemeral DH or ephemeral ECDH.

OpenSSL Interpretation

tensor(pts/0):/etc/apache2> openssl ciphers -V 'HIGH+EDH+AESGCM:HIGH+EECDH+AESGCM:HIGH+EDH:HIGH+EECDH:+SHA256:-TLSv1:-SHA:!SEED:!aNULL:!eNULL:!LOW:!3DES:!MD5:!EXP:!PSK:!SRP:!DSS:@STRENGTH:+TLSv1:+SSLv3:+SSLv2:EDH+RC4:EECDH+RC4'                   
	0x00,0x9F - DHE-RSA-AES256-GCM-SHA384     TLSv1.2 Kx=DH   Au=RSA   Enc=AESGCM(256) Mac=AEAD
	0xC0,0x30 - ECDHE-RSA-AES256-GCM-SHA384   TLSv1.2 Kx=ECDH Au=RSA   Enc=AESGCM(256) Mac=AEAD
	0xC0,0x2C - ECDHE-ECDSA-AES256-GCM-SHA384 TLSv1.2 Kx=ECDH Au=ECDSA Enc=AESGCM(256) Mac=AEAD
	0xC0,0x28 - ECDHE-RSA-AES256-SHA384       TLSv1.2 Kx=ECDH Au=RSA   Enc=AES(256)    Mac=SHA384
	0xC0,0x24 - ECDHE-ECDSA-AES256-SHA384     TLSv1.2 Kx=ECDH Au=ECDSA Enc=AES(256)    Mac=SHA384
	0x00,0x6B - DHE-RSA-AES256-SHA256         TLSv1.2 Kx=DH   Au=RSA   Enc=AES(256)    Mac=SHA256
	0x00,0x9E - DHE-RSA-AES128-GCM-SHA256     TLSv1.2 Kx=DH   Au=RSA   Enc=AESGCM(128) Mac=AEAD
	0xC0,0x2F - ECDHE-RSA-AES128-GCM-SHA256   TLSv1.2 Kx=ECDH Au=RSA   Enc=AESGCM(128) Mac=AEAD
	0xC0,0x2B - ECDHE-ECDSA-AES128-GCM-SHA256 TLSv1.2 Kx=ECDH Au=ECDSA Enc=AESGCM(128) Mac=AEAD
	0x00,0x67 - DHE-RSA-AES128-SHA256         TLSv1.2 Kx=DH   Au=RSA   Enc=AES(128)    Mac=SHA256
	0xC0,0x27 - ECDHE-RSA-AES128-SHA256       TLSv1.2 Kx=ECDH Au=RSA   Enc=AES(128)    Mac=SHA256
	0xC0,0x23 - ECDHE-ECDSA-AES128-SHA256     TLSv1.2 Kx=ECDH Au=ECDSA Enc=AES(128)    Mac=SHA256
	0xC0,0x11 - ECDHE-RSA-RC4-SHA             SSLv3   Kx=ECDH Au=RSA   Enc=RC4(128)    Mac=SHA1
	0xC0,0x07 - ECDHE-ECDSA-RC4-SHA           SSLv3   Kx=ECDH Au=ECDSA Enc=RC4(128)    Mac=SHA1
tensor(pts/0):/etc/apache2> openssl ciphers 'HIGH+EDH+AESGCM:HIGH+EECDH+AESGCM:HIGH+EDH:HIGH+EECDH:+SHA256:-TLSv1:-SHA:!SEED:!aNULL:!eNULL:!LOW:!3DES:!MD5:!EXP:!PSK:!SRP:!DSS:@STRENGTH:+TLSv1:+SSLv3:+SSLv2:EDH+RC4:EECDH+RC4' 
DHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:DHE-RSA-AES256-SHA256:DHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:DHE-RSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-RC4-SHA:ECDHE-ECDSA-RC4-SHA
tensor(pts/0):/etc/apache2> 

Note: I'm still slightly wary of Elliptic Curve's, so I don't mind that the slightly slower EDH suites are listed before EECDH suites, within each grouping of encryption key size and hash size. My simple rationale is if EC's are faster to compute, then they're also faster to brute-force.

Evaluation by Qualys' SSL Labs

At the moment (2014-08-01), the web server scores an A+ according to https://www.ssllabs.com/ssltest/analyze.html?d=ad5ey.net with the caveat that I don't care to support ancient operating systems such as Windows XP.

DNSSEC, DANE

Yep, I've had my domains "DNSSEC-ified" for a few years now, so adding DANE wasn't too painful. For background, for those of us that are wary of the huge vulnerability due to SSL/TLS clients trusting too many different Certificate Authorities, DANE is the spec for providing hashes (or whole copies...) of your SSL/TLS certificates in your DNSSEC zones.

Though the standard gives sites the option of using CA-signed or self-signed certificates, I've used flags in my TLSA records indicating my CA-signed certificates should be trusted even without CA verification as long as the records are validated via DNSSEC.