view doc/LDAP @ 363:7d64cbe0ef62 draft

Remove useless symlinks
author Jordi Gutiérrez Hermoso <jordigh@octave.org>
date Tue, 24 Apr 2012 13:22:15 -0400
parents 82e2c77565bb
children
line wrap: on
line source

Goal
====

LDAP is supported by several 3rd-party applications to connect to an
existing users/groups base.  Using LDAP natively in our project would
allow to maintain a users/groups base that other projects could use,
with real-time updates.

Ideally Savane could connect to an existing LDAP, either pre-existing
or dedicated to Savane, have a separate app for write accesses to
LDAP,


Issues
======

There are a few issues with using LDAP+Django+Unix:

- (Open)LDAP is much slower than MySQL (20s to list 60000 users, < 1s
  in MySQL without cache).  Increasing slapd's cache didn't help.  We
  didn't find any way to improve this, and even then, this would mean
  it's hard to install properly and poorly documented.  389DS, another
  free LDAP server implementation, doesn't advertise improved
  performances, and praises OpenLDAP's, so there's little hope there.
  http://directory.fedoraproject.org/wiki/FAQ#How_is_Fedora_Directory_Server_different_from_OpenLDAP.3F

- There's no ORM for LDAP, so much User-related Django code would need
  to be replaced

- There's no official support for LDAP in Django, and what's planned
  is a low-quality, replication based backend (instead of direct,
  synchronized use without caching), that needs to be complemented
  with a cron'd refresh of user profile data (email, real name, etc.)

  Backend: http://code.djangoproject.com/ticket/11526
  Synchro: http://www.djangosnippets.org/snippets/893/

- Django's "sha1$" passwords are ridiculously incompatible with SSHA
  passwords used by LDAP (among others).

- LDAP queries are limited.  For example you cannot use the '<'
  operator on shadowExpire or uidNumber, because you need to alter the
  schema for this, and this is considered bad practice since you're
  diverging from the RFC.  This means it's difficult to implement
  sanity checks such as uidNumber >= 1000 when importing system users.

Some solutions:

- Use slapd-sql so LDAP fetchs the data transparently in SQL. But it's
  experimental, we didn't test.
  http://www.openldap.org/software/man.cgi?query=slapd-sql

- Export the database to LDAP (instead of the other way around).  This
  involves a replication delay.  Possible Savane could update LDAP
  when a user ou group information is changed.  This means however
  than LDAP isn't the canonical users/groups base anymore - just a
  convenience copy.  Also implement a custom Django auth backend with
  support for CRYPT or SSHA passwords.

- Modify 3rd-party apps so they use an external database for
  authentication, instead of using an external LDAP directory.

- If LDAP is used for the system (Unix) through libnss-ldap(d), the
  performances issues are not fixed.  Either you need to rely on nscd
  (but this means you'll get a cache delay before changes are taken
  into account, which defeats the point of using libnss-*), either you
  rely on libnss-mysql-bg, which is more efficient (cf. NSS-MYSQL).


Plan
====

Currently we plan to:

- Use libnss-mysql-bg (possible switch to libnss-pgsql later) for the
  system.

- Export the DB to LDAP if we need a 3rd-party app with LDAP support
  in the future.


OpenLDAP
========

# Installation notes

# - domain: savannah.gnu.org
# - organisation: (whatever)
# - Allow LDAPv2 protocol: no
# - HDB

cat <<EOF | debconf-set-selections
slapd slapd/no_configuration boolean false
slapd slapd/domain string savannah.gnu.org
slapd shared/organization string GNU
slapd slapd/password2 password admin
slapd slapd/password1 password admin
EOF

apt-get --assume-yes install slapd
#dpkg-reconfigure slapd

# Test:
#ldapsearch -b 'dc=savannah,dc=gnu,dc=org' -D 'cn=admin,dc=savannah,dc=gnu,dc=org' -w admin -x

# Alternatively: minimal config:
cat <<EOF > /etc/ldap/slapd.conf:
pidfile /var/run/slapd/slapd.pid
modulepath /usr/lib/ldap
moduleload back_bdb
include /etc/ldap/schema/core.schema
sizelimit unlimited

index uid,uidNumber,gidNumber,memberUid,shadowExpire eq

# DB n1
database bdb
directory /var/lib/ldap
suffix "dc=savannah,dc=gnu,dc=org"
rootdn "cn=admin,dc=savannah,dc=gnu,dc=org"
rootpw admin

access to attrs=userPassword,shadowLastChange
        by dn="cn=admin,dc=gnu,dc=org" write
	by anonymous auth
        by self write
        by * none
EOF

(in all case add the indexes)


Unix auth
=========

# Enable user lookup with libnss-ldap.  For additional passwords
# support you'll need libpam-ldap but we don't need it for Savane,
# since we're using SSH keys instead of passwords.

cat <<EOF | debconf-set-selections
libnss-ldap shared/ldapns/ldap-server string ldap://127.0.0.1/
libnss-ldap shared/ldapns/base-dn string dc=savannah,dc=gnu,dc=org
libnss-ldap libnss-ldap/rootbinddn string cn=admin,dc=savannah,dc=gnu,dc=org
libnss-ldap libnss-ldap/rootbindpw password admin
libnss-ldap shared/ldapns/ldap_version select 3
EOF

apt-get --assume-yes install libnss-ldap
cat <<EOF >> /etc/libnss-ldap.conf
nss_base_passwd ou=users,dc=savannah,dc=gnu,dc=org
nss_base_shadow ou=users,dc=savannah,dc=gnu,dc=org
nss_base_group  ou=groups,dc=savannah,dc=gnu,dc=org
EOF

sed -i -e 's/^\(passwd:.*$\)/\1 ldap/' \
       -e 's/^\(group:.*$\)/\1 ldap/'  \
       -e 's/^\(shadow:.*$\)/\1 ldap/' \
    /etc/nsswitch.conf

# Fetching a user's groups is sadly pretty inefficient (e.g. try 'id
# yourusername').  To compensate, you can install the Name Service
# Caching Daemon:
apt-get --assume-yes install nscd

# To avoid user listings to be too long, you can either limit the
# number of result entries in slapd (sizelimit), or filter out some
# users, e.g. with nss_base_passwd
# ou=users,dc=savannah,dc=gnu,dc=org?sub?!(shadowExpire=10)