n this month’s article, I am going to discuss
the recent migration from our long-time friends Apache::AuthNetLDAP,
to the built-in C modules, mod_ldap and mod_auth_ldap. We have
been using Apache::AuthNetLDAP since 1999-2000, when Mark Wilcox, the
former web administrator for UNT, wrote the module. It has
worked well, and is still being used on the www farm as the
authentication mechanism. But, on web2, we had been noticing
some extreme delays in authentication for publishing, and I,
personally, had been noticing connectivity issues with the campus LDAP
servers.
As I am implementing LDAP groups to replace the htgroup
files of yore, I have become even more aware of these issues.
Because I had discovered that this publishing problem directly related
to the connections to the LDAP server, I knew that we would need to
implement caching to cache the users credentials on the web server, to
limit the number of times that the web server would need to query the
LDAP server for authentication and authorization. (HTTP is
stateless, so for the web server to know if you are allowed to see
each item you are requesting, it needs to query the LDAP server for
each item that is sent to the browser. (ie images, included
files, etc.)).
As you may guess, this could be a substantial
number of requests. In the case of publishing, some webDAV
clients, such as web folders, touch each file to get a directory
listing for the remote folder. This could send thousands of bind
requests to the LDAP server, and in the past, was believed to have
caused some instability in our directory services here on campus.
Since we needed caching, my first thought was to find a mod_perl
module that would cache these connections. Enter Apache::AuthenCache... Oops... No, exit
Apache::AuthenCache. Apache::AuthenCache does not support
mod_perl2, which is the version that we use on web2, therefore, this
was not an option. (There have been attempts to get the author
to port the module, and there are developers that have contacted me
about uploading their ported versions, but we haven’t succeeded in
this endeavor yet ;( ).
mod_ldap and mod_auth_ldap
Ok, now enter mod_ldap and mod_auth_ldap.
These are new modules that have been added to the Apache2 base,
allowing us to take advantage of the C implementations for LDAP
authentication.
First, to enable LDAP authentication with these
modules, you need to use the following flags when configuring Apache:
./configure –with-ldap –enable-ldap –enable-auth-ldap
IT IS VERY IMPORTANT TO HAVE –with-ldap in this
list, as it is not documented anywhere obvious. (Only in
httpd_install_dir/modules/experimental/README.ldap)
Second, enable caching on your server, but adding
the following lines to the httpd.conf.
LDAPSharedCacheSize 200000
LDAPCacheEntries 1024
LDAPCacheTTL 600
LDAPOpCacheEntries 1024
LDAPOpCacheTTL 600
LDAPTrustedCA /location/of/your/ca.crt
LDAPTrustedCAType BASE64_FILE
####End of LDAP Conf
#
# This should be changed to whatever you set
DocumentRoot to.
#
<Directory /your/webroot>
I just used the default that is found on:
http://httpd.apache.org/docs-2.0/mod/mod_ldap.html with the addition of the LDAPTrustedCA and
LDAPTrustedCAType directives. Use these two directives only if
you want to connect to the LDAP server over a secure connection,
(specifically, ldaps). The options for LDAPTrustedCAType are:
DER_FILE - file in binary DER format
BASE64_FILE - file in Base64 format
CERT7_DB_PATH - Netscape certificate database file
Third, we need to set the configuration for
mod_auth_ldap.
# include for the vHost conf
Include conf/webroot.conf
<Directory /your/web>
##### Beginning of mod_auth
#####################
AuthAuthoritative Off
AuthUserFile /location/to/password/file
AuthGroupFile /location/to/group/file
##### End of mod_auth #####################
##### Beginning mod_auth_ldap
##########################
AuthType Basic
AuthName "coolsite"
AuthLDAPEnabled on
AuthLDAPURL ldaps://your.ldap.server:636/o=base?uid
AuthLDAPBindDN "ldapuser"
AuthLDAPBindPassword "ldapuserpassword"
##### End mod_auth_ldap
##########################
</Directory>
This configuration posed some interesting
problems. First, I wanted Apache to check LDAP, and then fail to
basic Apache authentication if the user was not able to bind to the
LDAP server. Well, this was a wrong assumption on my part.
Basic Apache authentication is actually the first authentication
mechanism that is checked, then if that fails, it hands off
authentication to mod_auth_ldap. This is not that much of a
problem, but you need to make sure that you clear all usernames from
the password file that have a duplicate username in LDAP. For
example:
htpasswd
shannon:!@#$3485asfd
LDAP server
uid=shannon,o=base
If I login to the Apache using ‘shannon’ as my
login name, then Apache will check basic Apache authentication, (mod_auth),
and see that ‘shannon’ is indeed a user which should be authenticated
at the mod_auth level. This will return an error. Once you
remove the ‘shannon’ username from the htpasswd file, then mod_auth
will pass the authentication handling down to mod_auth_ldap, just as
we wanted.
Another important note: if you want mod_auth to
pass authentication to another authentication module, then you need to
set the directive:
AuthAuthoritative Off
in the httpd.conf file. If you don’t, then mod_auth will simply fail the user, and never check LDAP.
Finally, I believe that we found a bug in
mod_auth_ldap... You will notice that I am including conf files
for the virtual hosts. I do this for administrative reasons, as
well as making the config files much easier to read. Though the
directives:
##### Beginning of mod_auth #####################
AuthAuthoritative Off
AuthUserFile /location/to/password/file
AuthGroupFile /location/to/group/file
##### End of mod_auth #####################
can be used in the .htaccess file, or httpd.conf
file, the directives need to appear together. For example, I
wanted to set AuthAuthoritative to Off for all virtual hosts, but have
each virtual host use a different AuthUserFile and AuthGroupFile.
To do this, I placed AuthAuthoritative Off in the httpd.conf file,
then placed the Auth*File directives in each virtual host.conf file
that was later included into the main httpd.conf file. This
configuration would never fail, or DECLINE, to mod_auth_ldap, so I ran
Apache through the debugger, and realized that AuthAuthoritative was
being set to Off, when Apache was started, but then every time a
request was sent to Apache, mod_auth would re-initialize
AuthAuthoritative to On... My current work-around is to include
all of these directives in a <Directory> container in the main httpd.conf file. For more information, check out:
http://www.issociate.de/board/post/128389/interesting_problem_with_mod_auth/AuthAuthoritative.html
The final step in our configuration is to change
our <Limit> container, (in the .htaccess file, or <Directory>
container), to require groups. (The other types of ‘requires’
are well documented at:
http://httpd.apache.org/docs-2.0/mod/mod_auth_ldap.html#requiredirectives
Our old <Limit> container looked like:
<Limit PUT DELETE>
require group speeves admin
</Limit>
This only allowed the groups ‘speeves’ and
‘admin’ to PUT or DELETE after authenticating. The new <Limit>
should be changed to reflect the Distinguished Name of the group that
holds your user membership. For example:
<Limit PUT DELETE>
require group cn=speeves,ou=webgroups,o=base
require group cn=admin,ou=webgroups,o=base
</Limit>
What appears to be another bug, is that we need
to place multiple groups on separate lines. For some reason, the
space between multiple groups on the same line is causes issues with mod_auth_ldap reading in multiple entries from the require directive.
Therefore, my work-around was to put them on separate lines.
Very simple.
In Conclusion
Thank you for hanging in there with me through
this month’s article. I am pleased with the ease with which this
transition was made, and, from the feedback, you are as well. If
you have any questions about this article, please, feel free to
contact me at
speeves@unt.edu, or if you have general questions about web
development here at UNT, you can send those to
untwebdev@unt.edu .
Return to top