This is by far the hardest part of the operation, due to the cryptic way
OpenLDAP 2.4 now stores its configs within LDAP instead of in a config file.
See man slapd-config
We are going to build an LDAP server with Base DN "dc=realm1,dc=ws,dc=nsrc,dc=org". Change this to match your own realm.
Install the slapd server and ensure everything else needed is present:
# apt-get install slapd ldap-utils libsasl2-modules-gssapi-mit
Set up the service principal with keytab readable by slapd:
# mkdir /etc/ldap/krb5
# kadmin -p student/admin
addprinc -randkey ldap/pc1.ws.nsrc.org
ktadd -k /etc/ldap/krb5/krb5.keytab ldap/pc1.ws.nsrc.org
^D
# chown -R openldap:openldap /etc/ldap/krb5
# chmod 550 /etc/ldap/krb5
# chmod 440 /etc/ldap/krb5/krb5.keytab
# editor /etc/default/slapd
...
export KRB5_KTNAME=/etc/ldap/krb5/krb5.keytab
# service slapd restart
Install the schemas we need:
# ldapadd -Y EXTERNAL -H ldapi:/// -f /etc/ldap/schema/cosine.ldif
# ldapadd -Y EXTERNAL -H ldapi:/// -f /etc/ldap/schema/nis.ldif
# ldapadd -Y EXTERNAL -H ldapi:/// -f /etc/ldap/schema/inetorgperson.ldif
# ldapadd -Y EXTERNAL -H ldapi:/// -f /etc/ldap/schema/misc.ldif
NOTE: For a real production LDAP server, read the files in
/usr/share/doc/slapd
carefully, especially README.Debian.gz
and README.DB_CONFIG.gz
Now we need to run some scripts - either paste directly to a root shell, or create in temporary files and then run them.
BEWARE: in LDIF files, superfluous spaces at the end of lines may cause attributes to be rejected as invalid!
First is create_database.sh
ldapadd -Y EXTERNAL -H ldapi:/// <<EOS
# Load hdb backend module
dn: cn=module{0},cn=config
objectClass: olcModuleList
cn: module
olcModulepath: /usr/lib/ldap
olcModuleload: {0}back_hdb
EOS
ldapadd -Y EXTERNAL -H ldapi:/// <<EOS
# Create the hdb database and place the files under /var/lib/ldap
dn: olcDatabase={1}hdb,cn=config
objectClass: olcDatabaseConfig
objectClass: olcHdbConfig
olcDatabase: {1}hdb
olcDbDirectory: /var/lib/ldap
olcSuffix: dc=realm1,dc=ws,dc=nsrc,dc=org
olcDbConfig: {0}set_cachesize 0 2097152 0
olcDbConfig: {1}set_lk_max_objects 1500
olcDbConfig: {2}set_lk_max_locks 1500
olcDbConfig: {3}set_lk_max_lockers 1500
olcLastMod: TRUE
olcDbCheckpoint: 512 30
olcDbIndex: uid pres,eq
olcDbIndex: cn,sn,mail pres,eq,approx,sub
olcDbIndex: objectClass eq
EOS
(Note: we have no olcRootDN or olcRootPW. This is a pure Kerberos config)
Next is init_database.sh
ldapadd -Y EXTERNAL -H ldapi:/// <<EOS
dn: dc=realm1,dc=ws,dc=nsrc,dc=org
objectClass: dcObject
objectclass: organization
o: ws.nsrc.org
dc: ws
description: LDAP root
dn: ou=People,dc=realm1,dc=ws,dc=nsrc,dc=org
objectClass: top
objectClass: organizationalUnit
ou: People
dn: ou=Groups,dc=realm1,dc=ws,dc=nsrc,dc=org
objectClass: top
objectClass: organizationalUnit
ou: Groups
EOS
And finally config.sh
# Because these are 'replace' operations it's safe to modify this script
# and re-run it
ldapmodify -Y EXTERNAL -H ldapi:/// <<EOS
dn: cn=config
replace: olcSaslSecProps
olcSaslSecProps: noanonymous,noplain,minssf=56
dn: olcDatabase={1}hdb,cn=config
replace: olcAccess
olcAccess: {0}to * by dn.regex="^uid=([^@,]+)/admin,cn=gssapi,cn=auth$" manage by users read
-
replace: olcRequires
olcRequires: SASL
EOS
The simple ACL says that full access is permitted to */admin
principals in
our realm, and otherwise read access is granted to any valid user (i.e.
anyone with a kerberos ticket that we recognize). See OpenLDAP ITS#6757 for
a note on the format of the auth DN.
We also require SASL, which disables anonymous and simple binds.
Note: minssf enforces encryption. GSSAPI always returns 56 for ssf, regardless of the strength of the actual crypto mechanism in use. See http://lists.andrew.cmu.edu/pipermail/cyrus-sasl/2006-September/000628.html
The following tweak disables unused sasl mechanisms, and means that
-Y GSSAPI
can be omitted form the ldapsearch command line.
# editor /etc/ldap/sasl2/slapd.conf
mech_list: gssapi external
Update /etc/ldap/ldap.conf
to point to your own LDAP server and base DN.
Use ldapsearch to check that you can query it.
$ kinit testuser
$ ldapsearch [-Y GSSAPI] [-b "dc=realm1,dc=realm1,dc=ws,dc=nsrc,dc=org"]
This should dump back the (mostly empty) LDAP database, as long as you have a Kerberos ticket
We are going to create a user called "newuser"
Firstly in Kerberos:
$ kadmin -p student/admin
addprinc newuser
... choose a password
^D
And now in LDAP:
$ kinit student/admin
$ ldapadd <<EOS
dn: uid=newuser,ou=People,dc=ws,dc=nsrc,dc=org
objectClass: account
objectClass: posixAccount
cn: newuser
uid: newuser
uidNumber: 10000
gidNumber: 100
homeDirectory: /home/newuser
loginShell: /bin/bash
gecos: newuser
description: User account
EOS
$ kdestroy
Now update your LDAP nscd/nsswitch configuration (part 2 of exercise 2).
You will need to edit /etc/ldap.conf
with your own PC as LDAP server
and your own Base DN. Restart nscd after doing this.
To verify all is working:
$ id newuser
You should see a result with the uid and gid. Repeated operations should be quick as nscd will be caching them.
Troubleshooting:
/etc/cron.hourly/kerberos
if necessary.There is a package called ldapscripts
with simple tools for adding
and managing LDAP users. Unfortunately it doesn't know about GSSAPI
authentication, so you need to patch it. See ldapscripts-sasl.diff
Then configure it:
# editor /etc/ldapscripts/ldapscripts.conf
SASLAUTH="GSSAPI"
...
SERVER="ldap://pc1.ws.nsrc.org"
...
SUFFIX="dc=realm1,dc=ws,dc=nsrc,dc=org"
Then adding a new user in LDAP is as simple as:
$ kinit student/admin
$ ldapadduser someuser users
$ kdestroy
Adding groups and users into groups:
$ ldapaddgroup noc
$ ldapaddusertogroup someuser noc
You may need to restart nscd before 'id' shows this information.
OpenLDAP replication is left as an exercise to the reader.