[PREV] | [UP] | [NEXT]

LDAP Configuration and Setup



Overview:

The DISC system runs as a self-contained environment based on an LDAP directory tree. None of the system's users exist locally on the hosting platform, and all necessary system info is stored in the directory tree. For software that does not read LDAP directly, like Apache virtual hosts, domain names and mailinglist aliases, information is read from LDAP with a daemon and stored in the directory tree.
To make use of the various functions in LDAP implementations of other software packages, a number of specific schema files are included and some existing ones need modifications.
DISC generally knows four different classes of users: system-only accounts that are necessary for interactions with services like FTP or POP, admins (the helpdesk group) who can edit all settings for each domain, domain-admins who can change settings for the domains they are admin of and domain-users who can only change their personal settings within certain limits. To implement this, heavy use of LDAP ACLs is made.


Getting and Installing OpenLDAP

OpenLDAP can be downloaded as sourcecode from www.openldap.org here When configuring your build, default features are fine, but you may want to change the installation path with ./configure --prefix=/path. At the moment we do not make use of SSL because the system is intended to run on a single machine, so you do not need to include it. Neither does DISChosting use LDAP replication (slurpd), should you want to use it anyway, make sure you include the appropriate build options.
Our configuration options:
./configure --datadir=/var/lib/ldap --sysconfdir=/etc/ldap --enable-crypt --enable-bdb --enable-ldbm
Previously we used the Debian Sarge default compilation, but this ran into problems on a high amount of records, making a mess out of our essential data!
/ Further information on installing and configuring LDAP can be found in the OpenLDAP Quick Start Guide


DISC Directory Tree:

The directory tree for DISC holds the account information for the LDAP admin, for the DISC admin and for "system-only" accounts in it's main branch. From there - the root is called "dot" - it branches off dependent on hosted domain names. Each TLD is assigned a seperate subtree, and each hosted domain below that has a seperate subtree as well. This serves both the purpose of having a clear structure and facilitates the seperation of account priviledges by ACLs as we will see later,
A basic example structure looks like this:

   dot
    |--- helpdesk
    |--- observer
    |--- system-users
    |                        \______________________
    |                                                          |--- web
    |                                                          |--- vmail
    |                                                          |--- ftp
    |--- system-groups
    |                           \_____________________
    |                                                           |--- operators
    |--- com
    |--- net
    |--- org
    |         \_____________________ example.org
    |                                                             |--- domainadmin
    |                                                             |--- users
    |                                                             |--- databases
    |--- other tld
    | ...


Configuring slapd:

To configure slapd so it will support DISC functions, a number of settings have to be in effect, especially ACLs need a lot of attention. We will now go through the necessary configuration directives step by step, assuming a standard out-of-the box slapd.conf file, and beginning from the top.
Allthough we will try to keep this text up to date, be sure to compare your slapd.conf with the version in /examples/slapd.conf in the DiscHosting source!


Start by adding the following line right at the beginning of the global section:

allow bind_v2

This feature is necessary for compatibility with courier-imap authentication.

password-hash {CRYPT}

This feature is necessary for .... ????


Next,load all necessary schema files

The following schema includes have to be set in the config file:

include /etc/ldap/schema/core.schema
include /etc/ldap/schema/cosine.schema
include /etc/ldap/schema/nis.schema
include /etc/ldap/schema/inetorgperson.schema
include /etc/ldap/schema/openldap.schema
include /etc/ldap/schema/dnsZone.schema
include /etc/ldap/schema/pureftpd.schema
include /etc/ldap/schema/authldap.schema
include /etc/ldap/schema/qmail.schema
include /etc/ldap/schema/squirrelmail.schema
include /etc/ldap/schema/amavis.schema
include /etc/ldap/schema/disc.schema
include /etc/ldap/schema/apachevirt.schema
include /etc/ldap/schema/sympa.schema
include /etc/ldap/schema/mailman.schema

Most of these schema files are either included with OpenLDAP or come with a specific software package. The apachevirt and disc schema files are specific to DISC, however, and the amavis.schema has been modified for use. (For details on the necessary schema modifications check out the Amavis section Mail System part of this manual) The schema files can be found in the /examples/schema directory of DISC. Copy them to /etc/ldap/schema


Now specify a database backend

Enter the following directives in your slapd.conf at the appropriate place

backend ldbm
database ldbm
moduleload back_ldbm

Even though some recommend using bdb backends, our tests with bdb were unsatisfactory. At the time of developement, a bug in the bdb backend prevented it's proper function with DISC, ldbm works reliably up to the time of drafting this document.
sizelimit unlimited

We need to set time and size limits, otherwise ldap will fail at 500 records (pretty soon).


Then enter database specific directives

First, specify the directory root:

suffix "dc=dot"


In the next step, define indices for frequently used attributes

index objectClass eq
index sn,mail,memberUid,associatedDomain pres,eq,approx,sub
index mailbox pres,eq
index maildrop pres,sub,eq
index cn,uid eq
index uidNumber eq
index gidNumber eq

Make sure those are set correctly, some lookups can fail in case of high workload if the attributes are not properly indexed.

As a final and essential step, configure access control

Since DISC stores all user data in ldap, unauthenticated access is not allowed. A good regular test is using phpldapadmin installed on your server, login in as a regular user. Generally, when you have access to information that is not yours or can even change other peoples information with that, something is terribly wrong in the ldap access control.

#
# Acess Control Configuration
#

# The first ACL block defines password access. It is essential for 
# authentication, since DISC does not allow anonymous binds.
# With this we make sure, that non-authenticated users can access passwords 
# for authentication purposes and people can write their own passwords. The 
# admin - that is, the LDAP, not the DISC admin - can write all passwords, 
# and the system users vmail and ftp can read them for authentication 
# purposes. The break rule in the end makes sure the next directive is 
# processed as well.
access to attribute=userPassword
        by dn="cn=admin,dc=dot" write
        by dn="uid=vmail,ou=system-users,dc=dot" read
	by dn="uid=ftp,ou=system-users,dc=dot" read
	by self write
	by anonymous auth
	by * none break

# Users in the helpdesk-categorie should be able to make new domains
# if this domain is in a new toplevel domain, they need this ACL
# to create the toplevel domain
access to dn="(dc=([^,]+),)*dc=dot"
        by dn="cn=admin,dc=dot" write
        by group/organizationalrole/roleOccupant="cn=helpdesk,dc=dot" write
	by * none break

# broadening the access of the userPassword rule above, not only admin,
# but also helpdesk users can change any password within the domains
# (but not systempasswords). Even more, domainadmins can change the
# all passwords of all users in their domain
access to dn="((dc=([^,]+),)*dc=([^,]+)),dc=dot" attrs=userPassword
        by dn="cn=admin,dc=dot" write
        by dn="uid=vmail,ou=system-users,dc=dot" read
	by dn="uid=ftp,ou=system-users,dc=dot" read
        by group/organizationalrole/roleOccupant="cn=helpdesk,dc=dot" write
        by group/organizationalrole/roleOccupant="cn=domainadmin,$1,dc=dot" write
	by self write
	by anonymous auth
	by * none break
		
## the entry pseudo attribute has to be readable to everyone, 
## and writeable to some otherwise some general queries which 
## are necessary do not give any results. 
## the break at the end makes sure further acls are evaluated because we
## want to set entry writeable for certain roleOccupants below
access to dn="((dc=([^,]+),)*dc=([^,]+)),dc=dot" attrs=children,entry
        by dn="cn=admin,dc=dot" write
        by group/organizationalrole/roleOccupant="cn=helpdesk,dc=dot" write
        by group/organizationalrole/roleOccupant="cn=domainadmin,$1,dc=dot" write
	by dn="uid=vmail,ou=system-users,dc=dot" read
	by dn="uid=ftp,ou=system-users,dc=dot" read
	by users read

# The next block governs access to the uid and ObjectClass attributes, 
# which need to be readable for system users to make service authentication 
# and user lookups possible.
# The regular expression used here matches all dn entries which begin with 
# uid and are located in the users ou of any tld subtree.
access to dn="uid=.*,ou=users,((dc=([^,]+),)*dc=([^,]+)),dc=dot" attrs=objectClass,uid 
	by dn="cn=admin,dc=dot" write
	by dn="uid=web,ou=system-users,dc=dot" read
        by dn="uid=vmail,ou=system-users,dc=dot" read
	by dn="uid=ftp,ou=system-users,dc=dot" read
	by group/organizationalrole/roleOccupant="cn=helpdesk,dc=dot" write
        by group/organizationalrole/roleOccupant="cn=domainadmin,$1,dc=dot" write
	by self read
	by group/organizationalrole/roleOccupant="cn=observer,dc=dot" read

# users can change some attributes themselves.
# the last rule breaks so roleOccupants can get write access 
# to these attributes later even if they match user here
access to dn="ou=users,((dc=([^,]+),)*dc=([^,]+)),dc=dot" attrs=cn,sn,givenName,homePostalAddress,homePhone,amavisSpamModifiesSubj,amavisBypassSpamChecks,amavisBypassVirusChecks,amavisSpamTagLevel,amavisSpamTag2Level,amavisSpamKillLevel,maildrop,deliveryMode,mailReplyText,userPassword
        by dn="cn=admin,dc=dot" write
	by dn="uid=vmail,ou=system-users,dc=dot" read
        by dn="uid=ftp,ou=system-users,dc=dot" read
	by group/organizationalrole/roleOccupant="cn=helpdesk,dc=dot" write
        by group/organizationalrole/roleOccupant="cn=domainadmin,$1,dc=dot" write
        by self write
	by group/organizationalrole/roleOccupant="cn=observer,dc=dot" read
	
# all other user attributes are read-only for users, but writeable for
# domainadmins and helpdesk
access to dn="ou=users,((dc=([^,]+),)*dc=([^,]+)),dc=dot"
        by dn="cn=admin,dc=dot" write
	by dn="uid=vmail,ou=system-users,dc=dot" read
	by dn="uid=ftp,ou=system-users,dc=dot" read
        by group/organizationalrole/roleOccupant="cn=helpdesk,dc=dot" write
        by group/organizationalrole/roleOccupant="cn=domainadmin,$1,dc=dot" write
        by self read
	by group/organizationalrole/roleOccupant="cn=observer,dc=dot" read

# aliases can only be defined by domainadmins and helpdesk
access to dn="ou=aliases,((dc=([^,]+),)*dc=([^,]+)),dc=dot"
        by dn="cn=admin,dc=dot" write
	by dn="uid=vmail,ou=system-users,dc=dot" read
        by group/organizationalrole/roleOccupant="cn=helpdesk,dc=dot" write
        by group/organizationalrole/roleOccupant="cn=domainadmin,$1,dc=dot" write
        by self read
	by group/organizationalrole/roleOccupant="cn=observer,dc=dot" read

# mysql access: for admins and domainadmins
access to dn="ou=databases,((dc=([^,]+),)*dc=([^,]+)),dc=dot"
        by dn="cn=admin,dc=dot" write
	by dn="uid=vmail,ou=system-users,dc=dot" read
	by dn="uid=ftp,ou=system-users,dc=dot" read
        by group/organizationalrole/roleOccupant="cn=helpdesk,dc=dot" write
        by group/organizationalrole/roleOccupant="cn=domainadmin,$1,dc=dot" write
	by group/organizationalrole/roleOccupant="cn=observer,dc=dot" read

# changing the admin: for admins and domainadmins
access to dn="cn=domainadmin,((dc=([^,]+),)*dc=([^,]+)),dc=dot"
        by dn="cn=admin,dc=dot" write
	by dn="uid=vmail,ou=system-users,dc=dot" read
	by dn="uid=ftp,ou=system-users,dc=dot" read
        by group/organizationalrole/roleOccupant="cn=helpdesk,dc=dot" write
        by group/organizationalrole/roleOccupant="cn=domainadmin,$1,dc=dot" write
	by group/organizationalrole/roleOccupant="cn=observer,dc=dot" read

### the roleOccupant attribute has to be readable 
### so users can see whether they are members of admin groups or not
access to dn="(dc=([^,]+)*,dc=([^,]+)),dc=dot"
        by dn="cn=admin,dc=dot" write
        by group/organizationalrole/roleOccupant="cn=helpdesk,dc=dot" write
        by group/organizationalrole/roleOccupant="cn=domainadmin,$1,dc=dot" write
        by users read

# helpdesk-attributes are writeable only by helpdesk and admin
access to dn="cn=helpdesk,dc=dot"
        by dn="cn=admin,dc=dot" write
        by group/organizationalrole/roleOccupant="cn=helpdesk,dc=dot" write
        by users read

# observer-attributes are only writeable by helpdesk and admin
access to dn="cn=observer,dc=dot"
        by dn="cn=admin,dc=dot" write
        by group/organizationalrole/roleOccupant="cn=helpdesk,dc=dot" write
        by users read

# The admin dn has full write access (one to rule them all ;-)
access to *
        by dn="cn=admin,dc=dot" write
       	by dn="uid=vmail,ou=system-users,dc=dot" read
	by self read 
	by group/organizationalrole/roleOccupant="cn=observer,dc=dot" read
	by * none

Compare your /etc/ldap/slapd.conf file with /examples/slapd.conf before you continue! We try to keep the examples up to date, even if changes might not yet have made it into the installation manual.

Starting LDAP

You will need to restart ldap to let the changes take effect. We assume an empty LDAP database, so we remove any previous information too

# /etc/init.d/slapd stop
# rm -rf /var/lib/ldap/*
# /etc/init.d/slapd start

Check /var/log/syslog to see if slapd started without errors.

After that you should be set to upload the basic LDAP tree into the system. A simple setup like the structure in the beginning can be found in /examples/sample.ldif. You cannot just upload this: some changes have to be made first:

  • copy this file to my.ldif
  • fill in the userPassword values for admin, vmail, web, ftp and helpdesk@test.org like this:
    UserPassword: {SSHA}myplainpassword
    
  • then do slapadd < my.ldif to initiate the ldap database

    Now your ldap server is ready for use. Make sure external access is blockes, for instance with:
    iptables -I INPUT -p tcp -s ! 127.0.0.1 --dport ldap -j DROP
    

    Making backups of LDAP

    LDAP stores very important system information. It would not be so nice to loose it. So like mysql databases, keeping a backup is important.
    In /examples is a cron script for making backups: ldapbackup.cron.daily. Copy it to /etc/cron.daily/ldapbackup and make the directory for the backups:
    # mkdir -p /hosting/archive/ldap
    # chmod og-rwx /hosting/archive/ldap
    

    Our next step will be to finish the dischosting install and setup the admin interface, so we can log in as the helpdesk user.

    [PREV] | [UP] | [NEXT]