Tugger the SLUGger!SLUG Mailing List Archives

Re: [chat] LDAP talk

begin invisible ink quotation:

> What sort of stuff would you like to see covered in my LDAP talk? I have a
> bunch of things already mapped out, but I'd like to see if I'm aiming the
> talk at what people want to know. I guess the most popular thing is using
> LDAP for centralised authentication, which is defintiely part of the stuff
> I'm covering.

Just in case they might prove useful, here are some half-baked lecture
notes I had from a talk on the subject.  If there are significant errors
in it, I won't be too surprised.

LDAP - An Overview

What is a "directory"?

"Directory" is a generalised term for database-stored information
about network objects[1] with access or security attributes.  Examples:
Microsoft SAM database, Novell NDS database, NIS/NIS+ database.  Typically
not transactional.

What is "access"?

We mean client-server network access.  In this case, the native transport is
over TCP or UDP port 389.  Alternatively:

LDAP channel can run over SSL, using stunnel (LDAP V2 - OpenLDAP 1.2.x) or
natively (LDAP V3 - OpenLDAP 2.0.x).  Default fallback, with negligible
security, is the TCP/UDP port 389 mechanism.

(We will be discussing OpenLDAP, not the U. of Michigan LDAP Server:  
OpenLDAP is derived from the other one, but there are differences.)

LDAP-over-SSL is often called "LDAPS" -- not the plural of LDAP!

There is also an option for MIT Kerberos (v. 5) or KTH Kerberos (v. 4)
by itself or via a SASL (Simple Authentication and Security Layer) or GSSAPI
authentication interface -- not covered here.

What software does it use?

OpenLDAP (slapd), related libs and utilities.  
pam_ldap.so  and nss_ldap.so modules.  The PAM version does user/group
  information only; the NSS one can also support many other databases
  (listed below).
OpenSSL (optional)

Originally, the OSI consortium (the people who gave us the seven-layer
OSI network model) invented the "DAP" protocol, which would
have operated over the OSI network stack.  After the collapse of OSI,
U. of Michigan and the ISODE Consortium invented LDAP (IETF's RFC 1487, 
1993) as a more lightweight variant, running over TCP/IP.

What's LDAP for?

o  Unified authentication (user accounts) across multiple machines on a 
   LAN, similar to NIS/NIS+.
o  Re-uses / is compatible with other "directory"-like information
   such as employee database records / address books.

Any PAM-enabled application will get authentication, this way, automatically.

Application support:

No LDAP support in Samba-stable, only betas.  (Not fully PAM-ified.)
Sendmail supports it.
Postfix supports it.
BIND supports it (with a patch).
Netscape Navigator/Communicator's Roaming Access for Address Book and 
  Bookmark information are an LDAP client.

PAM vs. NSS:

PAM = Pluggable Authentication Modules :  Intermediate software layer
for general access authentication, e.g., for login, passwd, rlogin, su,
ftp, ssh, etc.  Access to diverse back-end databases is implemented via
plug-ins.  pam-ldap is one such.

PAM was invented by Sun for Solaris, and is now standard on most Linux

NSS = Name Service Switch, also invented by Sun, is a library-invocation
interface by which the system libraries get any combination of these 
database types from a hierarchical list of sources:

aliases: Mail aliases. 
ethers: Ethernet numbers. 
group: Groups of users. 
hosts: Host names and numbers. 
netgroup: Network wide list of host and users.
network: Network names and numbers. 
protocols: Network protocols. 
passwd: User passwords. 
rpc: Remote procedure call names and numbers.
services: Network services. 
shadow: Shadow user passwords. 

It's a bad idea to try to get anything but shadow, passwd and group 
data from LDAP (performance, they change too seldom, and it's more 
convenient to have them as local files), so in practice that isn't 

Populating OpenLDAP's default "ldbm"[2] disk database (priming the pump):

First, create an LDIF (LDAP Data Interchange Format) flat-file
your_file.ldif, then run "ldif2ldbm -i your_file.ldif" to import it.
You have to do this before slapd will start.

LDIF is a way of writing X.500 directory data.  Example LDIF file
(always in ASCII) from the LDAP Implementation HOWTO follows:

 # dn = "distinguished name" is an X.500 descriptor fully identifying an object
 dn:dc=yourorg, dc=com
 # Below a "dn", one has object attributes in "name: value" format.
 objectclass: top
 objectclass: organizationalUnit

 #multiple records within an LDIF are delimited by blank lines
 dn:ou=groups, dc=yourorg, dc=com
 objectclass: top
 objectclass: organizationalUnit
 ou: groups

 dn:ou=people, dc=yourorg, dc=com
 objectclass: top
 objectclass: organizationalUnit
 ou: people

 dn: cn=Giuseppe LoBiondo, ou=people, dc=yourorg, dc=com
 cn: Giuseppe Lo Biondo
 sn: Lo Biondo
 objectclass: top
 objectclass: person
 objectclass: posixAccount
 objectclass: shadowAccount
 gecos:Giuseppe Lo Biondo
 homeDirectory: /home/giuseppe
 shadowMin: 0
 shadowMax: 999999
 shadowWarning: 7
 shadowInactive: -1
 shadowExpire: -1
 shadowFlag: 0

 dn: cn=mygroup, ou=groups, dc=yourorg, dc=com
 objectclass: top
 objectclass: posixGroup
 cn: mygroup
 gidnumber: 100
 memberuid: giuseppe
 memberuid: anotheruser

Afterwards, ordinarily one maintains LDAP database contents using normal
account tools.  One general-purpose browser directly to the LDAP database:
Jarek Gawor's LDAP Browser/Editor, http://www-unix.mcs.anl.gov/~gawor/ldap/
Or, one can use OpenLDAP's "slapadd" command-line utility to import from 
more LDIF files, ldapsearch to search records, ldapdelete to delete records,
ldapmodify to edit/add records,

Enabling LDAP support via PAM:

For each service you'll want to LDAP-enable (such as login, sshd), edit its
/etc/pam.d/* file to be roughly like this:

 auth     required   /lib/security/pam_securetty.so
 auth     required   /lib/security/pam_nologin.so
 auth     sufficient /lib/security/pam_ldap.so
 auth     required   /lib/security/pam_unix_auth.so use_first_pass
 account  sufficient /lib/security/pam_ldap.so
 account  required   /lib/security/pam_unix_acct.so
 password required   /lib/security/pam_cracklib.so
 password sufficient /lib/security/pam_ldap.so
 password required   /lib/security/pam_unix_passwd.so use_first_pass md5 shadow
 session  required   /lib/security/pam_unix_session.so

Warning:  Do NOT fool with PAM files without having a backup copy of the 
entire /etc/pam.d/ directory stored away, in case you lock yourself out
and have to boot a maintenance floppy to recover your system.

Enabling LDAP support via NSS:

This approach is easier.  Edit /etc/nsswitch.conf to change the 
authentication order, like this:

 passwd: files ldap
 group:  files ldap
 shadow: files ldap

Note the other service names:  hosts, networks, protocols, services,ethers,
rpc, netgroup.  You _can_ use LDAP for hosts, but with speed problems that
are best _not_ dealt with by nscd, but rather pdnsd or similar.

Do NOT put "dns" before "ldap" on the hosts line:  Infinite recursion
whenever DNS doesn't return results, since LDAP calls getbyhostname.
Or at the minimum, populate the /etc/hosts file thoroughly, so that "files"
takes precedence.

LDAP client configuration:

Either the NSS or PAM approach will be constrained by /etc/ldap.conf, as will
any other LDAP-using process.  This is the client config, which specifies
where the LDAP server is, and how to talk to it.

# Your LDAP server. Must be resolvable without using LDAP.
 # The distinguished name of the search base.
 base dc=yourorg, dc=com
 # ldap_version 3
 # binddn cn=manager,dc=padl,dc=com
 #bindpw secret
 port 636  # stunnel
 #scope sub
 #scope one
 #scope base
 # Specific to nss_ldap.
 #crypt md5
 #crypt sha
 #crypt des  #default
 # Specific to pam_ldap.
 pam_filter objectclass=posixAccount
 # The user ID attribute (defaults to uid)
 pam_login_attribute uid
 # Group member attribute
 pam_member_attribute memberuid
 #pam_login_attribute userPrincipalName
 #pam_template_login_attribute uid
 #pam_template_login nobody
 # Hash password locally
 pam_crypt local
 # SSL Configuration
 ssl yes
 sslpath /usr/local/ssl/certs

Configuring nscd (nameservice caching daemon):

Runs as a SysVInit service to compensate for speed problems with directory
services (LDAP, NIS, NIS+), configured in /etc/nscd.conf:

 enable-cache           passwd  yes      
 positive-time-to-live  passwd  600
 negative-time-to-live  passwd  20       
 suggested-size         passwd  211
 keep-hot-count         passwd  20       
 check-files            passwd  yes              
 enable-cache           group  yes       
 positive-time-to-live  group  3600      
 negative-time-to-live  group  60        
 suggested-size         group  211       
 keep-hot-count         group  20        
 check-files            group  yes        
# enable-cache           hosts  yes
# positive-time-to-live  hosts  600
# negative-time-to-live  hosts  20
# suggested-size         hosts  211
# keep-hot-count         hosts  20
# check-files            hosts  yes

Note:  nscd is bad about retaining obsolete DNS data (cache inconsistencies); 
consider pdnsd or other alternatives, for the DNS part.  Omit nscd entirely
until system size and activity demands it.  

First step in any debugging process should be to halt nscd, pdnsd, or any
other caching process.

Also, NSS and nscd chew up file descriptors the way Java chews up threads,
so you might want to double /proc/sys/fs/file-max to 8192.

Enabling sladp:

Runs as a SysVInit process.

o  To use the dafault port 389, just start "slapd" with no options/parameters.
o  To tunnel LDAP over stunnel, do

   stunnel -r ldap -d 636 -p stunnel.pem

o  To start LDAP v. 3 (if using OpenLDAP 2.0) over OpenSSL/TLS, do

   slapd -h "ldap:/// ldaps:///"

Security concerns:

There are two separate and equally worrying types of security exposure 
inherent in running an LDAP server:  resource discovery and direct attack.
For this reason, publicly accessible LDAP servers are almost unheard of,
and they should be used internally within an enterprise only with caution.

The "resource discovery" problem is that people can mine the contents of
the LDAP database to glean extensive details about the organisation.
This is the same risk as with DNS servers, except magnified by the greater
extent of information on file.  (You can mitigate this exposure, somewhat, 
by imposing ACLs = Access Control Lists on who can view which contents.)

Aside from that, the OpenLDAP server process has a shaky security history, 
and must run with root-equivalent authority.  Even if accessible only 
over SSL/TLS or Kerberos, it is thus an obvious point of attack on one's
key server machines.


This is a bit beyond the scope of this talk, but OpenLDAP comes with
"slurpd", which replicates the LDAP database to secondary copies, for
redundancy and localisation of traffic.


(1) Set up OpenLDAP, and populate it with a schema to check 
your Netscape Bookmarks into Roaming Access.  You'll find details 
in the LDAP HOWTO's section 6.1 - 6.2, and at the "Implementing Roaming 
Access" link below.

(2) Configure PAM (/etc/pam.d/*, pam_ldap.so) and the LDAP client 
(/etc/ldap.conf) to authenticate root and your regular username 
to LDAP instead of your standard authentication mechanism.  Use any
authentication mechanism you want.  (The default port 389 one is fine.)

Further Reading:

You Can Get There from Here, Part 4  (detailed LDAP setup) by Marcel Gagné

An Introduction to LDAP

LDAP Implementation HOWTO


OpenLDAP site

Implementing Roaming Access in Netscape

A project for Linux Directory Services over LDAP

LDAP Roadmap and FAQ

GNU libc (source of nscd)

pdnsd by Thomas Moestl


[1] Technically, it can contain arbitrary sorts of information,
but usually is limited to the foregoing.

[2] Alternative storage mechanisms include Sleepcat's Berkeley db and
FSF's gdbm, or various SQL databases.  However, ldbm is so much faster
and better-optimised for this role that people are usually advised to,
if anything,  keep _master_ copies of the LDAP database in a SQL 
database, and roll it out to ldbm.