This short HOWTO explains how to set up the excellent Lighttpd to work with a SSL certificate released from a CA. The whole processis fairly easy, but not completely straightforward. I hope the HOWTO will become the subject of a small talk during the next San Giacomo Festival, here in Maniago. ;-)
I'm assuming the host name for which the certificate will be set up is www.domain.ext and the operating system is Gentoo Linux (the process shouldn't be too different with another OS, though). Also, in my example I'm assuming that the certificate is a GoDaddy TurboSSL Certificate.
First of all, make sure you have OpenSSL and that Lighttpd is compiled with openssl support. In order to create your private key and the certificate request, I suggest you cd to you web server directory:
cd /etc/lighttpd
before generating the files with these two commands:
openssl genrsa -des3 -out www.domain.ext.key 1024
openssl req -new -key www.domain.ext.key -out www.domain.ext.csr
When, after issuing the second command, you are asked for the Common Name, be sure to enter the name of the host where you want to use you certificate, i.e.:
www.domain.ext
This will only work for https://www.domain.ext, and not for https://domain.ext or https://anyotherthing.domain.ext. Wildcard certificates exist, but they're more expensive (and IMHO not so useful).
OK, now you have the certificate request file, www.domain.ext.csr: go to your CA and upload it. After the verifications (GoDaddy only required me to reply to an e-mail), you'll get a download link for the certificate, which will be a file named:
www.domain.ext.crt
Depending on the CA you choose, you might need to download the CA certificate as well. In the case of GoDaddy, what is needed is the intermediate certificate (without this, browsers will complain that they cannot trust the CA).
At this point you have all the needed files, but a couple of actions still need to be performed. If you entered a password when creating the private key with OpenSSl, you'll now most likely want to remove it, otherwise Lighttpd will always prompt you for it when starting (which is not so handy):
cp www.mydomain.ext.key www.mydomain.ext.key.orig
openssl rsa -in www.mydomain.ext.key.orig -out www.mydomain.ext.key
Also, Lighttpd wants a single pem file, so you need to concatenate the key file and the certificate file as follows:
cat www.domain.ext.key www.domain.ext.crt > www.domain.ext.pem
For the sake of security you'd better make all these files readable only by root user:
chmod 600 *.pem *.key *.csr *.crt
The final step is the configuration of the web server. Open lighttpd.conf and add something similar to the following (this binds to a specific IP address, see Lighttpd SSL documentation for more options):
var.confdir = "/etc/lighttpd"
$SERVER["socket"] == "15.15.15.15:443" {
ssl.engine = "enable"
ssl.pemfile = var.confdir + "/www.domain.com.pem"
ssl.ca-file = var.confdir + "/gd_intermediate.crt"
server.name = var.confdir + "/www.domain.com"
server.document-root = "/my/document/root/"
}
You should be all set and ready to go now!

Hello Michele,
I read your article, buy I wonder, is there any way to have ssl on diferent domains (virtual) running on the same machine?
thanks
There is no real way to run virtual sites using https. The problem resides in the tls protocol not the web server. When tls is used ALL of the data is encrypted so there is no way to tell which virtual server the data is destine for. Which key should the server use to decrypt the data? About the only way to go would be to have virtual sites listen on different ports or different IP addresses. Not terribly virtual.
This limitation is why large ISPs are especially interested in tls2. My understanding is that tls2 will accommodate host headers i.e. virtual serves. (If tls2 ever gets completed.)
Chris
I don't know how to do this with LIGHTTPD but I know it's possible in Apache - so there should be a way in lighttpd.
And the point Chris added is strange - because the webserver knows the data he sends, and he can decrypt the data (he has to know which file someone orderd... :) ).
Maybe I'm wrong and LIGHTTPD is built differently, but in Apache it's possible, I know for shure.
Regards ~cimnine
From the Apache's SSL_FAQ (http://httpd.apache.org/docs/2.2/ssl/ssl_faq.html#vhosts) :
Why can't I use SSL with name-based/non-IP-based virtual hosts?
The reason is very technical, and a somewhat "chicken and egg" problem. The SSL protocol layer stays below the HTTP protocol layer and encapsulates HTTP. When an SSL connection (HTTPS) is established Apache/mod_ssl has to negotiate the SSL protocol parameters with the client. For this, mod_ssl has to consult the configuration of the virtual server (for instance it has to look for the cipher suite, the server certificate, etc.). But in order to go to the correct virtual server Apache has to know the Host HTTP header field. To do this, the HTTP request header has to be read. This cannot be done before the SSL handshake is finished, but the information is needed in order to complete the SSL handshake phase. Bingo!
That's weird, because it works on my hosts. :)
Regards, Chris
So, its very very easy to do named based virtual hosting. However there is a catch to it. So far what everyone said above is correct if you want to use diffrent keys for diffrent sites. For my personal server, I do not care if my key is signed for 8 diffrent domains names. At the end of the day, can vist any of those 8 domain names, and not get an SSL warrning. And I lose nothing, except for the fact that someone can see other sites that I am running. And for most people who are getting started with https, only have one IP, and don't even care if the cert is self signed, and hence your going to get an SSL error anyway... So why not make that happen to all your domains....
For lighttpd is really much easier to set up SSL for many domains, and one IP then apache.
$SERVER["socket"] == "IP:443" {
ssl.engine = "enable"
ssl.pemfile = "/PATH/TO/PEM"
ssl.ca-file = "/PATH/TO/CA"
simple-vhost.server-root = "/var/www/"
simple-vhost.default-host = "localhost"
simple-vhost.document-root = "/htdocs/"
}
done, this varables will need to be changed to suit you, but now all my sites have an SSL version.....
It would also be possible to branch this out to /var/www/http and /var/www/https and create symbolic links for those that you want in both.
You can make it work on both Apache and lighttpd. But you have to have a single certificate for all the sites. This is a little limiting for ISPs if their customers want their own certs. But if you want to run multiple virtual hosts under a single common domain name it is perfectly possible - e.g. a cert for "domain.net" could be used to cover "servername1.domain.net", "servername2.domain.net" etc.
How would i get a single ssl cert to work for all domains that i host?
for instance, all my virtual domains are stored in /home/http and then using lighttpd-mod-vhost-mysql i have them stored in the database as for example 'www.domain1.tld' and 'www.domain2.tld' which point to /home/http/domain1 and /home/http/domain2.
How would i make it so that a single ssl cert would work for all of those? would i just use the suggestion that 'George Shammas' made above?
You need a certificate like what go-daddy sells for multiple domains. The reason that they work and others do not is that instead of a CN, or Common Name the certificate CN is a serial number that is looked up with go-daddy. This serial number tells the client what domains are signed by the certificate.
m4pD20 FFFIILLUUUSSS3,