The Pragmatic Addict

lighttpd client certificates

These are some notes I have for enabling client certificates in lighttpd on a test server. This authentication method is very different than plain, digest etc.

After connecting and establing an SSL/TLS connection, the server requests a client certificate. A verification is done to make sure the client cert was signed by our certificate authority. If so, the common name of the client certificate is used as the authenticated user name in lighttpd.

Whats very interesting is that the SSL/TLS server certificate does not have to use the same signing authority as the client authentication!

Much of this is referenced from Schnouki. I tweaked things a bit to fit my setup.

This configuration will do the following:

Setup the OpenSSL environment

cd /tmp
mkdir ssl
cd ssl
mkdir demoCA
mkdir demoCA/newcerts
mkdir demoCA/crl

echo "00" > demoCA/serial
echo "00" > demoCA/crlnumber
touch demoCA/index.txt
cp /etc/ssl/openssl.cnf .

Create a self signed server certificate

openssl req -x509 -newkey rsa:8192 -keyout serverkey.pem -out servercert.pem -sha256 -nodes -days 36500
cat serverkey.pem servercert.pem > localhost.pem

Create Certificate Authority for client keys

openssl genrsa -out demoCA/cakey.pem 2048
openssl req -new -x509 -days 3650 -key demoCA/cakey.pem -out demoCA/cacert.pem

Create client auth certificate & sign with CA

openssl genrsa -out clientkey.pem 2048
openssl req -config openssl.cnf -new -key clientkey.pem -out client.csr

openssl ca -batch -config openssl.cnf -days 3650 -in client.csr -out clientcert.pem -keyfile demoCA/cakey.pem -cert demoCA/cacert.pem -policy policy_anything 
openssl pkcs12 -export -in clientcert.pem -inkey clientkey.pem -certfile demoCA/cacert.pem -out client.p12

Enable SSL/TLS & client cert auth in lighttpd

/etc/lighttpd/conf-enabled/10-ssl.conf

server.modules += ( "mod_openssl" )

$SERVER["socket"] == "0.0.0.0:443" {
        ssl.engine  = "enable"
        ssl.pemfile = "/tmp/ssl/localhost.pem"
        ssl.cipher-list = "HIGH"
}

$HTTP["host"] == "localhost" {
    ssl.ca-file = "/tmp/ssl/demoCA/cacert.pem"
    ssl.verifyclient.activate = "enable"
    ssl.verifyclient.enforce = "enable"
    ssl.verifyclient.username = "SSL_CLIENT_S_DN_CN"
}

Install the client certificate into firefox

Testing

If all goes well the following URL should prompt for a certificate to authenticate with:

https://localhost/


Created: 2024-05-21 Modified: 2024-07-28