by Martin Eliasson
2008-10-16 21:19:53
public

Victory! Authenticating Apache on Linux against Active Directory

I need to share this victory with you all! I finally managed to get Apache 2 on Ubuntu 8.04 to authenticate against Windows Active Directory.

You have probably tried to use mod_ldap, mod_auth_ldap or mod_authnz_ldap without much success. One of the reasons is that:

  1. Active Directory (AD) servers are picky with the configuration
  2. AD may be configured to use DIGEST-MD5 authentication.

A related problem to not getting authentication to work is that LDAP browsers like gq also have a problem browsing AD. I think that too is a binding / algorithm problem.

The way forward is to use the good old bash and a command line tool called ldapsearch which is part of ldap-utils package in Ubuntu 8.04.

In order to ge authentication to work you must first get ldapsearch to work.

>> ldapsearch -LLL -s sub -b "dc=spam,dc=com" -H ldap://egg.spam.com -D "cn=userX,cn=usr,dc=spam,dc=com" -Y DIGEST-MD5 "(!(objectClass=computer))" -w qwerty sAMAccountName

Once ldapsearch can authenticate and look up users in AD, your next step is to install mod_python for Apache2. Aha, you think, he couldn't be that clever? Yes I can! Why not code an authentication handler in mod python using your ldapsearch command line using a pipe?

Here's the important part of the mod_python code

from mod_python import apache

def authenhandler(req):

    pw = req.get_basic_auth_pw()
    user = req.user

    #...IMPRTANT TODO: sanitize input. No spaces allowed for now.

    LDAPRequest = 'ldapsearch -LLL -s sub -b "dc=spam,dc=com" -H ldap://egg.spam.com -D "cn=%s,cn=usr,dc=spam,dc=com" -Y DIGEST-MD5 "(!(objectClass=computer))" -U %s -w %s sAMAccountName' %(user, user, pw)

    ExitNormal,  ExitCode,  Message = runCommand(LDAPRequest)

    if not ExitNormal:
        return apache.HTTP_UNAUTHORIZED
    elif ExitCode != 0:
        return apache.HTTP_UNAUTHORIZED
    else:
        return apache.OK

Apache config section

<Directory /var/www/TestAD>
  Order allow,deny
  allow from all
  AddHandler mod_python .py
  PythonAuthenHandler ldap_authentication
  AuthType Basic
  AuthName "Restricted Area"
  Require valid-user
  AuthBasicAuthoritative off
</Directory>

Comments