Contents
-
-
CentOS 7
-
Installing OpenLDAP From Source
-
Starting Server
-
Adding Records
-
Ubuntu 9.10 Using /etc/ldap/slapd.conf
-
slapd Init Script
-
Gentoo OpenLDAP Server
-
Managing Accounts With ACL
-
-
-
Centos 7 Client Setup
-
Centos 6 Client Setup
-
CentOS 5 Client Setup
-
Ubuntu Client Setup
-
Gentoo Client Setup
-
-
-
OpenSSL Key Generation
-
TLS
-
Generating SSL Keys For OpenLDAP
-
-
-
Gentoo LDAP Clients
-
LDIF Format
-
ldapmodify
-
ldapadd
-
ldapsearch
-
/usr/bin/ldapdelete
-
Other Utilities
-
-
-
Logging
-
Mystery Death
-
InK’s Excellent Pro Tips
-
Fix passwd functionality
-
Connectivity
-
Directory Backup And Restore
-
Helpful Utilities
-
-
-
Useful Documents
-
Glossary
-
List Of Ubuntu LDAP Package Highlights
-
Screw LDAP/FreeIPA
It’s just too painful and recovering from problems is a full time job I do not want to have. You can replace gigabytes of cruft with this small script that just manually synchronizes users from a master machine.
#!/usr/bin/bash # Chris X Edwards - 2018-07-19 # == Concept # This script is designed to maintain /etc/passwd files on many # hosts such that the system (UID<1000) accounts are left as is # but the user accounts (1000<UID<65534) are populated from a # different password file (the master file). The idea is to avoid # LDAP or FreeIPA and just manipulate the passwd file entries # directly from a master source. # == Usage # ***This script is run on the host to change.*** # ${PATH}/pwclone <saved-passwd-master-file # or (pull) # ssh masterpw.example.edu cat /etc/passwd | ${PATH}/pwclone # or (push) # ssh clientpw.example.edu ${PATH}/pwclone </etc/passwd # # This script takes standard input so that it can be more easily # used remotely. You must pipe the master file to this script which # will modify the local /etc/passwd file based on the master's user # (but not system) entries. # # This is where the password file lives. It should be in the standard # place. Change to do testing. PWFILE=/etc/passwd #PWFILE=/root/pwclone/passwd-test # == Possible Problems # ***Make sure your master passwd file is not shadowed!!!*** # # Note that if someone on a client machine makes a change to this # file by changing their entry with the `passwd` command, running # this script will confusingly overwrite that change. One solution # is to do something like this to disable the local passwd command. # mv /usr/bin/passwd /usr/bin/passwd.local # NOTE='Log in to master.example.edu to make password changes.' # echo '#!/usr/bin/bash'$'\n'echo \"${NOTE}\" > /usr/bin/passwd # == Must be run as root/sudo # Fail nicely if this was run by a regular user without sudo. (( $EUID != 0 )) && echo "UID 0 (root) required. Try running with sudo." && exit # == Check and disable shadow if necessary # Check to see if this system is using the shadow system. # If so, there will be a shadow file (if not, none). # If there is a shadow system, it must be turned off _temporarily_. # If there is not a shadow system, it should remain that way. SHADOWPATH=/etc/shadow if [ -f ${SHADOWPATH} ]; then echo "Shadow password file detected at ${SHADOWPATH}" echo "Temporarily disabling shadow..." SHADOWCMD="pwunconv" else # Do nothing special. Ready to go. SHADOWCMD="" fi ${SHADOWCMD} # == MERGE # Merge user entries from master with system entries from current local. TEMPFILE=$(mktemp --tmpdir=/tmp pwclone.tmp.XXXXX) cat <(awk -F: '$3<1000 || $1=="nfsnobody"' ${PWFILE}) \ <(awk -F: '$3>=1000 && $1!="nfsnobody"' - ) \ | sort -n -t: -k3 > ${TEMPFILE} echo "Updating live ${PWFILE}..." mv ${TEMPFILE} ${PWFILE} # == Password file must be readable # If these permissions aren't right, then you can't look up names to UIDs. chmod 644 ${PWFILE} # == Restore shadow if necessary # If it was shadow before, restore it now. [ -n "${SHADOWCMD}" ] && echo "Restoring shadow..." && pwconv
To disable LDAP so that you can start using straightforward local password hashes use this command.
authconfig --disableldapauth --disableldap --enableshadow --updateall
OVERVIEW
LDAP stands for Lightweight Directory Access Protocol (see Glossary). A "directory" in this technical sense is like a database with the distinction that it is optimized to extract data rather than receive it. Normal databases tend to be more symmetrical in this respect. Directories are useful when the required task involves far more look ups than edits or record insertions.
Originally the prototypical "directory" was a large company’s phone directory but the more typical use now is a centralized collection of an organization’s user and infrastructure data, importantly including a centralized repository for user authentication information. In practical terms, if an organization has 100 machines and 10 users who are allowed to use all of them, only 10 centralized records are needed. Traditionally, each machine would need a separate lists of all 10 users. If a user changed his password or other information on one of the machines, in the simple approach, 99 other machines would have to be manually updated. Clearly synchronization is a strong feature of LDAP.
With LDAP authentication, when attempts to log into an LDAP enabled
host, the host does not (necessarily) need to check the
/etc/passwd
file but instead contacts the LDAP server specified in
its configuration. The host invokes LDAP client libraries which
contact the LDAP server. The host tells the server which username was
selected and provides a hash of the password the user gave. The LDAP
server then consults its directory and decides if that user and hash
are correct and if so, it tells the client to accept the user as
authenticated.
Clearly sending hashes of valid passwords over the network to a central location is sensitive business so an LDAP setup that does not use end to end encryption is not really a functional setup. Establishing the correct encryption techniques and testing their functionality is a big part of LDAP configuration management.
SERVER SETUP
CentOS 7 free-ipa
Well LDAP is such a PITA and apparently I wasn’t the only one to notice. It looks like Red Hat or somebody has spearheaded a big fancy dummy proof version called freeipa. I discuss it below, but I have confirmed that it does work on two CentOS 7 machines in March 2018.
So this is all getting to be ridiculous. So much so that getting all the parts to talk to each other correctly is extremely challenging thanks to the combinatoric explosion of possibilities (OpenSSL or GNUTLS? Port 636 or 398? sssd or nslcd?) Red Hat seems to have noticed this and, trying hard to compete with Active Directory, they’ve come up with a thing called "Red Hat Identity Management (IdM)" which "provides a centralized and unified way to manage identity stores, authentication, policies, and authorization policies in a Linux-based domain." IdM Documentation
There seems to be a free project called free-ipa. Here is its website.
This guide to installing Free-IPA seems ok. After following these instructions on a pristine install of CentOS 7 it pulled in 300 or so dependencies (no kidding) and then asked me a lot of questions eventually coming out with something like this.
The IPA Master Server will be configured with:
Hostname: auth-alab.ucex.edu
IP address(es): 172.99.99.07
Domain name: auth-alab.ucex.edu
Realm name: AUTH-ALAB.UCEX.EDU
Then the installer did some major BTC mining (or something) as it went through a 1000 step setup script. It finally spit out some more instructions that it might be wise to note.
Next steps:
1. You must make sure these network ports are open:
TCP Ports:
* 80, 443: HTTP/HTTPS
* 389, 636: LDAP/LDAPS
* 88, 464: kerberos
UDP Ports:
* 88, 464: kerberos
* 123: ntp
2. You can now obtain a kerberos ticket using the command: 'kinit admin'
This ticket will allow you to use the IPA tools (e.g., ipa user-add)
and the web user interface.
Be sure to back up the CA certificates stored in /root/cacert.p12
These files are required to create replicas. The password for these
files is the Directory Manager password
How about this for those firewall changes?
firewall-cmd --permanent --add-service=ntp
firewall-cmd --permanent --add-service=http
firewall-cmd --permanent --add-service=https
firewall-cmd --permanent --add-service=ldap
firewall-cmd --permanent --add-service=ldaps
firewall-cmd --permanent --add-service=kerberos
firewall-cmd --permanent --add-service=kpasswd
Rebooting was required, but after I did that, I was able to go to https://auth-alab.ucex.edu in a browser. The certificates complained but screw that. Approving the exception shows that this certificate expires in 2 years (convenient!). Mine (SHA1) ends in 99:88.
See below for client setup.
Troubleshooting free-ipa
I’m a bit nervous about Free-IPA. The lack of a sensible way to back up and restore the system is frightening (basically the risk of losing everyone’s passwords). And then then I sometimes find some randomly flaky behavior. Sometimes the rube goldberg machine just stops working. Here are some things I turned on to get it working again.
In no particular order.
systemctl restart httpd.service
systemctl restart rngd
systemctl restart dirsrv.target
systemctl restart httpd
systemctl restart sssd
systemctl restart dirsrv.target
systemctl restart krb5kdc
systemctl restart kadmin
systemctl restart pki-tomcatd.target
Maybe check for status first to see what’s up and what’s not. These hints taken from here.
CentOS 7 Server
Note that
this Red Hat document says that openldap-server
is
deprecated. That’s ominous. They say use "Identity Management in
RHEL". This is a good time to become aware of
FreeIPA.
Or how about one that addresses the problem with secure TLS connections using port 636. And another.
First make sure to yum install
these.
-
openldap
-
compat-openldap
-
openldap-clients
-
openldap-servers
-
openldap-servers-sql
-
openldap-devel
systemctl start slapd.service systemctl enable slapd.service
Check that the server started up.
netstat -antup | grep -i 389
Note this is not the secure port which is 636.
Set a password for the LDAP root.
slappasswd
It will spit out a salted hash which needs to be noted somewhere for use in future steps.
Set up the database by making an ldif file containing this. I put all of these
in /root
but they can go anywhere sensible.
dn: olcDatabase={2}hdb,cn=config
changetype: modify
replace: olcSuffix
olcSuffix: dc=alab,dc=ucex,dc=edu
dn: olcDatabase={2}hdb,cn=config
changetype: modify
replace: olcRootDN
olcRootDN: cn=ldapadm,dc=alab,dc=ucex,dc=edu
dn: olcDatabase={2}hdb,cn=config
changetype: modify
replace: olcRootPW
olcRootPW: {SSHA}U9999Z/f+P9999N+k99999+X9999999p
Apply this file with this.
ldapmodify -Y EXTERNAL -H ldapi:/// -f ~/db.ldif
Then the same with this which will limit monitor access to ldapadm which seems reasonable.
dn: olcDatabase={1}monitor,cn=config
changetype: modify
replace: olcAccess
olcAccess: {0}to * by dn.base="gidNumber=0+uidNumber=0,cn=peercred,cn=external, cn=auth" read by dn.base="cn=ldapadm,dc=alab,dc=ucex,dc=edu" read by * none
Apply it.
ldapmodify -Y EXTERNAL -H ldapi:/// -f ~/monitor.ldif
Now create a self-signed certificate.
#!/bin/bash openssl req -new -x509 -nodes -out \ /etc/openldap/certs/myldap.alab.ucex.edu.cert \ -keyout /etc/openldap/certs/myldap.alab.ucex.edu.key \ -days 365
Or look at this method which uses make files that are indeed on CentOS7 ready to go.
And make sure it’s owned by user ldap
which should exist if
everything is installed and running.
# chown ldap:ldap /etc/openldap/certs/myldap.alab.ucex.edu.cert
# chown ldap:ldap /etc/openldap/certs/myldap.alab.ucex.edu.key
Create this LDIF to configure the system to use these.
Rdn: cn=config changetype: modify replace: olcTLSCertificateFile olcTLSCertificateFile: /etc/openldap/certs/myldap.alab.ucex.edu.cert dn: cn=config changetype: modify replace: olcTLSCertificateKeyFile olcTLSCertificateKeyFile: /etc/openldap/certs/myldap.alab.ucex.edu.key
Load this setting as before.
ldapmodify -Y EXTERNAL -H ldapi:/// -f ~/certs.ldif
Try the following diagnostic command.
# slaptest -u
It should produce this.
config file testing succeeded
Copy this template into the production place.
cp /usr/share/openldap-servers/DB_CONFIG.example /var/lib/ldap/DB_CONFIG
Everything but that file should be owned correctly, but just to be sure might as well hit everything.
chown ldap:ldap /var/lib/ldap/*
Now add the normal LDAP schemas which are helpfully provided.
ldapadd -Y EXTERNAL -H ldapi:/// -f /etc/openldap/schema/cosine.ldif
ldapadd -Y EXTERNAL -H ldapi:/// -f /etc/openldap/schema/nis.ldif
ldapadd -Y EXTERNAL -H ldapi:/// -f /etc/openldap/schema/inetorgperson.ldif
Create the main layout for the normal application (user log in).
dn: dc=alab,dc=ucex,dc=edu
dc: alab
objectClass: top
objectClass: domain
dn: cn=ldapadm,dc=alab,dc=ucex,dc=edu
objectClass: organizationalRole
cn: ldapadm
description: LDAP Manager
dn: ou=People,dc=alab,dc=ucex,dc=edu
objectClass: organizationalUnit
ou: People
dn: ou=Group,dc=alab,dc=ucex,dc=edu
objectClass: organizationalUnit
ou: Group
Now apply that file with this.
ldapadd -x -W -D "cn=ldapadm,dc=alab,dc=ucex,dc=edu" -f ~/base.ldif
It will prompt for the password that goes with the hash generated previously. It should then spit out these success messages.
adding new entry "dc=alab,dc=ucex,dc=edu"
adding new entry "cn=ldapadm,dc=alab,dc=ucex,dc=edu"
adding new entry "ou=People,dc=alab,dc=ucex,dc=edu"
adding new entry "ou=Group,dc=alab,dc=ucex,dc=edu"
Now normal ldif users can be added and used.
Having firewall annoyances? Or maybe just fending off the inevitable…
firewall-cmd --permanent --add-service=ldap
firewall-cmd --permanent --add-service=ldaps
firewall-cmd --reload
Make sure the ones you need come back with success
.
Changing Root Password
Perhaps you started with a terrible password for testing.
Start the process by creating this LDIF.
dn: olcDatabase={0}config,cn=config
changetype: modify
add: olcRootPW
olcRootPW: {SSHA}kT2***Obtain_from_slappasswd***
Then run this.
ldapadd -Y EXTERNAL -H ldapi:/// -f passwd4dn.ldif
OpenLDAP From Source
First you need to get it. Best to go to OpenLDAP’s official home. Then you can find something like this for version 2.4.33.
To check to see what version you may already have try:
$ /usr/local/libexec/slapd -V
@(#) $OpenLDAP: slapd 2.4.32 (Sep 28 2012 12:53:47) $
xed@sad.xed.ch:/usr/local/src/ldap/openldap-2.4.32/servers/slapd
None of the packages for the distros are well-behaved. For this reason and because I’m not keen to get locked into a particular fragile distribution where the service works, I am trying to install from the latest sources and configure it generically.
The first problem is that OpenLDAP doesn’t put things neatly where they would go if they were integrated packages. Of course this may be helpful if you need to clear out an old OpenLDAP installation. I had to do things like:
$ cd /etc/openldap; sudo ln -s /usr/local/etc/openldap/schema
$ cd /var/lib; sudo ln -s /usr/local/var/openldap-data
$ sudo mkdir /var/run/slapd
Most of the stuff is in /usr/local
by default.
Also you need to put a blank file in the db backend configuration directory or it will complain:
$ sudo touch /var/openldap-data/DB_CONFIG
Server Configuration File
The OpenLDAP server can be configured in two ways. The first and the one I’ve been using is with a static configuration file. This file is sourced when the daemon starts and its settings are applied at that time.
include /etc/ldap/schema/core.schema
include /etc/ldap/schema/cosine.schema
include /etc/ldap/schema/inetorgperson.schema
include /etc/ldap/schema/nis.schema
# SECURITY
access to attrs=userPassword
by self write
by anonymous auth
by dn.base="cn=ldapadmin,dc=alab,dc=ucex,dc=edu" write
by * none
access to *
by self write
by dn.base="cn=ldapadmin,dc=alab,dc=ucex,dc=edu" write
by * read
# DON'T bother with ARGS file unless you feel strongly
# slapd scripts stop scripts need this to work
pidfile /var/run/slapd/slapd.pid
# enable a lot of logging - we might need it
# but generates huge logs
#loglevel -1
# MODULELOAD definitions
# not required (comment out) before version 2.3
moduleload back_bdb.la
# TLS-enabled connections
TLSCACertificateFile /etc/ldap/ldapscert.pem
TLSCertificateFile /etc/ldap/ldapscert.pem
TLSCertificateKeyFile /etc/ldap/ldapskey.pem
database bdb
suffix "dc=alab,dc=ucex,dc=edu"
# root or superuser
rootdn "cn=ldapadmin,dc=alab,dc=ucex,dc=edu"
# Apparently the password is plaintext here. Protect well!
rootpw SecretStuff
# The database directory MUST exist prior to running slapd AND
# change path as necessary
directory /var/lib/ldap
# Indices to maintain for this directory
# unique id so equality match only
index uid pres,eq
# allows general searching on commonname, etc
index cn,sn pres,eq,approx,sub
# if searches will include objectClass uncomment following
index objectClass eq
# index objectClass eq
# shows use of default index parameter
index default eq,sub
# other database parameters
# read more in slapd.conf reference section
cachesize 10000
checkpoint 128 15
Might want to sudo chmod 600 /etc/ldap/slapd.conf
because of the
password in there.
The other way to configure OpenLDAP is to store the configuration information in a directory that the LDAP server manages. Besides being a bit sketchy to configure a server with that running server, I found that some init scripts weren’t flexible with one’s choice of configuration strategies. The upside, in theory, to this strategy is that configuration settings can be adjusted in real time as the server runs and the new settings are applied immediately without any interruption.
Starting Server
Now the server can be started up. This is where it is possible to
specify where the config file is. Also you can add some logging output
(try slapd -d?
for logging options).
$ sudo slapd -f /etc/ldap/slapd.conf -d1023 -h "ldaps://"
Or this is more comprehensive:
$ sudo /usr/local/libexec/slapd -f /etc/openldap/slapd.conf -d10 -h "ldaps:// ldapi:///"
The d
option has logging levels.
Adding Records
Now the server is running and you can prepare LDIFs to populate it. Here’s an LDIF that prepares the base of the tree, the admin account, the users list, and the groups list.
dn: dc=alab,dc=ucex,dc=edu
objectClass: dcObject
objectclass: organization
o: alab.ucex.edu
dc: alab
description: The SysAdmin Lab Root
dn: cn=ldapadmin,dc=alab,dc=ucex,dc=edu
objectClass: simpleSecurityObject
objectClass: organizationalRole
cn: ldapadmin
userPassword: SecretStuff
description: LDAP administrator
dn: ou=users,dc=alab,dc=ucex,dc=edu
objectClass: top
objectClass: organizationalUnit
ou: users
description: The SysAdmin Lab User List
dn: ou=groups,dc=alab,dc=ucex,dc=edu
objectClass: organizationalUnit
ou: groups
This can be added with:
$ sudo ldapadd -x -D cn=ldapadmin,dc=alab,dc=ucex,dc=edu -W -f new.ldif
Here’s a sample LDIF that includes a couple of groups and a comprehensive entry for a user. .u+g.ldif
dn: cn=alab,ou=groups,dc=alab,dc=ucex,dc=edu
objectClass: posixGroup
cn: alab
gidNumber: 10000
dn: cn=alabadmin,ou=groups,dc=alab,dc=ucex,dc=edu
objectClass: posixGroup
cn: alabadmin
gidNumber: 10001
# LDIF for Chris X Edwards
dn: uid=xed,ou=users,dc=alab,dc=ucex,dc=edu
objectClass: top
objectClass: posixAccount
objectclass: person
objectclass: organizationalPerson
objectclass: inetOrgPerson
uid: xed
givenName: Chris
sn: Edwards
cn: Chris X Edwards
cn: Chris Edwards
o: SysAdmin Lab
o: El Xavier Supercomputer Center
o: School of Pharmacy
o: UCEX
ou: users
userPassword: {SSHA}bozJBRxxxxxxxxxxxxxxxxxxx5e81J5g
uidNumber: 1000
gidNumber: 1001
roomNumber: 345E
gecos: Chris X Edwards,,,,
l: El Xavier
st: CA
employeeType: staff
telephoneNumber: Korea95
mail: cxedwards@ucex.edu
mail: chris@xed.ch
loginShell: /bin/bash
homeDirectory: /home/xed
labeledURI: http://xed.name/job Chris' work web page
description: An affable fellow.
This can be added with:
$ sudo ldapadd -x -D cn=ldapadmin,dc=alab,dc=ucex,dc=edu -W -f u+g.ldif
You can test to see if that all worked well with this:
$ sudo ldapsearch -x -D cn=ldapadmin,dc=alab,dc=ucex,dc=edu \
-W -b ou=users,dc=alab,dc=ucex,dc=edu 'uid=xed'
Some more examples of populating users: First add the users ou:
$ sudo ldapadd -x -D cn=ldapadmin,dc=alab,dc=ucex,dc=edu -W -f users.ldif
dn: ou=users,dc=alab,dc=ucex,dc=edu
objectClass: top
objectClass: organizationalUnit
ou: users
description: The SysAdmin Lab User List
Now you can add users:
$ sudo ldapadd -x -D cn=ldapadmin,dc=alab,dc=ucex,dc=edu -W -f xed.ldif
# LDIF for Chris X Edwards
dn: uid=xed,ou=users,dc=alab,dc=ucex,dc=edu
objectClass: top
objectClass: posixAccount
objectclass: person
objectclass: organizationalPerson
objectclass: inetOrgPerson
uid: xed
givenName: Chris
sn: Edwards
cn: Chris X Edwards
cn: Chris Edwards
o: SysAdmin Lab
o: El Xavier Supercomputer Center
o: School of Pharmacy
o: UCEX
ou: users
userPassword: {SSHA}LbwKeFxxxxxxxxxxxxxxxxxxxI9x4uKK
uidNumber: 1000
gidNumber: 1001
roomNumber: 345E
gecos: Chris X Edwards,,,,
l: El Xavier
st: CA
employeeType: staff
telephoneNumber: 6195673295
mail: cxedwards@ucex.edu
mail: chris@xed.ch
loginShell: /bin/bash
homeDirectory: /home/xed
labeledURI: http://xed.name/job Chris' work web page
description: An affable fellow.
Ubuntu 9.10 Using /etc/ldap/slapd.conf
This is the traditional way to configure an OpenLDAP server using a straight forward configuration file. The main problem with this approach is that Ubuntu 9.10 wants to move on to using the directory based configuration system. This means that the start up scripts (/etc/init.d/slapd) won’t work and the server has to be started manually. Another problem is that perhaps in a few years OpenLDAP will cut off this way of configuration.
First of all OpenLDAP needs to be present. Turns out that it’s almost impossible to compile it from source because of the mystical BerkeleyDB requirement. It’s ok then to just use the Ubuntu binary installed in the normal way.
$ sudo apt-get install -y slapd ldapscripts python-ldap
Now that it’s installed, it’s probably running and this is actually not what you want. So stop it.
$ sudo /etc/init.d/slapd stop
Also you need to put a blank file in the db backend configuration directory or it will complain:
$ sudo touch /var/lib/ldap/DB_CONFIG
slapd Init Script
Here is a script I wrote to start, restart, and stop the LDAP server running on Ubuntu 9.10.
#!/bin/bash
### BEGIN INIT INFO
# Provides: xed_slapd
# Required-Start: $remote_fs $network $syslog
# Required-Stop: $remote_fs $network $syslog
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: OpenLDAP standalone server with old slapd.conf config.
### END INIT INFO
function starter {
if [ -e /var/run/slapd/slapd.pid ]
then
echo "There exists a /var/run/slapd/slapd.pid:"
cat /var/run/slapd/slapd.pid
echo "Removing old slapd.pid."
restarter
else
echo "Starting LDAP server"
# Include -d768 (or whatever) for debugging on console.
# Otherwise it goes to background.
slapd -f /etc/ldap/slapd.conf -h "ldaps:// ldapi:///"
if [ -e /var/run/slapd/slapd.pid ]
then
echo -n "Server started on: "
cat /var/run/slapd/slapd.pid
else
echo "PROBLEM STARTING SERVER! No PID file."
fi
fi
} # End function starter.
function stopper {
PIDF=/var/run/slapd/slapd.pid
if [ -e $PIDF ]
then
PID=`cat $PIDF`
if kill -9 "$PID" && rm "$PIDF"
then
echo "Killed $PID and removed: $PIDF"
else
echo "Something is wrong with the PID file. Or maybe you need to use sudo."
echo "$PIDF contains: $PID"
exit
fi
else
echo "Can not find pid file. Checking processes:"
if ps -ef | grep "[0-9] slapd" >/dev/null
then
echo "There is no pid file at $PIDF"
echo,"but a slapd process is running:"
ps -ef | grep "[0-9] slapd"
echo "You should kill that manually."
fi
exit
fi
} # End function stopper.
function restarter {
stopper
starter
} # End function restarter.
function statuser {
PIDF=/var/run/slapd/slapd.pid
if [ -e $PIDF ]
then
echo -n "There is a PID file ($PIDF) containing: "
cat $PIDF
ps -ef | grep "[0-9] slapd"
nmap -p 636,389 127.0.0.1 | grep /tcp
else
echo "Can not find pid file. Checking processes:"
if ps -ef | grep "[0-9] slapd" >/dev/null
then
echo "There is no pid file at $PIDF"
echo,"but a slapd process is running:"
ps -ef | grep "[0-9] slapd"
fi
exit
fi
} # End function statuser.
if [ "$1" == "start" ]; then starter; exit; fi
if [ "$1" == "stop" ]; then stopper; exit; fi
if [ "$1" == "restart" ]; then restarter; exit; fi
if [ "$1" == "status" ]; then statuser; exit; fi
echo "Usage: slapd_start {start|stop|restart}"
exit
LDAP on Ubuntu 9.10 Using /etc/ldap/slapd.d
This is the "new" way to configure slapd which involves configuring the LDAP server by storing the configuration information in the LDAP server. Let’s repeat that for clarity: use slapd to configure slapd. Obviously this invites some chicken and egg problems. Also there is not as much reasonable information on-line about how to use this kind of configuration system. The Ubuntu start up scripts (/etc/init.d/slapd) uses this system.
Install LDAP related packages.
Note that server runs immediately upon installation. Start by adding the necessary schemas to the directory:
Note that the password is in plain text here. Best use:
$ slappasswd -h {SSHA}
And fix that. This can be done later with ldapmodify.
Create the following ldif files.
sudo apt-get install -y slapd ldapscripts python-ldap
sudo dpkg-reconfigure slapd
sudo ldapadd -Y EXTERNAL -H ldapi:/// -f /etc/ldap/schema/cosine.ldif
sudo ldapadd -Y EXTERNAL -H ldapi:/// -f /etc/ldap/schema/inetorgperson.ldif
sudo ldapadd -Y EXTERNAL -H ldapi:/// -f /etc/ldap/schema/nis.ldif
sudo ldapadd -Y EXTERNAL -H ldapi:/// <<EOF1
dn: cn=module,cn=config
objectClass: olcModuleList
cn: module
olcModulepath: /usr/lib/ldap
olcModuleload: back_hdb
EOF1
sudo ldapadd -Y EXTERNAL -H ldapi:/// <<EOF2
dn: olcDatabase=hdb,cn=config
objectClass: olcDatabaseConfig
objectClass: olcHdbConfig
olcDatabase: hdb
olcSuffix: dc=alab,dc=ucex,dc=edu
olcDbDirectory: /var/lib/ldap
olcRootDN: cn=ldapadmin,dc=alab,dc=ucex,dc=edu
olcRootPW: xxxxxxxxxxxxxxxxxx
olcDbIndex: uid pres,eq
olcDbIndex: cn,sn pres,eq,approx,sub
olcDbIndex: objectClass eq
olcAccess: to attrs=userPassword
by self write
by anonymous auth
by dn.base="cn=ldapadmin,dc=alab,dc=ucex,dc=edu" write
by * none
olcAccess: to *
by self write
by dn.base="cn=ldapadmin,dc=alab,dc=ucex,dc=edu" write
by * read
EOF2
Note that there is sometimes confusing syntax in examples one can correct order of option execution. database?). The special frontend database = {-1}, and the config Or something like that.
Check your work.
$ sudo slapcat
Should show you everything above as the server knows it. If this produces this warning:
hdb_db_open: warning - no DB_CONFIG file found in directory /var/lib/ldap: (2).
Expect poor performance for suffix "dc=alab,dc=ucex,dc=edu".
Then just:
$ sudo touch /var/lib/ldap/DB_CONFIG
and
$ sudo slapcat
again a couple of times.
Gentoo OpenLDAP Server
This is my attempt to get a Gentoo server working as an LDAP server
using emerge
and the full Gentoo way.
echo 'net-nds/openldap -gdbm berkdb' >> /etc/portage/package.use
/etc/init.d/slapd start
/etc/openldap/slapd.conf
←-- Gentoo
/etc/conf.d/slapd
←-- Gentoo
/usr/lib/openldap/slapd
←-- Gentoo executable lives here
slapd.d configuration directory tree
/etc/openldap/slapd.d - This is the place that the alternate configuration style is specified. It is generated using this command:
sudo slaptest -f slapd.conf -F slapd.d
Seems Ubuntu uses this by default.
The problem is that the /etc/init.d/slapd
mechanism doesn’t use the
-F <dirname> but rather the old -f <slapd.conf>. Don’t know how
important it is to make the config file LDAPable.
Managing Accounts With ACL
Maybe you can use Access Control Lists to control things. Here’s a rough outline of an example to stimulate creativity.
In this example organizationalStatus=0
means active:
access to
attrs=userPassword
filter=(&(objectClass=inetOrgPerson)(!(organizationalStatus=0)))
by group="cn=Admins,ou=Groups,ou=example" =wx
by group="cn=Replicas,ou=Groups,ou=example" read
by * none
access to
attrs=userPassword
filter=(&(objectClass=inetOrgPerson)(organizationalStatus=0))
by group="cn=Admins,ou=Groups,ou=example" =swx
by group="cn=Replicas,ou=Groups,ou=example" read
by self =wx
by * =x
CLIENT SETUP
CentOS 7 free-ipa
Here is the client setup guide for using the free-ipa system.
The system seems to be very fussy about authentic FQDN (domain names). If you don’t have such a setup, well, that could be problematic.
host xed-ablab.ucsd.edu
cat /etc/hostname
sudo yum update
Once everything is prepared for installation, installing is pretty easy.
sudo yum install freeipa-client
sudo ipa-client-install --force-ntpd
I did the --force-ntpd
to suppress a warning and it seemed like the
way I would want to do things anyway. When answering questions, it
asks for the domain name of the server but I gave it the actual
hostname. This means that if you have a tld of thebig.com and your
server is at ipa-mygroup.thebig.com, then having failovers muck with
thebig.com might be messy. What they’re envisioning, and I am an
enthusiastic supporter of doing it this correct way, is something like
ipa.mygroup.thebig.com which would allow you to have
mygroup.thebig.com be the domain (which won’t mess with higher level
thebig.com business) and ipa be the host in that domain. C’est la vie.
Once it all completes, you can check to see if it’s working. Here I
check the password list generally. This should not contain nemo
, my
test user that only the ipa server knows about. Then I specify nemo
and if I get back the uid and not an error, we know that the client
has received that information from the ipa server. Yea!
getent passwd
getent passwd nemo
ssh -l nemo localhost
Finally try logging in. There will be a password harangue and the weirdest thing to me is that the password has a minimum change default of 1 hour. The maximum of 90 days is totally ridiculous. I changed it to 730 (2 years) by going to Policy→Password_Policies→Max_lifetime on the server control.
CentOS 7 Cleint Setup
Install necessary things.
# yum install openldap-clients nss-pam-ldapd
Do the authconfig. Note I also used an IP address for the ldapserver
.
# authconfig --enableldap --enableldapauth --ldapserver=alab.ucex.edu --ldapbasedn="dc=ucex,dc=edu" --enablemkhomedir --update
Previous attempt…
Client LDAP partially working:
# yum install pam_ldap nss-pam-ldapd nscd
# yum erase sssd-client
# authconfig --enableldap --enableldapauth --ldapserver=ldaps://172.99.99.117 --ldapbasedn="dc=alab,dc=ucex,dc=edu" --enablelocauthorize --enablesysnetauth --updateall
After running that, getent passwd
and id ${USER}
worked.
CentOS 6 Client Setup
Everything was working great in CentOS 5 and then 6 comes along and
LDAP is completely a show stopper. It turns out that the main reason
for this is that the way the distro is organized to deal with topics
like authentication has completely changed. CentOS (and obviously a
well-known upstream vendor) decided to add SSSD or System Security
Services Daemon. This was intended to simplify some things in some
situations but for my set up it just cause a complete failure. To
learn more about sssd
you might want to look over
the SSSD FAQ.
A good diagnostic to run on a clean system is:
authconfig --test
See what’s going on there.
The first and obvious step is probably to install the packages pertinent to LDAP client behavior:
yum install openldap-clients
yum install pam_ldap
Maybe even:
sudo yum install openldap nss-pam-ldapd openldap-clients pam-ldap nscd
Some people believe a step like this is necessary:
authconfig --enableldap --enableldapauth --ldapserver=ldap-alab.ucex.edu --ldapbasedn="dc=alab,dc=ucex,dc=edu" --update
Or, try this:
authconfig --enableldap --enableldapauth --ldapserver=ldaps://ldap-alab.ucex.edu --ldapbasedn="dc=alab,dc=ucex,dc=edu" --enableldaptls --enablelocauthorize --enablesysnetauth --updateall
Or try this which really works:
authconfig --enableldap --enableldapauth --ldapserver=ldaps://ldap-alab.ucex.edu --ldapbasedn="dc=alab,dc=ucex,dc=edu" --enablelocauthorize --enablesysnetauth --updateall
Note the --enableldaptls
option should not be in here now.
Amazingly this causes it to not authenticate the first time you
enter the password; it authenticates on the second attempt! How messed
up is that?
I did that step but I’m not 100% sure if it was absolutely necessary.
I don’t think it was necessary for the ldapsearch
command that
worked.
What if SELinux or an iptables firewall is in the way? Disable them and get things working. Later you can put them back carefully.
service iptables stop
setenforce 0
Edited my /etc/openldap/ldap.conf
to be this:
BASE dc=alab,dc=ucex,dc=edu
URI ldap://ldap-alab.ucex.edu/
ldap_version 3
rootbinddn cn=ldapadmin,dc=alab,dc=ucex,dc=edu
timelimit 30
bind_timelimit 30
idle_timelimit 30
s_initgroups_ignoreusers root,ldap,named,avahi,haldaemon,dbus,radvd,tomcat,radiusd,news,mailman,nscd,gdm
TLS_REQCERT never
TLS_CACERT /etc/openldap/cacerts/ldapscert.pem
pam_password md5
Put the TLS cert in the places specified by TLS_REQCERT
.
Here’s a way to test LDAP server receptiveness:
ldapsearch -x -H ldaps://ldap-alab.example.edu -b dc=alab,dc=ucex,dc=edu
THIS WORKED!
However, id user
did not.
Maybe something called "nslcd" is needed. Apparently this package provides for it:
yum install nss-pam-ldapd
It also installs nscd
as a dependency.
Edit the /etc/nslcd.conf
to be something like this:
uri ldaps://ldap-alab.ucex.edu
ldap_version 3
rootpwmoddn cn=ldapadmin,dc=alab,dc=ucex,dc=edu
bind_timelimit 30
timelimit 30
idle_timelimit 30
tls_reqcert never
tls_cacertdir /etc/openldap/cacerts/
tls_cacertfile /etc/openldap/cacerts/ldapscert.pem
uid nslcd
gid ldap
uri ldaps://ldap-alab.ucex.edu
base dc=alab,dc=ucex,dc=edu
tls_cacertdir /etc/openldap/cacerts
It does seem that this file is the one that causes trouble. Even when
I can get a clean connection and the user database can be dumped with
ldapsearch
, the id
and getent
commands don’t work. Here is what
eventually worked for me on CentOS 6.4.
ldap_version 3
rootpwmoddn cn=ldapadmin,dc=alab,dc=ucex,dc=edu
bind_timelimit 30
timelimit 30
idle_timelimit 30
tls_reqcert never
tls_cacertdir /etc/openldap/cacerts
tls_cacertfile /etc/openldap/certs/ldapscert.pem
uid nslcd
gid ldap
uri ldaps://ldap-alab.ucex.edu
base dc=alab,dc=ucex,dc=edu
ssl no
Don’t forget to run the
authconfig --enableldap --enableldapauth \
--ldapserver=ldaps://ldap-alab.ucex.edu \
--ldapbasedn="dc=alab,dc=ucex,dc=edu" --enablelocauthorize \
--enablesysnetauth --updateall
Now I was able reduce this command to:
authconfig --enableldap --enableldapauth --enablesysnetauth --updateall
This allowed a system where ldapsearch
worked but not id ${USER}
t start working.
Note
|
The tls_cacertfile and tls_cacertdir look suspicious but
that’s what worked. My dir was really /etc/openldap/certs . The other
was empty. Now I’m just doing ln -s certs cacerts and skipping any
problems like that. |
Warning
|
If you use ssl start_tls in this configuration file then it
will not work and you’ll get an error: err=1 text=TLS already started
Hmm. It seems that the authconfig command puts this incorrect
option back in the config file. You must make sure it is not there. I
took out the --enableldapstarttls option which then keeps the
authconfig from adding that line. Then you must service nslcd
restart to get that working right and then it works. |
Now fire that up with:
service nslcd start
And now keep an eye on tail -f /var/log/debug
and try id user
and
see if any action happens.
WORKS! Holy shit!
Trying to repeat this on a fresh install of Server CentOS 6.2 it didn’t work. I noticed that there was some messy stuff with sssd which was not present when things worked. So I got rid of it:
yum erase sssd
And then it seemed to make contact with the ldap-server (or try). Still not working though.
CentOS 5 Client Setup
-
Have LDAP client packages installed:
sudo yum install openldap openldap_clients nss-ldap
-
Make sure there’s a
/etc/openldap
directory. -
Make sure there’s a
ldapscert.pem
in/etc/openldap/cacerts/
. This will look a bit like this:-----BEGIN CERTIFICATE----- MIIEjQPPN3FtNjVONtVWNYFcf0KH5f3EMA0GCSqGSIb3DQEBODHNZVTXZDswCQYD <22 lines removed for brevity> KVIv7twCP6zCdXFFb8Lh0IxschXizn/qe9lPP2aDuVO3VeNFf1SMgGYN2lcL+vC0 bnjgoriYrh0m6fUl8l3Guj== -----END CERTIFICATE-----
-
Run
authconfig
to set where the LDAP server is: authconfig --enableldap --enableldapauth --enableldaptls --ldapserver=ldap-alab.ucex.edu --update -
Make an
/etc/ldap.conf
that looks like this:base dc=alab,dc=ucex,dc=edu uri ldaps://ldap-alab.ucex.edu/ ldap_version 3 rootbinddn cn=ldapadmin,dc=alab,dc=ucex,dc=edu timelimit 30 bind_timelimit 30 idle_timelimit 3600 nss_initgroups_ignoreusers root,ldap,named,avahi,haldaemon,dbus,radvd,tomcat,radiusd,news,mailman,nscd,gdm TLS_REQCERT never TLS_CACERT /etc/openldap/cacerts/ldapscert.pem pam_password md5
-
I think that different things look for this in different places. So make it available everywhere like this:
rm -f /etc/openldap/ldap.conf ; ln -s /etc/ldap.conf /etc/openldap/
-
Then
/etc/nsswitch.conf
needs to be set with something sensible like:passwd: files ldap shadow: files ldap group: files ldap
Ubuntu LDAP Client Setup
Install the client stuff:
$ sudo apt-get install libnss-ldap
This installs these packages too:
auth-client-config ldap-auth-client ldap-auth-config libpam-ldap
Maybe consider the nscd
package.
Upon installation, configuration questions will be asked that will help set
things up.
You can redo this (and some more) with:
$ sudo dpkg-reconfigure ldap-auth-config
First thing is the URI of the LDAP server:
ldap://abagyan-athena.ucex.edu:389/
- ldapi
-
LDAP over IPC (for local machines?)
- ldaps
-
LDAP over SSL (port 636)
- ldap
-
I think this is the right one for TLS. Not 100% sure.
Next is the ldap-auth-config dn of the LDAP search base.
ou=users,dc=alab,dc=ucex,dc=edu
Next the version, why not:
3
Make local root Database admin:
Probably ok for simple things, but no generally (central admin) Does LDAP database require login? I guess this is about the ACL setup. I think in normal cases, anyone can try their luck authenticating and so it’s a:
No
LDAP account for root (bind dn):
cn=ldapadmin,dc=alab,dc=ucex,dc=edu
LDAP root account password (password for bind dn):
aSecret
Then fix up the nsswitch.conf and pam configuration files. This command seems possibly handy:
sudo auth-client-config -t nss -p lac_ldap
Here’s it’s format:
auth-client-config -p PROFILE -t TYPE
I think that this basically means switching the /etc/nsswitch.conf entries to be these:
passwd: files ldap
group: files ldap
shadow: files ldap
And adding a "pam_ldap.so" entry to the "/etc/pam.d/common-*" files. For example, here’s /etc/pam.d/common-password:
password [success=2 default=ignore] pam_unix.so obscure sha512
password [success=1 user_unknown=ignore default=die] pam_ldap.so use_authtok try_first_pass
Here’s /etc/pam.d/common-auth:
auth [success=2 default=ignore] pam_unix.so nullok_secure
auth [success=1 default=ignore] pam_ldap.so use_first_pass
Here’s /etc/pam.d/common-account:
account [success=2 new_authtok_reqd=done default=ignore] pam_unix.so
account [success=1 default=ignore] pam_ldap.so
Make sure pam is 100% happy by doing this:
$ sudo pam-auth-update
Create or modify /etc/ldap.conf file to be:
base dc=alab,dc=ucex,dc=edu
URI ldaps://abagyan-athena.ucex.edu/
ldap_version 3
rootbinddn cn=ldapadmin,dc=alab,dc=ucex,dc=edu
bind_policy soft
TLS_REQCERT never
TLS_CACERT /etc/ldap/ldapscert.pem
More Ubuntu Client Setup
Now to get a remote client working, you need to set up its /etc/ldap/ldap.conf file which controls client things:
base dc=alab,dc=ucex,dc=edu
URI ldaps://abagyan-athena.ucex.edu/
ldap_version 3
rootbinddn cn=ldapadmin,dc=alab,dc=ucex,dc=edu
bind_policy soft
#pam_password md5
# This is important to getting self-signed certs to work!
TLS_REQCERT never
TLS_CACERT /etc/ldap/ldapscert.pem
Also copy ldapscert.pem over and make sure it’s world readable.
A preliminary test useful for troubleshooting:
$ openssl s_client -connect abagyan-athena.ucex.edu:636 -showcerts
To actually test the remote clients:
$ ldapsearch -x -H ldaps://abagyan-athena.ucex.edu \
-b ou=users,dc=alab,dc=ucex,dc=edu '*'
A similar test can be used on the server itself if it’s not responding to ldaps:
$ sudo ldapsearch -x -H ldapi:/// -b ou=users,dc=alab,dc=ucex,dc=edu '*'
To test if TLS is working, check that the secure port (636) is ok with:
$ nmap -v localhost
Then try to connect with openssl’s tester client:
$ openssl s_client -connect localhost:636 -showcerts
On client config:
TLS_REQCERT allow
This allows your OpenLDAP or OpenLDAP-based client software (for example, gq) to accept self-signed server certificates.
And in /etc/ldap.conf:
tls_cert /etc/ldap/ldapscert.pem
tls_key /etc/ldap/ldapskey.pem
Gentoo LDAP Clients
Maybe need these:
-
emerge pam_ldap - mostly includes
lib/security/pam_ldap.so
-
emerge nss_ldap -
/lib/libnss_ldap-2.12.2.so
,/etc/nsswitch.ldap
,/etc/ldap.conf
CLIENT FUNCTIONALITY
This command run from the client should make a connection and return a nonsensitive (no hashes) dump of all the users (or whatever you have in there).
# ldapsearch -x -b 'dc=alab,dc=ucex,dc=edu' '(objectclass=*)'
This has been known to work properly on CentOS 5 and 6 both as root and normal users. It is probably a good way to monitor for the LDAP server dying but I’m not sure about that.
To check if user information is being made available to the operating system, try:
# getent passwd someuser
Of course this kind of checking is prone to unproductive hanging if there is a problem.
LDIF Format
- LDAP Data Interchange Format
-
The file format used to communicate with the LDAP server when changing the directory. Used by ldapsearch, ldapadd, and ldapmodify, etc.
dn: uid=xed,ou=People,dc=xed,dc=ch
uid: xed
cn: Chris X Edwards
objectClass: account
objectClass: posixAccount
objectClass: top
objectClass: shadowAccount
userPassword:: e2NyexxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxCZ0FnMWJ
lYklGNEhyVFhQd1VORWxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxaFIvUUcx
shadowLastChange: 14557
shadowMax: 99999
shadowWarning: 7
loginShell: /bin/bash
uidNumber: 500
gidNumber: 500
homeDirectory: /home/xed/
gecos: Chris X Edwards
structuralObjectClass: account
entryUUID: 23d6026d-56d5-4b2a-81d5-d673809bf3e1
creatorsName: cn=ldapadmin,dc=xed,dc=ch
createTimestamp: 20091129194112Z
entryCSN: 20091129194112.386639Z#000000#000#000000
modifiersName: cn=ldapadmin,dc=xed,dc=ch
modifyTimestamp: 20091129194112Z
ldapmodify
ldapmodify -x -W -D "cn=ldapadmin,dc=xed,dc=ch" -f change.ldif
Where "change.ldif" is something like:
dn: cn=Chris Edwards,ou=xed,dc=xed,dc=ch
changetype: modify
replace:uid
uid: 4444
-
replace:employeeNumber
employeeNumber: 98722
This replaces the uid and the employeeNumber. Here’s how to do it on the secure server setup:
ldapmodify -D "cn=ldapadmin,dc=alab,dc=ucex,dc=edu"\
-H ldaps://localhost -W -f modifysomething.ldif
On the server itself, try this:
ldapmodify -x -W -H ldapi:/// -D "cn=ldapadmin,dc=alab,dc=ucex,dc=edu"\
-f modifysomething.ldif
ldapadd
Create example.ldif
dn: uid=xed,ou=People,dc=xed,dc=ch
uid: xed
cn: Chris X Edwards
objectClass: account
objectClass: posixAccount
objectClass: top
objectClass: shadowAccount
userPassword: {crypt}$6$qmOwDkEl$hbTM.....
shadowLastChange: 14557
shadowMax: 99999
shadowWarning: 7
loginShell: /bin/bash
uidNumber: 500
gidNumber: 500
homeDirectory: /home/xed/
gecos: Chris X Edwards
ldapadd -x -D "cn=ldapadmin,dc=xed,dc=ch" -W -f example.ldif
Use ldapadd to add schemas too:
ldapadd -Y EXTERNAL -H ldapi:/// -f /etc/ldap/schema/cosine.ldif
ldapadd -Y EXTERNAL -H ldapi:/// -f /etc/ldap/schema/inetorgperson.ldif
ldapadd -Y EXTERNAL -H ldapi:/// -f /etc/ldap/schema/nis.ldif
-
-x
= simple authentication instead of SASL -
-Y
<mech> = SASL mechanism (PLAIN, LOGIN, DIGEST-MD5, CRAM-MD5, KERBEROS_V4, EXTERNAL=tls) -
-H
= ldapuri format is protocol://host:port/dn??scope?(cn=Some%20Filter) (see man ldapurl) -
-f
= LDIF file to add
ldapsearch
-
-x = Use simple authentication instead of SASL.
-
-W = Prompt for simple authentication. Not used for SASL.
-
-b = Search base. Starting point on tree for search.
-
-D <binddn> = For simple authentication, the dn to bind with, not for SASL.
-
-Y = SASL "mechanism". A good one seems to be "EXTERNAL".
-
-ZZ = TLS and require success.
-
-H = ldapuri format is protocol://host:port/dn??scope?(cn=Some%20Filter) (see man ldapuri)
This can be used to test to see things are working:
ldapsearch -x -b 'dc=xed,dc=ch' '(objectclass=*)'
Example, find the user xed’s record:
ldapsearch -x -W -D "cn=ldapadmin,dc=xed,dc=ch" -b "dc=xed,dc=ch" "uid=xed"
/usr/bin/ldapdelete
To get rid of an entire record in the directory:
ldapdelete -x -W -H ldapi:/// -D "cn=ldapadmin,dc=alab,dc=ucex,dc=edu" "ou=sudoers,dc=alab,dc=ucex,dc=edu"
Other Utilities
-
/usr/bin/ldapcompare
-
/usr/bin/ldapexop
-
/usr/bin/ldapmodrdn
-
/usr/bin/ldappasswd
-
/usr/bin/ldapurl
-
/usr/bin/ldapwhoami
-
/usr/sbin/slapacl
-
/usr/sbin/slapadd - Add a database
slapadd -l <inputfile> -f <slapdconfigfile> [-d <debuglevel>] [-n <integer>|-b <suffix>] * /usr/sbin/slapauth * /usr/sbin/slapcat - Dump the contents of an entire database
-
/usr/sbin/slapdn
-
/usr/sbin/slapindex
-
/usr/sbin/slappasswd- Use to generate passwords and hashes of passwords.
-
slappasswd -g # Generates a random password.
-
-
slappasswd # Prompts for password and generates hash suitable for LDAP.
-
-
/usr/sbin/slapschema
-
/usr/sbin/slaptest
REPLICATION
See syncrepl
.
http://www.openldap.org/doc/admin24/replication.html
TROUBLESHOOTING
LDAP is trouble so let’s start with how to diagnose problems or verify certain things are actually working.
Logging
LDAP events on the OpenLDAP server generally go to syslog. Watching
tail -f /var/log/syslog
should tell you if a connection attempt was
even made at all. It might also hint at other problems. If no
connection attempt was even recorded at the server then it’s not worth
trying to debug problems with certificates or other details of that
nature.
If you really want to see everything happening on the port, dump those packets with something like this:
# tcpdump -n tcp port ldaps
Error Codes
Of course all that logging will do no good if it is too cryptic to
comprehend. This list of LDAP error codes was
to the point and exactly what you’d hope to find when trying to decode
something like err=49
.
Mystery Dotted Decimal Strings
Often the output of slapd
verbose logging will contain awful things
like this:
545de4ab slap_global_control: unrecognized control: 1.3.6.1.4.1.42.2.27.8.5.1
545de4ab backend_check_controls: unrecognized non-critical control: 1.3.6.1.4.1.42.2.27.8.5.1
"These are not intended to be displayed to users," says the incredibly optimistic RFC2252. That document has a list with some of these things, but it looks like they can be whimsically made up by application programmers. To figure out what these crazy strings are trying to say, I had to go to the source code.
# grep "1.3.6.1.4.1.42.2.27.8.5.1" openldap-2.4.40/include/ldap.h
#define LDAP_CONTROL_PASSWORDPOLICYREQUEST "1.3.6.1.4.1.42.2.27.8.5.1"
#define LDAP_CONTROL_PASSWORDPOLICYRESPONSE "1.3.6.1.4.1.42.2.27.8.5.1"
Not exactly helpful but much more helpful than before.
Mystery Death
There is a mysterious mode of failure where the LDAP server stops working. It seems like sometimes it comes back from the dead after a long while but maybe not always. I have tracked it down to very aggressive jobs making tons of requests. The answer in the past has been to manually restart the server.
Further investigation has shown that in /var/log/syslog
there will
be some stuff like warning: cannot open /etc/hosts.allow: Too many
open files
. I can’t quite figure out exactly what that means or how
to properly cure it but it’s known and discussed
here.
I think I’ll try setting up a monitor that uses a simple ldapsearch
and when it fails, trigger a restart of the server automatically.
InK’s Excellent Pro Tips
-
Are the versions of OpenLDAP the same?
-
Or are you using a newer version on Gentoo?
-
How are the UID lookups failing? Using ldapsearch? getent passwd?
-
Are you seeing any errors in the client or server logs?
-
Have you started the daemon on the server with debugging turned up?
-
Instead of TLS, have you tried SSL and forcing all communication across 636?
-
One issue I ran into was Ubuntu’s use of GnuTLS vs. OpenSSL - contrary to popular belief/misconception, GnuTLS does not transparently deal with OpenSSL …
Fix passwd functionality
If the passwd
command doesn’t work look here:
/etc/pam.d/common-password
and remove this:
use_authtok
Connectivity
Make sure there is an open port on the LDAP server. This will be 389
for LDAP and 636 for LDAPS. Try nmap -p 389,636 ldap.example.com
.
Directory Backup And Restore
Here is how to make a dump of the directory database contents.
Remember that these files contain password hashes and are therefore
kind of sensitive. Ideally you should turn off the server to ensure
consistency, but as long as no one is actively modifying the directory
(no admin activity or passwd
commands) you should be ok.
$ sudo slapcat -v -f /etc/ldap/slapd.conf -l /home/xed/ldap/$(date +%Y%m%d).ldif
Here is a complete routine I used to restore a directory from a backup LDIF. Shut down the server and do this:
$ cd /usr/local/var
$ sudo rm openldap-data/*
$ sudo touch openldap-data/DB_CONFIG
$ sudo slapadd -v -c -l /home/xed/backup.20110711.ldif -f /etc/openldap/slapd.conf
$ sudo slapindex -f /etc/openldap/slapd.conf
TLS SETUP Place the certificate and key where they can be found. See TLS on how to use openssl to generate these certificates.
$ sudo cp ldaps*pem /etc/ldap/
Now prepare a /etc/ldap/slapd.conf file containing as described in the server set up section.
Now the server can be started up. This is where it is possible to
specify where the config file is. Also you can add some logging output
(try slapd -d?
for logging options, or slapd -d0123
to run in the
terminal and not fork).
$ sudo slapd -f /etc/ldap/slapd.conf -d1023 -h "ldaps://"
Helpful Utilities ?
-
LDAP Account Manager - http://www.ldap-account-manager.org/
-
gq
ENCRYPTION SETUP
It’s important to not use LDAP for machine authentication without encrypting the traffic. Without encryption, there’s almost no point to using any kind of access mechanism at all.
OpenSSL Key Generation
Start by generating a cert and a key:
$ sudo openssl req -x509 -nodes -newkey rsa:2048 -days 7300 -keyout ldapskey.pem -out ldapscert.pem
Note the default expiration is 30 days, so setting to 20 years is about as trouble free as it’s going to get.
$ sudo chown openldap:openldap *pem
$ sudo chmod 0400 *pem
Note the certificate is the public key and the key is the private key. This is self-signed so this avoids any certificate authority annoyances.
sudo ldapadd -Y EXTERNAL -H ldapi:/// <<EOF3
objectClass: olcGlobal
olcTLSCertificateFile: /etc/ldap/ldapscert.pem
olcTLSCertificateKeyFile: /etc/ldap/ldapskey.pem
EOF3
Need this too?
olcTLSCACertificateFile: /etc/ldap/ldapcacert.pem
Edit:
$ sudo vi /etc/default/slapd to include stricter connections:
SLAPD_SERVICES="ldap://127.0.0.1:389/ ldaps:/// ldapi:///"
or mabye (?)
SLAPD_SERVICES="ldap://127.0.0.1/ ldaps:///"
TLSCertificateFile /etc/ldap/ldapscert.pem
Specifies the file that contains the slapd server certificate.
TLSCertificateKeyFile /etc/ldap/ldapskey.pem
Specifies the file that contains the slapd server private key that matches the certificate stored in the TLSCertificateFile file. Currently, the private key must not be protected with a password, so it is of critical importance that it is protected carefully.
TLSCipherSuite TLSv1+RSA:!NULL
This is to disable the "NULL" ciphers (NULL-SHA and NULL-MD5). You can double check that this value is sensible with $ openssl ciphers -v TLSv1+RSA:!NULL This should produce the list of various encryption methods available. I think that’s what it’s doing. If it doesn’t fail, it’s probably ok.
TLSVerifyClient never
Default. Is this necessary?
disallow bind_anon
require bind
security simple_bind=128
SSL SETUP
Note
|
LDAP can use TLS (Transport Layer Security) or SSL (Secure
Socket Layer). TLS runs on the same port as unencrypted LDAP (389) but
an initial TLS Start protocol gets the encryption going. To get TLS
functionality, you must compile with --with-tls as a compile option
during the OpenLDAP build. SSL runs on a different port (636) and is
encrypted from the beginning. |
Generating SSL Keys For OpenLDAP
To use OpenLDAP in TLS or SSL mode you will need to generate a PEM format SSL key.
From this helpful web site:
cd /etc/openldap/ssl
/usr/bin/openssl req -newkey rsa:1024 -keyout tempfile1 -nodes -x509 -days 365 -out tempfile2
cat tempfile1 > ldap.pem
echo "" >> ldap.pem
cat tempfile2 >> ldap.pem
rm -f tempfile1 tempfile2
Note that this command creates an RSA key and then self-signs that key. Self-signed keys are not usual in (for example) HTTPS communications, as the keys are generally signed by a third party known as a Certification Authority. In this case, however, a self-signed key is perfectly okay, as most LDAP clients do not check the signature of the key.
Do these certificates work? With the server turned on try this:
$ openssl s_client -connect localhost:636 -showcerts
This web site has good information on using
OpenSSL. It discusses how to use s_server
and s_client
to test the
certificates as well as check to see that they’re not expired.
Place the certificate and key where they can be found. See TLS on how to use openssl to generate these certificates.
$ sudo cp ldaps*pem /etc/ldap/
Now prepare a /etc/ldap/slapd.conf file containing:
include /etc/ldap/schema/core.schema
include /etc/ldap/schema/cosine.schema
include /etc/ldap/schema/inetorgperson.schema
include /etc/ldap/schema/nis.schema
# SECURITY
access to attrs=userPassword
by self write
by anonymous auth
by dn.base="cn=ldapadmin,dc=alab,dc=ucex,dc=edu" write
by * none
access to *
by self write
by dn.base="cn=ldapadmin,dc=alab,dc=ucex,dc=edu" write
by * read
# DON'T bother with ARGS file unless you feel strongly
# slapd scripts stop scripts need this to work
pidfile /var/run/slapd/slapd.pid
# enable a lot of logging - we might need it
# but generates huge logs
#loglevel -1
# MODULELOAD definitions
# not required (comment out) before version 2.3
moduleload back_bdb.la
# TLS-enabled connections
TLSCACertificateFile /etc/ldap/ldapscert.pem
TLSCertificateFile /etc/ldap/ldapscert.pem
TLSCertificateKeyFile /etc/ldap/ldapskey.pem
database bdb
suffix "dc=alab,dc=ucex,dc=edu"
# root or superuser
rootdn "cn=ldapadmin,dc=alab,dc=ucex,dc=edu"
rootpw SecretStuff
# The database directory MUST exist prior to running slapd AND
# change path as necessary
directory /var/lib/ldap
# Indices to maintain for this directory
# unique id so equality match only
index uid pres,eq
# allows general searching on commonname, etc
index cn,sn pres,eq,approx,sub
# if searches will include objectClass uncomment following
index objectClass eq
# index objectClass eq
# shows use of default index parameter
index default eq,sub
# other database parameters
# read more in slapd.conf reference section
cachesize 10000
checkpoint 128 15
Might want to sudo chmod 600 /etc/ldap/slapd.conf
because of the
password in there.
REFERENCE
Useful Documents
-
The official definition of how LDAP should work is the RFC4511 protocol standard.
-
Useful HOWTO for Gentoo: link
-
Helpful overview of what LDAP is all about on Linux: link
-
Migration tools to move existing /etc/{passwd|group} to LDIF format: link
-
ldapvi - Use Vi to update LDAP directories: link
-
Useful Howto Ubuntu: link
-
Useful CentOS/Fedora Howto: link
-
Useful Looking CentOS6 Scripts: link
-
General Troubleshooting Helpfulness: link
-
This is pretty handy for knowing what you can sensibly put in an LDAP directory: link
-
This is the nss_ldap man page which is useful for defining fields of the client configuration: link
TLS Documents
Glossary
- LDAP
-
Lightweight Directory Access Protocol, rfc4511.
- X.500
-
The series of protocols which define things like Directory Access Protocol (DAP). Seems to be used only as a base or reference on which to create things like LDAP.
- slurpd
-
Standalone LDAP Update RePlication Daemon replaced by syncrepl (Sync-based replication)
- NSS
-
Name Service Switch sys-auth/nss_ldap - link
- DSA
-
Directory System Agent X.500 term for any DAP or LDAP enabled directory service e.g. an LDAP server.
- DSE
-
DSA Specific Entry (DSE) A control entry in a local directory server.
- DIT
-
Directory Information Tree aka namingContext
- SASL
-
Simple Authentication and Security Layer
- TLS
-
Transport Layer Security ("OpenLDAP clients and servers are capable of using the TLS framework to provide integrity and confidentiality protections and to support LDAP authentication using the SASL EXTERNAL mechanism.")
+----------------------+
| LDAP message layer |
+----------------------+ > LDAP PDUs
+----------------------+ < data
| SASL layer |
+----------------------+ > SASL-protected data
+----------------------+ < data
| TLS layer |
Application +----------------------+ > TLS-protected data
------------+----------------------+ < data
Transport | transport connection |
+----------------------+
- slapd
-
Standalone Lightweight Access Protocol Daemon
- LDIF
-
LDAP Data Interchange Format
- DN
-
Distinguished name, a sequence of RDNs connected by commas. Example: "cn=xed,ou=users,dc=alab,dc=ucex,dc=edu"
- RDN
-
Relative distinguished name, an attribute with an asscoiated value in the form
attribute=value
. Example: dc=edu - DC
-
Domain component
- CN
-
Common name
- OU
-
Organizational unit
- BER
-
Basic Encoding Rules - The mysterious
ber
saturates the OpenLDAP source code with absolutely no explanation. It is defined on page 4 of rfc4511 and vaguely here. The LDAP spec says that it uses a "subset" of BER. Seems to relate to how data is packaged for transmission. - PDU
-
LDAP Message Protocol Data Unit.
Another Useful LDAP Glossary: link
List Of Ubuntu LDAP Package Highlights
slapd - OpenLDAP server (slapd) Contains these useful things:
-
/etc/ldap
-
/etc/ldap/schema
-
/usr/sbin/slapd
-
/usr/sbin/slapacl
-
/usr/sbin/slapadd
-
/usr/sbin/slapauth
-
/usr/sbin/slapcat
-
/usr/sbin/slapdn
-
/usr/sbin/slapindex
-
/usr/sbin/slappasswd
-
/usr/sbin/slaptest - test config files for wholesomeness
ldap-utils - OpenLDAP utilities Contains these useful things:
-
/usr/bin/ldapdelete
-
/usr/bin/ldapmodrdn
-
/usr/bin/ldapsearch
-
/usr/bin/ldapcompare
-
/usr/bin/ldapmodify
-
/usr/bin/ldappasswd
-
/usr/bin/ldapwhoami
-
/usr/bin/ldapexop
-
/usr/bin/ldapurl
ldapscripts - Add and remove user and groups (stored in a LDAP directory) Contains these useful things:
-
/usr/sbin/ldapdeletemachine
-
/usr/sbin/ldapmodifygroup
-
/usr/sbin/ldapsetpasswd
-
/usr/sbin/lsldap
-
/usr/sbin/ldapadduser
-
/usr/sbin/ldapdeleteuser
-
/usr/sbin/ldapsetprimarygroup
-
/usr/sbin/ldapfinger
-
/usr/sbin/ldapid
-
/usr/sbin/ldapmodifymachine
-
/usr/sbin/ldaprenamegroup
-
/usr/sbin/ldapaddgroup
-
/usr/sbin/ldapaddusertogroup
-
/usr/sbin/ldapdeleteuserfromgroup
-
/usr/sbin/ldapinit
-
/usr/sbin/ldapmodifyuser
-
/usr/sbin/ldaprenamemachine
-
/usr/sbin/ldapaddmachine
-
/usr/sbin/ldapdeletegroup
-
/usr/sbin/ldaprenameuser
python-ldap - An LDAP interface module for Python Contains these useful things:
-
/usr/lib/python2.6/dist-packages/ldap
-
/usr/lib/python2.6/dist-packages/ldap/schema
Also notice:
-
/usr/lib/python2.6/dist-packages/ldap/ldapobject.py
-
/usr/lib/python2.6/dist-packages/ldapurl.py
-
/usr/lib/python2.6/dist-packages/ldif.py