In our lighttpd 2 development branch we use modules to implement SSL support; this allows us to support different ssl libraries, and today I want to talk about mod_gnutls.
SSL/TLS had some trouble. On the one hand there is the BEAST attack , which recommends using RC4 for SSL3.0 and TLS1.0 connections and on the other hand RC4 in TLS is broken .
So while some clients may support TLS1.1 or even TLS1.2, you still have to support RC4 for those which don’t, but you also don’t want to allow RC4 for clients that support TLS1.1 or TLS1.2. Most server configurations can’t handle that – but mod_gnutls can, using a nice hook function in GnuTLS (PolarSSL supports this directly too, and Hiawatha is using it).
Basically it will just append
":-CIPHER-ALL:+ARCFOUR-128" to your priority string (similar to ciphers in OpenSSL) if the connection uses TLS1.0 or SSL3.0.
"NORMAL:-VERS-SSL3.0:-CIPHER-ALL:-SHA1:-MD5:+SHA1:+AES-256-GCM:+AES-256-CBC:+CAMELLIA-256-CBC:%SERVER_PRECEDENCE" as priority string for GnuTLS in lighttpd2, and mod_gnutls will fix BEAST for you:
- SSL3.0 is disabled – all clients should at least support TLS1.0 now
-SHA1:-MD5:+SHA1 reorders the ciphers so that SHA1 comes later and removes MD5 ciphers (there is only one supported MD5 cipher:
-CIPHER-ALL:+AES-256-GCM:+AES-256-CBC:+CAMELLIA-256-CBC selects the 3 ciphers we’d like to support. You could also add 128-bit ciphers if you want:
%SERVER_PRECEDENCE tells the GnuTLS server to reorder the ciphers to its own preference.
- You could add “:-RSA” to force DHE/ECDHE key exchanges which should provide perfect forward secrecy.
The recommended priority string should result in the following cipher list:
For TLS1.0 it will use this instead (SSL3.0 is disabled):
With a standard RSA key it will use the following ciphers (update: we now support DHE):
and for TLS1.0:
lighttpd 2 config example:
"priority" => "NORMAL:-VERS-SSL3.0:-CIPHER-ALL:-SHA1:-MD5:+SHA1:+AES-256-GCM:+AES-256-CBC:+CAMELLIA-256-CBC:%SERVER_PRECEDENCE",
"listen" => "0.0.0.0:443",
"pemfile" => "/ssl/certs/lighttpd_server.pem"
Now you can test your server (needs a recent enough version of GnuTLS that at least includes support for TLS1.1, tested with gnutls 3.0.22):
gnutls-cli --priority="NORMAL:-CIPHER-ALL:+ARCFOUR-128" example.com
gnutls-cli --priority="NORMAL:-CIPHER-ALL:+ARCFOUR-128:-VERS-TLS-ALL:+VERS-TLS1.0" example.com
gnutls-cli --priority="NORMAL:-ARCFOUR-128:-VERS-TLS-ALL:+VERS-TLS1.0" example.com
The first one should fail; GnuTLS should use TLS1.2 to connect, and RC4 won’t be available. The second command should work – it should use TLS1.0 to connect, and only RC4 should be available, and that is why the third one should fail again.
Qualys SSL Labs Server Test should detect this setup, it will show the
"SSL_RSA_WITH_RC4_128_MD5" under “Suites used only for BEAST mitigation (TLS 1.0 and earlier)”.