lighttpd and SSL client certificates
I recently configured my lighttpd server to enable authentication based on SSL client certificates on a private subdomain. Here’s a quick how-to.
-
Configure OpenSSL:
$ cp /etc/ssl/openssl.cnf ./ $ $EDITOR openssl.cnf # Edit "dir" $ mkdir certs $ echo "00" > serial $ echo "00" > crlnumber $ touch index.txt
-
Create the CA:
$ openssl genrsa -out ca.key 2048 # Generate a RSA-2048 private key $ openssl req -new -x509 -days 3650 -key ca.key -out ca.crt # Generate a certificate from the private key
-
Create a SSL client certificate:
$ openssl genrsa -out client.key 2048 # Generate a RSA-2048 private key $ openssl req -config openssl.cnf -new -key client.key -out client.csr # Generate a certificate from the private key $ openssl ca -batch -config openssl.cnf -days 3650 -in client.csr -out client.crt -keyfile ca.key -cert ca.crt -policy policy_anything # Sign the certificate using the CA $ openssl pkcs12 -export -in client.crt -inkey client.key -certfile ca.crt -out client.p12 # Convert the certificate to PKCS#12 for browser support
-
Import the certificates in a browser. For example in Firefox:
- Go to Settings, “Advanced”, “Certificates” tab, and click “Show certificates”
- In “Authorities”, click “Import” and select
ca.crt
- In “Your certificates”, click “Import” and select
client.p12
-
Configure lighttpd.
-
If you haven’t configured SSL in lighttpd yet, do it.
-
Add your newly generated
ca.crt
as thessl.ca-file
for the private subdomain:$ cat /etc/lighttpd/lighttpd.conf | grep ssl.ca-file ssl.ca-file = "/etc/lighttpd/ca-client.pem"
-
Enable client certificate verification in lighttpd:
$HTTP["host"] == "my-ssl-domain" { ssl.ca-file = "/etc/lighttpd/ca-client.pem" ssl.verifyclient.activate = "enable" ssl.verifyclient.enforce = "enable" ssl.verifyclient.username = "SSL_CLIENT_S_DN_CN" }
ssl.verifyclient.activate
activates the client certificate verificationssl.verifyclient.enforce
allows to enforce valid client certificates: if enabled, the SSL connections will fail if no client certificate is provided. If disabled, client certificates will be optional.ssl.verifyclient.username
defines which field of the client certificate will be stored in the request environment (which can then be used by scripts run by the server):SSL_CLIENT_S_DN_CN
for the Common Name,SSL_CLIENT_S_DN_emailAddress
for the email address, etc.- more options are described in the official docs.
-
-
Restart lighttpd and visit your site: you should be asked which certificate you want to use to connect.
Comments
Join the conversation by sending an email. Your comment will be added here and to the public inbox after moderation.
Which one is the ca-client.pem?
It’s the ca.crt created at step 2.
What’s in your openssl.cnf? After creating my own OpenSSL based CA and creating my certificates i can still not use them as they where not signed by any CA in my target system’s trusted CA bundle. Did you just inject your own CA’s certificate into the trusted CA bundle of your target system?
What about ssl.verifyclient.depth?
Mine didn’t work at first but fortunately I left the browser there hanging. Then when I moved to another desktop/workspace to do something else, I accidentally hit the windows key which caused every window in the workspace to miniaturize, and then I saw the Firefox prompt window waiting for me to press OK. To summarize, Firefox put up a query box on another workspace than the browser, and hid it under existing windows. I believe that’s called security by obfuscation.
@Craig: No idea. Never used it, and I don’t even use lighttpd anymore…