Feature #1288
closedSSL Client Certificate validation.
Description
I took the opportunity to port #921 to trunk, enhance it and the port it back to 1.4.x branch ;)
Lighttpd should support SSL Client Certificate validating. There are a lot of good use-cases for this.
And most importantly Apache mod_ssl supports it :p
Files
Updated by nmaier over 17 years ago
Lighttpd Client Certificate Validation README¶
A patchset to add support for validation client side ssl certificates to lighty.
Contents¶
- lighty-clientvalidation-1.4.x.patch - against branches/lighttpd-1.4.x@1882
- lighty-clientvalidation-trunk.patch - against trunk@1878
- test/ca.crt - CA Cert used when conducting the testing
- test/server.prem - Server Certificate (pemfile) during testing
- test/client.p12 - Client Certificate during testing; password=test
- test/lighttpd14.conf - test conf for the 1.4.x branch
- test/lighttpd.conf - test conf for the trunk
New configuration¶
- bool ssl.verifyclient.activate - Activate the functionality; default=disable
- bool ssl.verifyclient.enforce - Only let clients with a cert in; default=enable
- short ssl.verifyclient.depth - Depth of validation that OpenSSL should perform; default=9
- string ssl.verifyclient.username - Use this Certificate entry as a username which will be passed to (most) handlers
Idea¶
My goal was to add validation of client certs to lighttpd.
I tried to keep somewhat compatible with apache2.
Apache will set REMOTE_USER. This implementation does as well (.username) but additionally provides all SSL_CLIENT_DN_* entries.
Webapps/handlers may use this information for fine grained authentication/identity checking.
Allowing the client to not provide a certificate (see: .enforce/REMOTE_USER/SSL_CLIENT_DN_*) might provide webapps with the ability to allow also anonymous access. This is turned off by default to protect against "lazy people" ;)
The CA file it will use is configured through ssl.ca-file.
Testing¶
I carried out testing on two system:- Ubuntu Feisty / PHP5.2.1
- Debian Sarge / PHP5.2.3-0.dotdeb.0
Browsers tested * Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.8.1.6) Gecko/20061201 Firefox/2.0.0.6 (Ubuntu-feisty) * Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9a7pre) Gecko/2007072118 Minefield/3.0a7pre * Mozilla/5.0 (Windows; U; Windows NT 5.1; de; rv:1.8.1.6) Gecko/20070725 Firefox/2.0.0.6 * Opera/9.22 (Windows NT 5.1; de) (Opera sucks for CS btw :p) * Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1)
Tested was against a static index.html, a favicon and a phpinfo() script via php5-fcgi.
Known issues¶
- It seems that CA certs using other than sha1 fail.
- At the moment lighty screams about a lot of read errors. This will also happen without this patchset
Acknowledgements¶
- The OpenSSL folks for their library, obviously ;)
- Lars for bringing this up and pointing me in the right direction through his patches; see <http://trac.lighttpd.net/trac/ticket/921>
Copyright/License¶
The authors disclaims copyright to the code thereby placing it into public domain.
Lighttpd Devs may simply take this and interoperate this into lighty without legal problems.
(I would be thankful for some credit however, and I guess Lars would too ;))
Updated by presbrey over 17 years ago
Conditional configurations prevent SSL_ environment variables from being passed to CGI. A snippet from the failing case follows:
$SERVER["socket"] == "0.0.0.0:443" { ssl.engine = "enable" ssl.verifyclient.activate = "enable" ssl.verifyclient.enforce = "enable" ssl.verifyclient.depth = 2 server.document-root = "/srv/www/root-ssl/" }
Updated by nmaier over 17 years ago
Replying to presbrey:
Conditional configurations prevent SSL_ environment variables from being passed to CGI. ...
I had the code that adds the envvars in the wrong place, i.e. before the config was merged. Hence only the global context was recognized. Should be fixed by now.
Furthermore I fixed an error causing segfaults when the ssl.engine and verifyclient are enabled but later the engine is conditionally disabled again.
(Hence the ssl stuff is random and openssl crashed).
Updated by presbrey over 17 years ago
Replying to nmaier:
Getting close nmaier... here's the next bug. In a script resolved via url.rewrite-once (i.e: url.rewrite-once += ( "^/main/do/([[^\]]+)(\??.*)" => "/main/$1.php$2" )
), environment variables' values are injected twice producing duplicated values:
_ENV[SSL_CLIENT_S_DN_C] US, US _ENV[SSL_CLIENT_S_DN_ST] State, State _ENV[SSL_CLIENT_S_DN_CN] presbrey, presbrey _ENV[SSL_CLIENT_S_DN_EMAILADDRESS] presbrey@foo.bar, presbrey@foo.bar
...etc.
Updated by presbrey over 17 years ago
Replying to nmaier:
Getting close nmaier... here's the next bug. In a script resolved via url.rewrite-once (i.e: url.rewrite-once += ( "^/main/do/([^\]+)(\??.*)" => "/main/$1.php$2" )
), environment variables' values are injected twice producing duplicated values:
_ENV["SSL_CLIENT_S_DN_C"] US, US _ENV["SSL_CLIENT_S_DN_ST"] State, State _ENV["SSL_CLIENT_S_DN_CN"] presbrey, presbrey _ENV["SSL_CLIENT_S_DN_EMAILADDRESS"] presbrey@foo.bar, presbrey@foo.bar
...etc.
(fixed trac comment formatting)
Updated by presbrey over 17 years ago
Moving the call to https_add_ssl_entries below plugins_call_handle_uri_raw in response.c fixes the issue I reported (attached new patch above).
Updated by Anonymous over 16 years ago
Is there any chance to see support for Certificate Revocation Lists? This would be ideal in case certificates are compromised.
Great work on this patch, by the way, thanks!
-- berto
Updated by hvdkamer over 16 years ago
I've backported this patch to the version shipped in Debian Etch. It works great. However in Apache the complete presented certificate can be exported in an environment variable. Is it possible to do the same in Lighttpd? See the Apache documentation:
http://www.apache-ssl.org/docs.html#SSLExportClientCertificates
With the complete certificate more rigoreus testing of the authentication would be possible. For example in this setup:
https://test.hetlab.tk/certlogin/
I accept certificates from CAcert, Ascertia, StartSSL and my own CA. I now use the e-mailaddress because that one is in the three free certificate providers tested with a mailprobe. In this case someone can use the same e-mailaddress in all certificate providers and still be mapped to the same account. Not a real problem, but with access to the certificate we could use the fingerprint in a tighter control. The above question could also be done in the application code. In this case checking the CRL is better be done in the server? Anyway, access to the complete certificate could be ice in more scenarios...
Updated by lcorbes over 16 years ago
Hi all,
I don't know if it will be usefull to someone else but I add a patch to get the serial number of the client certificate in environment variables.
This allow us to check it for authentification thru a cgi script.
(The patch works on 1.4.19, will check for 1.5.x if needed).
Updated by Anonymous over 16 years ago
Hi, is it possible to set ssl.verifyclient for a folder?
Something like:
$SERVER[[socket]] == "0.0.0.0:443" { ssl.engine = "enable" $HTTP[[url]] =~ "^/login/" { ssl.verifyclient.activate = "enable" ssl.verifyclient.enforce = "enable" ssl.verifyclient.depth = 2 } }
Updated by Anonymous about 16 years ago
What is the status of this issue?
Is there any version that supports this?
-- sinister
Updated by stbuehler about 16 years ago
i plan to have a look at it after 1.4.20 got released.
Updated by iuridiniz about 16 years ago
This issue is marked for 1.4.21, so will it be possible on 1.4.21? I'm currently doing this by using stunnel.
Updated by stbuehler about 16 years ago
- Patch available set to No
As long as the feature request is not "fixed" it obviously isn't included.
Updated by akrus about 16 years ago
Installed lighttpd/1.4.20 with this patch yesterday, works fine, but anyway it would be great the patch is included in mainstream :)
Updated by akrus about 16 years ago
Okay, someone to add CRL support? Would be great...
Updated by akrus almost 16 years ago
Uploaded patch for 1.4.20, minor changes, but previous one didn't work as expected :)
currently trying to make $HTTP["url"] support...
Updated by kjikaqawej almost 16 years ago
nmaier wrote:
Copyright/License¶
The authors disclaims copyright to the code thereby placing it into public domain.
Lighttpd Devs may simply take this and interoperate this into lighty without legal problems.
(I would be thankful for some credit however, and I guess Lars would too ;))
Maybe it's possible where you are, but in .ca and .us you can't put anything into the public domain, unless you're at NASA or some org. that has explicit laws allowing you to do so. Also, with your statement, you effectively put it under a permissive BSD-like licence. Nonetheless, it would be GPL (v2, dunno about v3) compatible. Note, I'm not a lawyer, and you should consult a lawyer for more information.
As for the work itself, thank you :).
Updated by icy almost 16 years ago
- Target version changed from 1.4.21 to 1.4.22
Updated by akrus almost 16 years ago
why 1.4.22? lighttpd is missing this feature for sooooo long.
Updated by icy almost 16 years ago
True but we wanted to get 1.4.21 out very soon and in fact there is already a RC out (see blog).
We included the most important fixes and some stuff that was particularly easy to commit in that version.
I haven't looked through all these patches and it would need some testing too. Therefor it was set for .22 like all other patches that didn't make it into .21
I am sorry that this feature didn't make it into svn yet but there are limits on how much time we can invest so something is always falling behind :(
Updated by stbuehler over 15 years ago
- Target version changed from 1.4.22 to 1.4.23
Updated by tdussa over 15 years ago
So why has the target version been bounced again?
Updated by jkb over 15 years ago
any chance somebody can make a patch against 1.4.21? our site really needs this feature and would hate to switch to apache for this. thanks.
Updated by akrus over 15 years ago
Here we go~
Updated by icy over 15 years ago
tdussa wrote:
So why has the target version been bounced again?
Because 1.4.22 is an important bugfix release that needs to be pushed out as fast as possible. Mostly concerning FreeBSD users.
Sorry, again :(
And thanks to nmaier, presbrey and akrus for working on the patches! I will keep an eye on this one.
Updated by jkb over 15 years ago
solved my problem, deleting previous note. sorry about this..
Updated by bjuchli over 15 years ago
Hi everybody,
i've updated the patch to 1.4.22. I've never made a patch before... so here's what i did:
Compared the the files 1.4.21 files to the 1.4.21 files that are affected by the patch (1.4.21).
Since only only /src/server.c has changed i've adjusted line 209 of the patch from
@@ -275,6 +275,7 @@ to @@ -278,6 +278,7 @@
since the altered code section has moved down 3 lines but has not changed itself.
I think i should work. At least it seems to work for me ;-)
Updated by oleg.smirnov over 15 years ago
- File lighttpd-clientverify2-1.4.22.patch lighttpd-clientverify2-1.4.22.patch added
- Target version changed from 1.4.23 to 1.4.22
I checked patch for 1.4.22 -- it actually works, and wrote one more feauture: now it sets SSL_CLIENT_VERIFY env variable in the same way as mod_ssl does.
Updated by icy over 15 years ago
- Target version changed from 1.4.22 to 1.4.23
Please don't set target version to something already released. It's the version that is planed to include the change.
Updated by jkb over 15 years ago
hi... is there a way to do client authentication based on URL string or Agent string?
Updated by akrus over 15 years ago
jkb wrote:
hi... is there a way to do client authentication based on URL string or Agent string?
You may write a new patch that will support it :) currently there's no support for this kind of authorization, only 'enable' or 'disable'.
Updated by hamar over 15 years ago
How can I authenticate users with certificates coming from multiple CAs? Is there a way to configure the CA certificate path, something equivalent to the SSLCACertificatePath directive in apache?
Updated by nipil over 15 years ago
hamar wrote:
How can I authenticate users with certificates coming from multiple CAs? Is there a way to configure the CA certificate path, something equivalent to the SSLCACertificatePath directive in apache?
As far as i know, you can add the different CA certificates to the ca-file. Maybe you could ask hvdkamer (who posted above), he does this kind of multiple acceptance in his testbed located at https://test.hetlab.tk.
Updated by stbuehler over 15 years ago
Okay... how to get this upstream: I want one clean patch for the latest released version (1.4.22 now). Porting it to trunk shouldn't be too difficult after that.
This means that the involved developers should be included in that patch (if they want to), and all used environment variables should be documented; and i think it would be nice to have some more "standard" (i.e. Apache) variables there.
I tried to find the time to do this myself... but as you see, nothing happend yet. So if you want to help getting this upstream, you know what to do :)
Updated by stbuehler over 15 years ago
- Target version changed from 1.4.23 to 1.4.24
Updated by presbrey over 15 years ago
Attached patch to latest trunk (r2585). Compatible with GSSAPI patch (#1899).
Updated by nicolas314 about 15 years ago
Just my 2 cents on the topic: mod_ssl forwards a lot more variables than what the current patch seems to offer. A quick glance shows:
SSL_CIPHER, SSL_CIPHER_ALGKEYSIZE,
SSL_CIPHER_EXPORT, SSL_CIPHER_USEKEYSIZE,
SSL_CLIENT_CERT, SSL_CLIENT_VERIFY,
SSL_COMPRESS_METHOD, SSL_PROTOCOL,
SSL_SERVER_A_KEY, SSL_SERVER_A_SIG,
SSL_SERVER_CERT, SSL_SERVER_I_DN,
SSL_SERVER_I_DN_CN, SSL_SERVER_I_DN_O,
SSL_SERVER_M_SERIAL, SSL_SERVER_M_VERSION,
SSL_SERVER_S_DN, SSL_SERVER_S_DN_C,
SSL_SERVER_S_DN_CN, SSL_SERVER_S_DN_O,
SSL_SERVER_S_DN_OU, SSL_SERVER_V_END,
SSL_SERVER_V_START SSL_VERSION_INTERFACE
SSL_VERSION_LIBRARY
Most important for client certificate validation would be to pass the client certificate itself, which would allow web apps to dig out whatever values they need.
Many thanks for bringing this to lighttpd!
Updated by stbuehler about 15 years ago
- Assignee deleted (
jan) - Priority changed from High to Normal
- Target version changed from 1.4.24 to 1.4.x
- Missing in 1.5.x set to No
I pushed the basic verification support now; but the environment vars are missing for now (I really think the vars should be documented in the code) - I agree with nicolas314: we should at least export the client cert, and the others should be included too.
Updated by patrickdk about 15 years ago
nicolas314 wrote:
SSL_CIPHER, SSL_CIPHER_ALGKEYSIZE,
SSL_CIPHER_EXPORT, SSL_CIPHER_USEKEYSIZE,
SSL_COMPRESS_METHOD, SSL_PROTOCOL,
SSL_SERVER_A_KEY, SSL_SERVER_A_SIG,
SSL_SERVER_CERT, SSL_SERVER_I_DN,
SSL_SERVER_I_DN_CN, SSL_SERVER_I_DN_O,
SSL_SERVER_M_SERIAL, SSL_SERVER_M_VERSION,
SSL_SERVER_S_DN, SSL_SERVER_S_DN_C,
SSL_SERVER_S_DN_CN, SSL_SERVER_S_DN_O,
SSL_SERVER_S_DN_OU, SSL_SERVER_V_END,
SSL_SERVER_V_START SSL_VERSION_INTERFACE
SSL_VERSION_LIBRARY
Shouldn't all those be a seperate issue? those should be passed on any ssl session, and not a client thing
I agree the client_cert belongs on this ticket though.
Updated by nicolas314 about 15 years ago
patrickdk wrote:
Shouldn't all those be a seperate issue?
You are right, sorry. Server-side and protocol-related SSL variables should always be present whenever SSL is used. Client-side variables: the client certificate is a minimum, splitting it into components would probably be very appreciated by application writers.
Updated by ostehovel about 15 years ago
- File diff.patch added
I just made a patch by combinding some other patches in this thread.
This patch was made from rev #2656 of the trunk
and if you find any mistakes, bad typing stuff like that please re-upload a corrected version please ;D
Oste Hovel
Updated by stbuehler about 15 years ago
- Status changed from New to Fixed
- % Done changed from 0 to 100
Applied in changeset r2688.
Updated by stbuehler about 15 years ago
- Target version changed from 1.4.x to 1.4.25
Updated by cicik about 14 years ago
- File lighttpd-1.4.28-clientvalidation-serialenv.patch lighttpd-1.4.28-clientvalidation-serialenv.patch added
Here is a patch for lighttpd 1.4.28 that sets serial number of the client certificate into environment. Previous patch won't work with this version of lighttpd.
Updated by gstrauss over 8 years ago
- Related to Bug #2093: ssl client auth doesn't work... (in 1.4.24) added
Updated by gstrauss over 8 years ago
- Related to Feature #478: Add support for mutually authenticated SSL added
Also available in: Atom