Now that I've got an LDAP
server up and running I'm trying to get my personal web server set up so it has a blanket authentication for my personal applications, static content and development stuff. The web applications I'm talking about aren't meant to be exposed to the public at large, they're not what you find here on Late Night PC Service
or any of my other sites. These are things like PHP Calendar
, Task Freak
, a bunch of development versions of apps I'm working on and some static content that might be a single html file or an image.
I currently have a server that's accessible through DynDNS
and I use basic HTTP authentication
on it. The server runs Apache HTTPD 2.2 and has whatever modules I want on it. My next server is roughly the same but I want to make things a little more secure and a little simpler (at the same time no less). So my idea was to move to LDAP
as the Authentication Provider and Digest as the Authentication Type.
Digest Authentication vs Basic
Digest is better than Basic because it Basic sends the user's password unencrypted. It'd be very easy for someone with a tool like Wireshark
) to sniff the password as it flies through an unencrypted wireless connection in a coffee shop. I guess (I've never tried). AuthType Basic just does a base64 encoding, not encryption. AuthType Digest
creates an MD5 digest from the password that the user enters in the browser and sends to the server that instead. It's actually much more complex than that (and there are supposed to be other algorithms besides MD5), but in effect that's what it boils down to.
LDAP Authentication Provider
authentication provider is better than the file authentication provider because the LDAP
database is a nice central database for all your users and passwords. It's designed to deal with user authentication and helps move closer to an SSO
environment. By checking user passwords against the LDAP database
, users can have the same username and password for all the services on the network.
Now here's the rub: you can have the LDAP
Authentication Provider (or others) with Basic authentication or the file Authentication provider with Digest Authentication. You can't have both, not with Apache alone.
Authentication Methods that Work
I did a lot of research and experimenting, here's what I know. Oh, and in the descriptions that follow I say "Apache" does everything but really a lot of it is delegated to modules like mod_ldap, mod_auth_basic, mod_authnz_ldap, mod_auth_digest and mod_authn_file.
Here's an Apache .htaccess file that will provide basic authentication with a password file.
AuthName "basic private area"
The passwords in .htpasswd are created with the htpasswd2 tool at the command-line.
Here's an Apache .htaccess file that will provide digest authentication with a digest file.
AuthName "digest private area"
The command-line tool htdigest2 works similarly to htpasswd2 but the AuthName ("digest private area") must be supplied as it matters too. For example:
rob4@copper:~> htdigest2 -c .digest_pw "digest private area" dude
Adding password for dude in realm digest private area.
New password: duder
Re-type new password: duder
I think that changing the AuthName will require you to re-create the entries in your digest file.
Here's an Apache .htaccess file that will provide basic authentication against the LDAP
AuthName "LDAP Private Area"
In this case the user sees the authentication dialog pop up, they enter their user id as it is stored in the LDAP
database. They also enter the corresponding password. In my case, I want this to be the same password that's used to log in to a user account on computers in my home. The username and password that the user enters in the authentication dialog are sent to the server unencrypted (because this is AuthType Basic). On the server side, Apache (through the LDAP
modules) asks the LDAP
server and searches for the user with the given uid. The returned record includes an MD5 digest of that user's password which Apache can compare to the MD5 digest of the password that it received from the user. If they match then the user is in, otherwise access is denied.
The problem here is, as I mentioned above, the trip from the browser to Apache is unencrypted. I don't think I have a real risk in my situation but if I'm going to have a password anyway (to keep out casual surfers & bots) then I want it to be useful.
But I Wanted Both...
What I want is something like this
AuthName "LDAP digest private area"
This doesn't work. When I try it I get this in my Apache error log.
[Thu Aug 30 15:23:30 2007] [alert] [client 192.168.3.105] /home/rob4/www/copper/htdocs/authtest/.htaccess: The 'ldap' Authn provider doesn't support Digest Authentication
At the moment I'm stymied. I want to have an easy way to ensure that any visitor to my home machine is securely authenticated, no matter what they're looking at. This is a small set of people and most (other than me) are infrequent visitors, but I still think it should be done right - simple for legitimate users to access and not worth the time for anyone else. I'm not tied to HTTP Authentication but it seemed like the obvious choice for this application. Apparently it's not. If you're ready to give up, then at least have a laugh with Joe Gregorio's view of the situation
From here I'm going to consider other options that revolve around checking for a valid user in .htaccess or httpd.conf and redirecting users who aren't signed in to a login page for authentication. That might have to be an SSL/TLS page or maybe I can do something with this interesting example of using PHP to do HTTP Authentication
. I could start with the Digest version of the example and the LDAP functions in PHP
that I'll inevitably have to dive in to eventually. If I go this route I'd like to follow up by using the REMOTE_USER server variable to automatically log in the user to any applications on the server.
Sorry I've got no great conclusion today but I do need to come up with something so when I do I'll blog that too.