January 28, 2010 -
Tested under Debian Lenny
This howto is basic, as in “no security involved”. I may come up with a second part to this guide about securing OpenLDAP with TLS, if I ever find the time.
Meanwhile see http://www.openldap.org/doc/admin23/security.html for the security aspect of things.
In this example, I’ll create a tree following this scheme : dc=my,dc=domain,dc=tld.
It’s really up to you how you organize your tree, it’s really for organizational purposes. You can limit your tree to a single root branch, for example dc=myname.
Install OpenLDAP server and some useful utilities :
# apt-get install slapd ldap-utils
You should be prompted for a password, if not create it from the command line :
# slappasswd
New password:
Re-enter new password:
{SSHA}vFk3EP4SSW0RDm4yEKD
Edit /etc/ldap/slapd.conf :
You should copy the password obtained with slappasswd under the rootpw option.
include /etc/ldap/schema/core.schema
include /etc/ldap/schema/cosine.schema
include /etc/ldap/schema/nis.schema
include /etc/ldap/schema/inetorgperson.schema
pidfile /var/run/slapd/slapd.pid
argsfile /var/run/slapd/slapd.args
loglevel none
modulepath /usr/lib/ldap
moduleload back_hdb
sizelimit 500
tool-threads 1
backend hdb
database hdb
suffix "dc=my,dc=domain,dc=tld"
rootdn "cn=admin,dc=my,dc=domain,dc=tld"
rootpw "{SSHA}vFk3EP4SSW0RDm4yEKD"
directory "/var/lib/ldap"
dbconfig set_cachesize 0 2097152 0
dbconfig set_lk_max_objects 1500
dbconfig set_lk_max_locks 1500
dbconfig set_lk_max_lockers 1500
index objectClass eq
lastmod on
checkpoint 512 30
access to attrs=userPassword,shadowLastChange
by dn="cn=admin,dc=my,dc=domain,dc=tld" write
by anonymous auth
by self write
by * none
access to dn.base="" by * read
access to *
by dn="cn=admin,dc=my,dc=domain,dc=tld" write
by * read
“cn=admin,dc=my,dc=domain,dc=tld” is the database admin. This is what you will use as credential when you need to modify something in the database.
Then edit /etc/ldap/ldap.conf :
This is the configuration for the LDAP client.
HOST 127.0.0.1
BASE dc=my,dc=domain,dc=tld
URI ldap://localhost
Now create a directory that will contain some initial configuration files.
# mkdir /etc/ldap/LDIF
In this directory create the following files :
1_base.ldif (the base of our LDAP tree) :
dn: dc=my,dc=domain,dc=tld
dc: my
objectClass: domain
2_group.ldif (this will be the branch that will host our groups) :
dn: ou=Groups,dc=my,dc=domain,dc=tld
ou: Groups
objectClass: organizationalUnit
3_dev.ldif (this is our first group) :
dn: cn=dev,ou=Groups,dc=my,dc=domain,dc=tld
cn: dev
gidNumber: 30000
memberUid: user1
objectClass: posixGroup
objectClass: top
description: developers
4_people.ldif (this is the branch hosting users) :
dn: ou=People,dc=my,dc=domain,dc=tld
ou: People
objectClass: organizationalUnit
5_user1.ldif (this is our first user) :
dn: uid=user1,ou=People,dc=my,dc=domain,dc=tld
uid: user1
cn: John Doe
displayName: John Doe
givenName: Doe
sn: Doe
objectClass: inetOrgPerson
userPassword: pass
mail: johndoe@domain.tld
When we are done, we can restart OpenLDAP and create the tree and import some data :
# /etc/init.d/slapd restart
# cd /etc/ldap/LDIF
# for i in `ls`; do ldapadd -x -D "cn=admin,dc=my,dc=domain,dc=tld" -W -f $i ; done
You should be prompted for the admin password as much as you have LDIF files in the directory.
If you didn’t name your file 1_base.ldif, 2_group.ldif, etc. the command may fail as it may try to add a group or user before creating its branch.
Now you should be able to query the LDAP tree :
# ldapsearch -x
# extended LDIF
#
# LDAPv3
# base <dc=my,dc=domain,dc=tld> (default) with scope subtree
# filter: (objectclass=*)
# requesting: ALL
#
# my.domain.tld
dn: dc=my,dc=domain,dc=tld
dc: my
objectClass: domain
# Groups, my.domain.tld
dn: ou=Groups,dc=my,dc=domain,dc=tld
ou: Groups
objectClass: organizationalUnit
# People, my.domain.tld
dn: ou=People,dc=my,dc=domain,dc=tld
ou: People
objectClass: organizationalUnit
# user1, People, my.domain.tld
dn: uid=user1,ou=People,dc=my,dc=domain,dc=tld
uid: user1
cn: John Doe
displayName: John Doe
givenName: Doe
sn: Doe
objectClass: inetOrgPerson
mail: johndoe@domain.tld
# dev, Groups, my.domain.tld
dn: cn=dev,ou=Groups,dc=my,dc=domain,dc=tld
cn: dev
gidNumber: 30000
memberUid: user1
objectClass: posixGroup
objectClass: top
description: developers
# search result
search: 2
result: 0 Success
# numResponses: 6
# numEntries: 5
This command requires /etc/ldap/ldap.conf. If you don’t have ldap.conf configured you’d have to type the whole command :
# ldapsearch -x -b "dc=my,dc=domain,dc=tld" -H ldap://server
Now, you can authenticate several services against your new LDAP server.
For example, web authentication in Apache.. Take a look at http://www.wains.be/index.php/2010/01/26/apache-simple-authentication-and-ldap-authentication-examples/
You also may want to install PHP LDAP Admin for managing your LDAP database through a web GUI :
# apt-get install phpldapadmin
Then go to http://server/phpldapadmin and authentify with cn=admin,dc=my,dc=domain,dc=tld and your rootpw.
January 26, 2010 -
Simple authentication :
Users credentials are stored in a file created with htpasswd command
<Location /dir/>
AuthType Basic
AuthName "Authentication"
AuthUserFile /etc/apache2/passwd-file
Require user username1 username2
</Location>
If we want to allow all users in passwd-file, use :
Require valid-user
LDAP user authentication :
We allow user1 and user2 found in the branch ou=People,dc=domain,dc=tld
<Location /dir/>
AuthName "Authentication"
AuthType Basic
AuthBasicProvider ldap
AuthzLDAPAuthoritative on
AuthLDAPURL ldap://127.0.0.1/ou=People,dc=domain,dc=tld
Require ldap-user user1 user2
</Location>
LDAP group authentication :
We allow all users in the group “support”, users are defined in that group under the memberUid field
<Location /dir/>
AuthName "Authentication"
AuthType Basic
AuthBasicProvider ldap
AuthzLDAPAuthoritative on
AuthLDAPURL ldap://127.0.0.1/ou=People,dc=domain,dc=tld
AuthLDAPGroupAttribute memberUid
AuthLDAPGroupAttributeIsDN off
Require ldap-group cn=support,ou=Groups,dc=domain,dc=tld
</Location>
Combination of users and group :
<Location /dir/>
AuthName "Authentication"
AuthType Basic
AuthBasicProvider ldap
AuthzLDAPAuthoritative on
AuthLDAPURL ldap://127.0.0.1/ou=People,dc=domain,dc=tld
AuthLDAPGroupAttribute memberUid
AuthLDAPGroupAttributeIsDN off
Require ldap-group cn=support,ou=Groups,dc=domain,dc=tld
Require ldap-attribute gidNumber=10000
Require ldap-user user1 user3 user5
</Location>
See also :
- Conditional web authentication : http://www.wains.be/index.php/2007/01/27/apache-conditional-http-authentication/
- Source for this post : http://www.linux.com/archive/feature/120050?theme=print
Keith in his post is wrong about the “Satisfy Any” option, as explained in Apache documentation : http://httpd.apache.org/docs/2.0/mod/core.html#satisfy :
This directive is only useful if access to a particular area is being restricted by both username/password and client host address. In this case the default behavior (All) is to require that the client passes the address access restriction and enters a valid username and password. With the Any option the client will be granted access if they either pass the host restriction or enter a valid username and password.
He seems to explain that the “Satisfy Any” option is necessary when using several “Require” arguments. That’s incorrect, all Require arguments are evaluated by default and must pass checks to give access to the resource.
January 25, 2010 -
This will just explain the configuration files needed for Postfix to check against the LDAP server.
We want to be able to send emails to username@domain.tld
We also want to have aliases for our users, for example : firstname.lastname@domain.tld pointing to username@domain.tld
Finally, we want groups to act as a mailing list, forwarding emails to members of the group, for example : support@domain.tld
LDAP tree
dc=domain,dc=tld
|-------ou=Aliases,dc=domain,dc=tld
|---------------cn=support,ou=Aliases,dc=domain,dc=tld
|
| cn : support
| description : alias support
| gidNumber : 50000
| mailRoutingAddress : support@domain.tld
| memberUid : it (this is a group with a inetLocalMailRecipient class and a mailRoutingAddress field defined)
| memberUid : username3 (this is a user account)
|
|-------ou=Groups,dc=domain,dc=tld
|---------------cn=it,ou=Groups,dc=domain,dc=tld
|
| cn : it
| description : IT dept group
| gidNumber : 40000
| mailRoutingAddress : it@domain.tld
| memberUid : username1
| memberUid : username2
|
|-------ou=Users,dc=domain,dc=tld
|---------------uid=username1,ou=Users,dc=domain,dc=tld
cn : username1
gecos : John Doe
gidNumber : 10000
homeDirectory : /home/username1
mail : john.doe@domain.tld
mailLocalAddress : john.doe
uid : username1
[...]
Postfix configuration
For this to work, we must define “append_at_myorigin = yes” in main.cf
For group/alias emails to work, the group must have the inetLocalMailRecipient class and mailRoutingAddress defined
So we basically add in main.cf :
virtual_alias_maps = ldap:/etc/postfix/ldap-account.cf, ldap:/etc/postfix/ldap-group.cf, ldap:/etc/postfix/ldap-alias.cf
It means that Postfix will check ldap-account.cf first, then ldap-group.cf and finally ldap-alias.cf.
So we create those files :
ldap-account.cf (for virtual users) :
server_host = localhost
port = 389
version = 3
search_base = ou=Users,dc=domain,dc=tld
scope = sub
# we search through the Users base for the recipient email address (%s)
query_filter = (mail=%s)
# if we find anything under ou=Users,dc=domain,dc=tld, we deliver to the account specified under "uid"
# so basically, if we send an email to john.doe@domain.tld, we will find an entry, finally delivering the email to uid username1
result_attribute = uid
ldap-alias.cf (for virtual aliases) :
server_host = localhost
port = 389
version = 3
scope = sub
# we search through the Aliases base...
search_base = ou=Aliases,dc=domain,dc=tld
# ...for the recipient email address (%s) specified under mailRoutingAddress field
query_filter = mailRoutingAddress=%s
# If we find anything, return memberUid, that can be accounts, groups, or aliases
result_attribute = memberUid
ldap-group.cf (for virtual groups) :
server_host = localhost
port = 389
version = 3
scope = sub
# Same as aliases, but in a different base
search_base = ou=Groups,dc=domain,dc=tld
query_filter = mailRoutingAddress=%s
result_attribute = memberUid
July 13, 2007 -
yolinux.com has a great guide about password protection, security and authentication for OpenLDAP.
Source : yolinux.com
Mirror : http://www.wains.be/mirrors/yolinux.com/openldap-password/
-
I’ll consider you already have a database running.
I’ll only review how to set up the SSL certificate and key and what to change in the config files.
December 17, 2006 -
Matthew Feldt was kind enough to put up a guide explaining how to set up OpenLDAP as an addressbook compatible with Evolution and Microsoft Outlook.
Please visit his page here : http://www.feldt.com/work/projects/openLDAP/
A mirror of his page is available here : http://www.wains.be/mirrors/feldt.com/
The guide works for CentOS/RHEL 4.4.
Thanks Matthew for that very well written howto !
For your information, LDAP support in Outlook is terrible. No autocompletion available.. pretty much like IMAP support.. “terrible on purpose” ™
September 18, 2006 -
For some reason openldap stopped running and listening on port 389 after our server had a problem…
The database files (BDB type) were actually corrupted…
This is how to fix the issue and recover the DB :
- install db4-utils (under RedHat)
- cd /var/lib/ldap (or whatever directory in which the DB files are located)
- /etc/init.d/ldap stop
- run /usr/sbin/slapd_db_recover in the directory
- /etc/init.d/ldap start
The server was up again after fixing the DB
-
OpenLDAP logs via syslogd LOCAL4 so to stream the log you will need to add a line like this to syslog.conf (normally /etc/syslog.conf):
local4.* /var/log/ldap.log
The above command will log all levels of local4 (OpenLDAP) output to the defined file. In many systems you need to create an empty log file before logging will be visible.
The OpenLDAP logging level is set using the following command:
loglevel number
The possible values for number are:
loglevel Logging description
-1 enable all debugging
0 no debugging
1 trace function calls
2 debug packet handling
4 heavy trace debugging
8 connection management
16 print out packets sent and received
32 search filter processing
64 configuration file processing
128 access control list processing
256 stats log connections/operations/results
512 stats log entries sent
1024 print communication with shell backends
2048 print entry parsing debugging
April 1, 2006 -
This guide will help you setting up an LDAP directory under RHEL 4/CentOS 4 systems, 100 % compatible with Mozilla Thunderbird 1.5. Management of the LDAP directory will be done with phpLdapAdmin.
1. Install the needed packages
# yum install openldap-servers openldap-clients
2. Download the LDAP schema for Thunderbird
# wget http://www.wains.be/pub/thunderbird.schema -O /etc/openldap/schema/thunderbird.schema
3. Create the directory tree in which the database will be stored
# mkdir /var/lib/ldap/local
4. Change ownership
# chown ldap:ldap /var/lib/ldap/local
5. Make sure LDAP will start at boot
# chkconfig --level 345 ldap on
6. open tcp port 389 under iptables
# iptables -A INPUT -p tcp --dport 389 -j ACCEPT
# iptables-save > /etc/sysconfig/iptables
7. Make a backup of the default config
# mv /etc/openldap/slapd.conf /etc/openldap/slapd.conf.bak
8. Create and edit /etc/openldap/slapd.conf :
include /etc/openldap/schema/core.schema
include /etc/openldap/schema/cosine.schema
include /etc/openldap/schema/inetorgperson.schema
#include /etc/openldap/schema/nis.schema
include /etc/openldap/schema/thunderbird.schema
# bind_v2 will allow compatibility with older Thunderbird clients (tested under v0.4 & v0.5)
allow bind_v2
pidfile /var/run/slapd.pid
argsfile /var/run/slapd.args
database bdb
suffix "dc=domain,dc=be"
rootdn "cn=AddressManager,dc=domain,dc=be"
rootpw secret
directory /var/lib/ldap/local
index objectClass eq,pres
index ou,cn,mail,surname,givenname eq,pres,sub
#index uidNumber,gidNumber,loginShell eq,pres
#index uid,memberUid eq,pres,sub
#index nisMapName,nisMapEntry eq,pres,sub
9. Start the ldap service :
[root@server](1034)# service ldap start
Checking configuration files for : config file testing succeeded
Starting slapd: [ OK ]
10. Make sure ldap is running (IMPORTANT : if slapd crashes, you’d still get an OK when starting the service) :
[root@server](1036)# service ldap status
slapd (pid 2299) is running...
11. Create directory_def.ldif (directory structure) :
dn: dc=domain,dc=be
objectclass: top
objectclass: dcObject
objectclass: organization
dc: domain
o: Name of your company
12. Create directory.ldif (directory data) :
dn: cn=John Doe,dc=domain,dc=be
objectclass: top
objectclass: person
objectclass: organizationalPerson
objectclass: inetOrgPerson
givenName: John
sn: Doe
cn: John Doe
mail: john.doe@domain.be
Contacts should be separated by a blank line
13. Inject the directory structure :
ldapadd -xv -D "cn=AddressManager,dc=domain,dc=be" -f directory_def.ldif -W
ldap_initialize( <default> )
Enter LDAP Password: xxxxxx
add objectclass:
top
dcObject
organization
add dc:
domain
add o:
Name of your company
adding new entry "dc=domain,dc=be"
modify complete</default>
14. Inject the data into the directory :
ldapadd -xv -D "cn=AddressManager,dc=domain,dc=be" -f directory.ldif -W
15. Make sure data have been correctly injected :
ldapsearch -x -b "dc=domain,dc=be" "(objectclass=*)"
# extended LDIF
#
# LDAPv3
# base <dc =domain,dc=be> with scope sub
# filter: (objectclass=*)
# requesting: ALL
#
# domain.be
dn: dc=domain,dc=be
objectClass: top
objectClass: dcObject
objectClass: organization
dc: domain
o: Name of your company
# John Doe, domain.be
dn: cn=John Doe,dc=domain,dc=be
objectClass: top
objectClass: person
objectClass: organizationalPerson
objectClass: inetOrgPerson
givenName: John
sn: Doe
cn: John Doe
mail: john.doe@domain.be</dc>
16. Add the ldap addressbook server into Thunderbird :
For some reason, setting LDAP autocompletion into the general configuration did not work.
I had to add the LDAP autocompletion into the account settings
For more info : http://www.stolaf.edu/services/iit/documentation/thunderbird/ldap.html
For domain.be :
Name : domain directory
Hostname : ldap.domain.be
Base DN : dc=domain,dc=be
17. Install phpldapadmin
- yum install php-ldap
- Grab the RPM version of phpldapadmin that fits to your system on rpmfind.net
SRC RPM : ftp://rpmfind.net/linux/fedora/extras/4/SRPMS/phpldapadmin-0.9.8.2-1.fc4.src.rpm
RPM : ftp://rpmfind.net/linux/fedora/extras/4/i386/phpldapadmin-0.9.8.2-1.fc4.noarch.rpm
- Edit /etc/httpd/conf.d/phpldapadmin and allow connection from your IP
- service httpd restart
- Edit /etc/phpldapadmin/config.php and edit these values :
$ldapservers->SetValue($i,'server','name','Thunderbird LDAP Server');
$ldapservers->SetValue($i,'server','host','127.0.0.1');
$ldapservers->SetValue($i,'server','port','389');
$ldapservers->SetValue($i,'server','base',array('dc=domain,dc=be'));
$ldapservers->SetValue($i,'server','auth_type','config');
$ldapservers->SetValue($i,'login','dn','cn=AddressManager,dc=domain,dc=be');
$ldapservers->SetValue($i,'login','pass','secret');
Connect to http://host.domain.be/phpldapadmin/
You should be able to access your LDAP database, please note that this config is not the most secure scheme, you should set a password to access this directory
More info : http://applications.linux.com/article.pl?sid=05/05/18/1248224
Thunderbird can only read into LDAP directories, not write :
https://bugzilla.mozilla.org/show_bug.cgi?id=86405