add ssl to lighttpd server

For some time now I have protected all my own connections to trivia with an SSL connection. I do this to protect my user credentials when managing trivia’s content or configuration. In fact my server is configured to force any connection coming from my IP address to a secured SSL connection so that I cannot accidentally connect in clear.

Of course my X509 certificate is self signed (why would I go to the trouble and expense of getting a certificate from a commercial CA?). I built it in the standard form recommended on many sites (and as I have discussed before) thus:

openssl req -new -x509 -nodes -keyout server.pem -out server.pem -days 1095

This says, build a PEM format file called “server.pem” which contains both the (new) server private key (by default RSA) and the (new) certificate. The certificate will be valid for 1095 days (three years).(The “-nodes” switch means there will be no passphrase). I have happily used certificates like this (and similarly contructed TLS certificates) to protect my webserver and POP3/IMAP/SMTP servers for some years. When running this command you will be prompted for certificate details covering location, organisation name and common name (i.e. the name of the server). The only really critical component here is the “Common Name”. If your server is called wwww.something.org, then that is what you must enter in the Common name field. On trivia I used something like this:

Country Name (2 letter code) [AU]:UK

State or Province Name (full name) [Some-State]:Norfolk

Locality Name (eg, city) []:Norwich

Organization Name (eg, company) [Internet Widgits Pty Ltd]:trivia

Organizational Unit Name (eg, section) []:

Common Name (eg, YOUR name) []:baldric.net

Email Address []:postmaster@baldric.net

A month or two ago I found a nice firefox plugin from calomel.org. This plugin adds a toolbar button which changes colour (from red, through amber to green) according to the plugin’s assessment of the strength of the SSL cipher of the current connection. Clicking on the button gives you a reasonably detailed summary of the SSL negotiation parameters from the site you are connected to. In addition to checking the connection, the tool offers the ability to change how firefox negotiates its connection with SSL enabled sites. So for example you can allow only TLS v1.1 and v1.2 and turn off OCSP checks or limit the connection to choosing only ciphers which offer forward secrecy. All in all a very useful and interesting plugin.

One problem immediately became apparent on trivia – I got a big red button and the plugin complained that the connection was very insecure.

baldric-cert-info

As can be seen above, the certificate was 1024 bit RSA with a 128 bit RC4 symmetric cipher. The biggest problem of course was the lack of a trust chain because the certificate was self signed. The question is, should I care about this? For my threat model, probably not. After all, all I am trying to protect is my user credentials when managing a blog. My finances are not threatened. However, the recent brouhaha around NSA/GCHQ capability against SSL, and the publicity about the weakness of RC4 cipher suites got me thinking about how I could strengthen the SSL connection if necessary. After all, whilst I might not care about, or need, a particularly strong SSL connection to trivia, readers might be interested in how to build and configure a stronger certificate and cipher chain. After a little research on the openssl site and a few others such as madboa and skytale.net I came up with a stronger set of options. I also strengthened the SSL preferences offered by my lighttpd installation during the negotiation handshake. Here’s how:

Firstly we need to build the X509 certificate file using stronger ciphers thus:

openssl req -x509 -nodes -sha256 -newkey rsa:2048 -keyout server.pem -out server.pem -days 1095

As with the first option shown above, this tells openssl to build a new X509 certificate file called server.pem which will be vailid for three years. However, in this case we specify sha256 with 2048 bit RSA rather than the weaker defaults. Once again we need to supply the certificate location and naming details as above.

When the certificate is complete it needs to be stored in a directory accessible to the webserver (I use /etc/lighttpd/ssl). Because the certificate contains the server’s private key it needs to be protected from casual prying eyes so it is a good idea to make it read only and owned by root (chmod 400). The certificate is only read on startup before lighty gives up root priviliges so mode 400 root is fine.

Now we need to strengthen the default ciphers offered by lighty in the SSL negotiation with the client.

The lighty configuration file for SSL (usually found at /etc/lighttpd/conf-enabled/10-ssl.conf) contains a list of prefered ciphers. By default it looks like this on debian.

$SERVER[“socket”] == “0.0.0.0:443” {

ssl.engine = “enable”

ssl.pemfile = “/etc/lighttpd/server.pem”

ssl.cipher-list = “ECDHE-RSA-AES256-SHA384:AES256-SHA256:RC4:HIGH:!MD5:!aNULL:!EDH:!AESGCM”

ssl.honor-cipher-order = “enable”

}

(I normally change the pemfile location to /etc/lighttpd/ssl/server.pem)

But this configuration allows weak RC4 ciphers to be offered in the negotiation with the client. A better configuration would be:

$SERVER[“socket”] == “0.0.0.0:443” {

ssl.engine = “enable”

ssl.pemfile = “/etc/lighttpd/ssl/server.pem”

ssl.use-sslv2 = “disable”

ssl.use-sslv3 = “disable”

ssl.cipher-list = “TLSv1+HIGH !SSLv2 !RC4 !aNULL !eNULL !3DES @STRENGTH”

ssl.honor-cipher-order = “enable”

}

This says: use the TLSv1=HIGH cipher set (see the openssl documentation on cipher suites) but do not use SSLv2, the RC4 suite or any of the very weak (or completely insecure) ones thereafter. The “@STRENGTH” directive means we should sort the ciphers by strength and offer the most secure first. For good measure I have also disabled use of the (old) ssl-v2 and ssl-v3 suites in separate lines.

Qualys SSL labs over at www.ssllabs.com provide a very good suite of on-line tests for SSL certificates. They also provide some good advice on SSL/TLS implementation. All you need to do when testing a site is enter the full domain name of that site and it will be subjected to a battery of tests and after a minute or two you get a very detailed report of the strength (or otherwise) of negotiated connection. My test of trivia after building the new configuration got a pleasingly strong set of results. (Well, actually I got an F, but I would have got an A if the trust chain failure was ignored).

But hey, I’m still not going to pay a CA for something I can do myself for nothing.

And why should I trust a commercial CA anyway?

Permanent link to this article: https://baldric.net/2013/09/12/add-ssl-to-lighttpd-server/