Back to the sea ; the Lightweight Directory (LDAP), episode V

       947 words, 5 minutes

OpenBSD 4.8 ships with a home-made LDAP daemon called ldapd.
According to the man page, “ldapd does not fully work yet” ; but for basic authentication directory, it seems to work just fine.

Basics

There’s nearly nothing to do except install OpenBSD.
The daemon comes configured with a default configuration file:

# /usr/sbin/ldapd -dv
parsing config /etc/ldapd.conf
parsing schema file '/etc/ldap/core.schema'
parsing schema file '/etc/ldap/inetorgperson.schema'
parsing schema file '/etc/ldap/nis.schema'
startup
listening on /var/run/ldapi
listening on fe80:3::1:389
listening on ::1:389
listening on 127.0.0.1:389
ldape: entering event loop

Now, let’s configure the base and admin user:

# vi /etc/ldapd.conf
namespace "dc=tumfatig,dc=net" {
        rootdn          "cn=admin,dc=tumfatig,dc=net"
        rootpw          "{SSHA}xxx"
        index           sn
        index           givenName
        index           cn
        index           mail
}

Remote connexion

The only twitch is that it listens on localhost and there are no ldap tools installed by default :) We can either install the openldap-client-*.tgz package or modify the installation so that it’s manageable from a remote location.

Configure ldapd to listen on the NIC:

# /etc/ldapd.conf  
listen on em0  

# /usr/sbin/ldapd -dv  
(...)  
listening on 192.168.12.144:389  
listening on ::1:389  
listening on 127.0.0.1:389  
(...) 

And connect to it:

# ldapsearch -x -H ldap://192.168.12.144 -D "cn=admin,dc=tumfatig,dc=net" -W
Enter LDAP Password:
ldap_bind: Confidentiality required (13)

On the server-side, your can see

accepted connection from 192.168.12.1 on fd 15
got request type 0, id 1
bind dn = cn=admin,dc=tumfatig,dc=net
refusing non-anonymous bind on insecure connection
sending response 1 with result 13
end-of-file on connection 15
closing connection 15

Of course, send the admin password on the network via an unsecured channel is… not secure :)

Configuring SSL

The service will be used as ldap.tumfatig.net and the SSL certificate was generated during episode IV (the Certificate Authority). So let’s configure the system and the daemon for TLS encryption:

# cp -p /etc/ssl/TMFCA/certs/ldap.tumfatig.net.crt \
  /etc/ssl/TMFCA/private/ldap.tumfatig.net.key     \
  /etc/ldap/certs/
# cp -p /etc/ssl/TMFCA/certs/localhost.crt         \
  /etc/ssl/TMFCA/private/localhost.key /etc/ldap/certs/

# vi /etc/ldapd.conf
(...)
listen on lo0 ldaps certificate localhost
listen on em0 ldaps certificate ldap.tumfatig.net
(...)
# /usr/sbin/ldapd -dv
(...)
loading certificate file /etc/ldap/certs/ldap.tumfatig.net.crt
loading key file /etc/ldap/certs/ldap.tumfatig.net.key
(...)
listening on fe80:1::20c:29ff:fe17:3948:636
ssl_setup: ssl setup finished for listener: 0x207fc0800
listening on 192.168.12.144:636
ssl_setup: ssl setup finished for listener: 0x20e9c6800
(...)

Copy the CA certificate and configure LDAP tools to use it. Then, you’ll be able to communicate with ldapd:

# cat ~/.ldaprc
TLS_CACERT /Users/jca/ca.tumfatig.net.pem
# ldapsearch -x -H ldaps://ldap.tumfatig.net -D "cn=admin,dc=tumfatig,dc=net" -W
Enter LDAP Password:
# extended LDIF
#
# LDAPv3
# base <> (default) with scope subtree
# filter: (objectclass=*)
# requesting: ALL
#

# search result
search: 2
result: 32 No such object

# numResponses: 1

On the server-side:

accepted connection from 192.168.12.1 on fd 15
ssl_session_init: switching to SSL
ssl_session_accept: accepting client
ssl_session_accept: accepting client
ssl_session_accept: accepted ssl client
got request type 0, id 1
bind dn = cn=admin,dc=tumfatig,dc=net
successfully authenticated as cn=admin,dc=tumfatig,dc=net
sending response 1 with result 0
got request type 3, id 2
base dn = , scope = 2
requesting 01 access to  by cn=admin,dc=tumfatig,dc=net, in namespace global
sending response 5 with result 32
finished search on msgid 2
got request type 2, id 3
current bind dn = cn=admin,dc=tumfatig,dc=net
end-of-file on connection 15
closing connection 15

Automatic start

The LDAP daemon is started from the standard rc scripts:

# vi /etc/rc.conf.local
ldapd_flags=""
# /usr/sbin/ldapd

Schema modification

I aim to use ldapd to store my application services (Mail, Web…).

Let’s enhanced the LDAP schema to be used by Postfix and friends:

# ftp -o /etc/ldap/courier.schema \
  http://courier.cvs.sourceforge.net/viewvc/courier/libs/authlib/authldap.schema

# vi /etc/ldapd.conf
(...)
schema "/etc/ldap/core.schema"
schema "/etc/ldap/nis.schema"
schema "/etc/ldap/courier.schema"
schema "/etc/ldap/inetorgperson.schema"
(...)

# diff courier.schema.orig courier.schema
78,82c78,82
< #attributetype ( 1.3.6.1.4.1.10018.1.1.14 NAME 'mailhost'
< #        DESC 'Host to which incoming POP/IMAP connections should be proxied'
< #        EQUALITY caseIgnoreIA5Match
< #        SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{256} )
< #
---
> attributetype ( 1.3.6.1.4.1.10018.1.1.14 NAME 'mailhost'
>         DESC 'Host to which incoming POP/IMAP connections should be proxied'
>         EQUALITY caseIgnoreIA5Match
>         SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{256} )
>

Now create the LDAP tree and import/create you objects.

Filtering access

Various tasks

Filling the directory

Create a LDIF file:

# vi tmf.ldif
# TuM'Fatig LDAP Tree
#
dn: dc=tumfatig,dc=net
objectClass: top
objectClass: domain
dc: tumfatig

dn: ou=users,dc=tumfatig,dc=net
objectClass: top
objectClass: organizationalUnit
description: Utilisateurs
ou: users

dn: ou=alias,dc=tumfatig,dc=net
objectClass: top
objectClass: organizationalUnit
description: Aliases
ou: alias

# Users
#
dn: uid=jca,ou=users,dc=tumfatig,dc=net
objectClass: top
objectClass: CourierMailAccount
objectClass: person
objectClass: organizationalPerson
objectClass: inetOrgPerson
cn: Joel Carnat
givenName: Joel
homeDirectory: /home/vmail
mail: joel@carnat.net
mailbox: jca/
sn: Carnat
uid: jca
userPassword: {SSHA}...

# E-mail aliases
#
dn: mail=jca@tumfatig.net,ou=alias,dc=tumfatig,dc=net
objectClass: top
objectClass: CourierMailAlias
objectClass: person
objectClass: organizationalPerson
objectClass: inetOrgPerson
cn: Joel Carnat
givenName: Joel
mail: jca@tumfatig.net
maildrop: joel@carnat.net
sn: Carnat

And import the data:

# ldapadd -x -H ldaps://ldap.tumfatig.net -D "cn=admin,dc=tumfatig,dc=net" -W -f tmf.ldif
Enter LDAP Password:
adding new entry "dc=tumfatig,dc=net"

adding new entry "ou=users,dc=tumfatig,dc=net"

adding new entry "ou=alias,dc=tumfatig,dc=net"

adding new entry "uid=jca,ou=users,dc=tumfatig,dc=net"

adding new entry "mail=jca@tumfatig.net,ou=alias,dc=tumfatig,dc=net"

Pretty easy and standard, huh :)

Indexes

LDAP makes faster replies if it has indexes of objects it hosts:

# ldapctl index  
Password:  
indexing namespace dc=tumfatig,dc=net 

Statistics

You can get stats from your LDAP daemon:

# ldapctl stats  
start time: Tue Jan 4 17:41:43 2011  
requests: 35  
search requests: 9  
bind requests: 5  
modify requests: 17  
timeouts: 0  
unindexed searches: 0  
active connections: 0  
active searches: 0

suffix: dc=tumfatig,dc=net  
data timestamp: Tue Jan 4 17:43:44 2011  
data page size: 16384  
data depth: 1  
data revisions: 26  
data entries: 10  
data branch/leaf/overflow pages: 0/1/0  
data cache size: 27 of 1024 (2.6% full)  
data page reads: 2  
data cache hits: 40 (95.2%)  
indx timestamp: Tue Jan 4 17:43:44 2011  
indx page size: 16384  
indx depth: 1  
indx revisions: 21  
indx entries: 40  
indx branch/leaf/overflow pages: 0/1/0  
indx cache size: 18 of 512 (3.5% full)  
indx page reads: 2  
indx cache hits: 63 (96.9%) 

That’s All Folks!