Author: Keith Winston
Network administrators frequently use the Lightweight Directory Access Protocol (LDAP) to implement a centralized directory server. You can use LDAP to authenticate users in Apache. Two popular open source LDAP solutions are OpenLDAP and Red Hat Directory Server. According to the Apache documentation, Novell LDAP and iPlanet Directory Server are also supported. This article focuses on OpenLDAP, but the concepts and examples should be applicable to the others.
LDAP was designed as a simplified version of the ITU-T X.500 directory specification. The default set of schemas contain all of the information you would find in traditional Linux system files such as /etc/passwd and /etc/group, or Sun’s Network Information System (NIS). The schemas are malleable and are often extended to contain additional demographic information or customized for specific applications.
Here’s an example of a typical LDAP user record in LDAP Data Interchange Format (LDIF):
dn: uid=keithw,ou=People,dc=company,dc=com uid: keithw cn: Keith Winston objectClass: account objectClass: posixAccount objectClass: top objectClass: shadowAccount userPassword: {crypt}$1$M/PZEwdp$KHjSay8JILX01YAHxjfc91 shadowLastChange: 13402 shadowMax: 99999 shadowWarning: 7 loginShell: /bin/bash uidNumber: 2741 gidNumber: 420 homeDirectory: /home/keithw gecos: Keith Winston
You can query the LDAP data with a number of tools, including the command-line ldapsearch
program, one of the standard OpenLDAP utilities. If you are new to LDAP, its terminology and syntax may be difficult at first. Taking the time to learn the LDAP search syntax will pay off later if you want to craft advanced policies using non-standard attributes.
Configuring Apache 2.2
Apache modules have been available for LDAP since at least version 1.3. However, if you have used mod_auth_ldap in the past, you should be aware that the bundled authentication and authorization modules have been refactored in version 2.2. The latest LDAP modules are loaded with these directives, usually in the httpd.conf file:
LoadModule ldap_module /path/to/mod_ldap.so LoadModule authnz_ldap_module /path/to/mod_authnz_ldap.so
Once the modules are loaded, you can control access by querying the directory for particular attributes. The key directive to point Apache at the LDAP server is AuthLDAPUrl
. A generic AuthLDAPUrl directive looks like this:
AuthLDAPUrl ldap://ldap.company.com/ou=People,dc=company,dc=com?uid
It defines the LDAP server, the base distinguished name (DN), the attribute to use in the search (usually Uid within the People organizational unit). For complex policies you may need extra search filters.
The next few sections show working examples of directives to enforce common policies. Each set of directives can be placed in the main Apache configuration file or in .htaccess files.
Any valid user
This set of directives allows access to the current directory to all valid users in the LDAP directory. Apache will ask the browser for a user ID and password and check them against the directory. If you are familiar with Apache Basic Authentication, there are only a few new directives to learn.
Order deny,allow Deny from All AuthName "Company.com Intranet" AuthType Basic AuthBasicProvider ldap AuthzLDAPAuthoritative off AuthLDAPUrl ldap://ldap.company.com/ou=People,dc=company,dc=com?uid Require valid-user Satisfy any
AuthBasicProvider ldap
is necessary so Apache knows to query an LDAP directory instead of a local file.
AuthzLDAPAuthoritative off
must be explicitly set because the default setting is “on” and authentication attempts for valid-user will fail otherwise. This is a tricky setting because other policies, such as Require ldap-user
, need the setting to be “on.” Setting this value off also allows other authentication methods to mixed with LDAP.
The Satisfy any
directive is not strictly required in this case because we are only testing one condition.
List of users
This set of directives allows access to the current directory to the users listed in the Require ldap-user
directive.
Order deny,allow Deny from All AuthName "Company.com Intranet" AuthType Basic AuthBasicProvider ldap AuthzLDAPAuthoritative on AuthLDAPUrl ldap://ldap.company.com/ou=People,dc=company,dc=com?uid Require ldap-user keithw joeuser Satisfy any
AuthzLDAPAuthoritative on
could be omitted since the default setting is “on,” but is left here for clarity.
Note the AuthLDAPUrl setting does not change. As in previous examples, it searches the directory for a matching Uid.
Member of a group
This set of directives allows access to the current directory to users who are either primary or secondary members of the group specified in the Require ldap-group
directive.
The group configuration may be the most difficult due to the schema design of directories that were converted from NIS (as mine was). Referring back to the user LDIF record, notice the gidNumber
attribute has a value of 420, the number assigned to the “infosys” group in my directory. It corresponds to the primary group of the user. However, the LDAP entry for each group lists only users who are secondary members of the group, using the memberUid
attribute. See below for a snippet of a group record:
dn: cn=infosys,ou=Group,dc=company,dc=com objectClass: posixGroup gidNumber: 420 memberUid: user1 memberUid: user2 memberUid: user3 ...
We need another test, Require ldap-attribute
, to pick up the primary users of the group, because they are not listed with the group itself. Here are the Apache
directives:
Order deny,allow Deny from All AuthName "Company.com Intranet" AuthType Basic AuthBasicProvider ldap AuthzLDAPAuthoritative on AuthLDAPUrl ldap://ldap.company.com/ou=People,dc=company,dc=com?uid AuthLDAPGroupAttribute memberUid AuthLDAPGroupAttributeIsDN off Require ldap-group cn=infosys,ou=Group,dc=company,dc=com Require ldap-attribute gidNumber=420 Satisfy any
AuthzLDAPAuthoritative on
could be omitted since the default setting is “on,” but it’s left here for clarity.
AuthLDAPGroupAttribute memberUid
indicates which attibute in the LDAP group record to match with the Uid — in this case, memberUid. A group record contains one memberUid attribute for each (non-primary) member of the group.
AuthLDAPGroupAttributeIsDN off
tells Apache to use the distinguished name of the client when checking for group membership. Otherwise, the username will be used. In my OpenLDAP directory, only the username was from NIS. The default setting is “on,” so setting it off was required. An LDAP directory may store the entire distinguished name, so you may need to change this setting based on your directory.
Require ldap-group
grants access to members of the “infosys” group. For multiple groups, add an additional directive for each.
Require ldap-attribute gidNumber=420
handles the primary users of group 420, the “infosys” group. Without this condition, primary users would be denied access. For multiple groups, add an additional directive for each.
The Satisfy any
directive is required because we are testing multiple conditions and want the successful test of any condition to grant access.
Combination of users and groups
The following example is a union of the user and group directives, but otherwise, there is nothing new.
Order deny,allow Deny from All AuthName "Company.com Intranet" AuthType Basic AuthBasicProvider ldap AuthzLDAPAuthoritative on AuthLDAPUrl ldap://ldap.company.com/ou=People,dc=company,dc=com?uid AuthLDAPGroupAttribute memberUid AuthLDAPGroupAttributeIsDN off Require ldap-group cn=infosys,ou=Group,dc=company,dc=com Require ldap-attribute gidNumber=420 Require ldap-user keithw joeuser Satisfy any
Debug and deploy
Testing LDAP authentication from a Web browser can be frustrating, because the only thing you know is whether access was granted or not. You don’t get any kind of feedback on why something did not work. For verbose information on each step in the process, set the LogLevel debug
option in Apache. With debugging active, Apache will record the connection status to the LDAP server, what attributes and values were requested, what was returned, and why conditions were met or not met. This information can be invaluable in fine-tuning LDAP access controls.
Categories:
- Apache & Web Servers
- System Administration