Differences between revisions 85 and 132 (spanning 47 versions)
Revision 85 as of 2012-04-25 19:45:58
Size: 23163
Comment: Adapt to Squeeze : TLS
Revision 132 as of 2020-10-21 17:14:57
Size: 26054
Editor: nodiscc
Comment: add categories
Deletions are marked like this. Additions are marked like this.
Line 1: Line 1:
## page was renamed from OpenLDAPSetup
= Setting up an LDAP server with OpenLDAP =

==TO DO== ==Work in Progess==

most of this page does not easily apply to ldap in squeeze. as of slapd 2.4.23 things changed a lot. I've found that most of the docs available in searches for ldap setup are for an older set up.

so this page and others need to be updated for Squeeze , Wheezy and the future.

== Install the OpenLDAP package slapd ==

Install the package with:
{{{
  # apt-get install slapd
}}}
answering the prompts as follows:

Note: if you don't get these options use {{{dpkg-reconfigure -plow slapd}}} after installation. With the latest version, it only asks you for admin user password and none of the rest, because the DNS domain name is taken from configured machine FQDN name.

 * For the DNS domain name, enter your domain name. This will be translated to an LDAP DN (for example, '{{{example.com}}}' would become '{{{dc=example, dc=com}}}'). This becomes what is known as your ''BaseDN'', the root of your database.
 * For your organization you can enter any string; this becomes associated to the '{{{o}}}' field of your ''BaseDN'' record.
 * Next enter your LDAP administrator password twice. This will set the password for '{{{cn=admin, BaseDN}}}' and give '{{{cn=admin, BaseDN}}}' write access to everything in your LDAP tree.
 * Accept the default of {{{No}}} to the question {{{Allow LDAPv2}}} protocol.
 * Use the default database backend.

For querying the LDAP server utilities like {{{ldapsearch}}} are available. See the [[LDAP/LDAPUtils]] topic for more details.

== Missing slapd.conf? ==
Since version 2.4.23-3 the configuration of OpenLDAP has been changed to /etc/ldap/slapd.d by default. The OpenLDAP packages in Debian provide an automatic migration to the new configuration style. With the new configuration style it is possible to change values on the fly without restarting slapd. Changes are made through the use of ldif files and ldap{add,modify}. In Debian you can use the following command to search the configuration:

      ldapsearch -Y EXTERNAL -H ldapi:/// -b "cn=config"

To modify configuration use the command:

      ldapmodify -Y EXTERNAL -H ldapi:/// -f <file.ldif>

For configuration options see the several manpages that exist or the documentation provided upstream.

The use of slapd.conf remains possible (optional).
[[https://openldap.org/|OpenLDAP]] is an [[OpenSource|open source]] implementation of the [[WikiPedia:Lightweight Directory Access Protocol]]. It includes [[DebianPkg:libldap-2.4-2|libraries]], [[DebianPkg:ldap-utils|clients]], and a [[DebianPkg:slapd|server]]. This page is about running the OpenLDAP Standalone LDAP Daemon `slapd` on Debian.

FixMe: update for (Buster/Bullseye) defaults and recommendations

ToDo: update for Buster/Bullseye; review, organize, refactor; consider moving specific topics (e.g. Samba) to separate pages

<<TableOfContents(2)>>

= Documentation and resources =

 * The Debian-specific setup and configuration of DebianPkg:slapd are documented in [[https://salsa.debian.org/openldap-team/openldap/raw/master/debian/slapd.README.Debian|/usr/share/doc/slapd/README.Debian.gz]].
 * Debian users have contributed some wiki pages about [[LDAP|LDAP and OpenLDAP]].
 * OpenLDAP includes comprehensive documentation in the form of [[ManPage|man pages]]. In the beginning you will likely need (at least) [[DebianMan:5/slapd-config|slapd-config(5)]], [[DebianMan:1/ldapsearch|ldapsearch(1)]], [[DebianMan:1/ldapmodify|ldapmodify(1)]], and [[DebianMan:5/ldif|ldif(5)]]. There are individual man pages for significant features of [[DebianMan:8/slapd|slapd(8)]] such as [[DebianMan:5/slapd-config|configuration]], [[DebianMan:5/slapd.access|access control]], [[DebianMan:5/slapd.backends|backends]], and [[DebianMan:5/slapd.overlays|overlays]].
 * The OpenLDAP project maintains an [[https://openldap.org/doc/admin24/|Administrator's Guide]].
 * The Ubuntu Server Guide includes [[https://ubuntu.com/server/docs/service-ldap|a chapter on OpenLDAP]], including guides for specific use cases.
 * LDAP is defined in a number of [[WikiPedia:Request_for_Comments|RFC]] documents, beginning with [[RFC:4510|RFC 4510]].
 * More information about LDAP in general may be found on [[https://ldap.com/|LDAP.com]].
 * Questions about the Debian packages may be emailed to the maintainers at pkg-openldap-devel@lists.alioth.debian.org. Please check [[DebianBug:src:openldap|the list of open bugs]] in case your issue is already known.
 * Questions about OpenLDAP software may be emailed to the OpenLDAP mailing list at openldap-technical@openldap.org.

= Installing and configuring the OpenLDAP server =

The OpenLDAP server package is DebianPkg:slapd. The recommended tools for configuring `slapd` and setting up your directory are DebianPkg:ldap-utils.

{{{
apt install slapd ldap-utils
}}}

You will be prompted to provide a password for the database administrator.

By default, an initial database is created in `/var/lib/ldap` and configured using the system's DNS domain name. If your system is in the domain `example.com`, the database suffix is `dc=example,dc=com` and the administrator is named `cn=admin,dc=example,dc=com`. The domain name and other details can be changed by preseeding, by running the installation at a different [[DebianMan:7/debconf#Priorities|debconf(7) priority]], or by running `dpkg-reconfigure slapd` after installation.

To check the database suffix, once the server is running, use [[DebianMan:1/ldapsearch|ldapsearch(1)]] to read the `namingContexts` attribute of the root DSE:

{{{
ldapsearch -x -s base -b "" namingContexts
}}}

== Tour of the installation ==

The following are the key files and directories installed by the `slapd` package:

 * [[DebianMan:8/slapd|slapd(8)]] and the associated tools such as [[DebianMan:8/slapadd|slapadd(8)]], [[DebianMan:8/slapcat|slapcat(8)]], [[DebianMan:8/slapindex|slapindex(8)]], and others are installed in `/usr/sbin`.
 * The loadable modules included with `slapd` are installed in `/usr/lib/ldap`.
 * [[https://ldap.com/understanding-ldap-schema/|LDAP Schema]] files included with `slapd` or other packages are installed in `/etc/ldap/schema`.
  * Files ending in `.schema` can be `include`d into a legacy `slapd.conf` file. By default, the Debian setup does not use these files.
  * Files ending in `.ldif` can be imported into the configuration using [[DebianMan:1/ldapadd|ldapadd(1)]]. This copies them into the configuration database and the source files are no longer used afterward.
 * The configuration database `cn=config` is stored in `/etc/ldap/slapd.d`, owned by the `openldap` user.
 * The default database is stored in `/var/lib/ldap`, owned by the `openldap` user.

The configuration is stored in an LDAP database rooted at `cn=config`. Many configuration changes can be made online, while `slapd` is running, using LDAP operations on this database. Debian's default access rules allow access by the system `root` user only. `root` may query or search the database using [[DebianMan:1/ldapsearch|ldapsearch(1)]] with SASL EXTERNAL authentication:

{{{
ldapsearch -H ldapi:/// -Y EXTERNAL -b "cn=config"
}}}

The package sets up a default directory based on the system's DNS domain. Debian's default access rules allow anyone to search this directory without any authentication:

{{{
ldapsearch -x -b "dc=example,dc=com"
}}}

To connect as the database administrator, use Simple authentication, and when prompted, enter the password configured during installation:

{{{
ldapsearch -x -D "cn=admin,dc=example,dc=com" -W -b "dc=example,dc=com"
}}}

= Basic tasks =

== Enable request logging ==

The server logs are sent to the system log (syslog and/or the journal). The default log level is `none`.

To enable basic request logging, change the log level to `stats`:

{{{
ldapmodify -H ldapi:/// -Y EXTERNAL << EOF
dn: cn=config
changetype: modify
replace: olcLogLevel
olcLogLevel: stats

EOF
}}}

If you wish to disable request logging later, repeat the procedure and set the log level back to `none`.

For more information, read about `olcLogLevel` in the [[DebianMan:5/slapd-config|slapd-config(5)]] man page.

== Enable TLS/SSL ==

To enable [[WikiPedia:Transport_Layer_Security|TLS]] in `slapd`, you will need the '''server certificate''' and the associated '''private key''', both in [[WikiPedia:Privacy-Enhanced_Mail|PEM]] format. You may also have an '''intermediate certificate'''. Clients will need the '''CA certificate''' which is the Issuer of the server or intermediate certificate.

The files must all be readable by the `openldap` user. It is recommended to ensure the private key is not readable by any user except `openldap`.

To configure the server certificate, private key, and intermediate certificate used by `slapd`:

{{{
ldapmodify -H ldapi:/// -Y EXTERNAL << EOF
dn: cn=config
changetype: modify
replace: olcTLSCertificateFile
olcTLSCertificateFile: /etc/ssl/certs/server.pem
-
replace: olcTLSCertificateKeyFile
olcTLSCertificateKeyFile: /etc/ssl/private/server.key
-
replace: olcTLSCACertificateFile
olcTLSCACertificateFile: /etc/ssl/certs/intermediate.pem

EOF
}}}

If you do not have an intermediate certificate, the `olcTLSCACertificate` lines should be omitted. The root CA does not need to be configured in `slapd`.

If the modifications fail with `ldap_modify: Other (e.g., implementation specific) error (80)`, check the file paths for typos, and ensure the files are readable by the `openldap` user.

After applying the configuration, test a secure connection using StartTLS:

{{{
LDAPTLS_CACERT=/etc/ssl/certs/ca.pem ldapwhoami -H ldap://ldap.example.com -ZZ -x
}}}

where `ca.pem` is the root CA certificate and `ldap.example.com` is the server's name, exactly matching the Common Name (CN) or Subject Alternative Name (SAN) in the server certificate.

If the secure connection is successful, `ldapwhoami` should just print `anonymous`. If it fails, append `-d 1` to the command line to enable debug output, and look for lines beginning with `TLS:`.

By default, `slapd` supports [[WikiPedia:StartTLS|StartTLS]] on the standard LDAP port 389. If you wish to enable the LDAPS protocol on port 636, then edit `/etc/default/slapd`, add `ldaps:///` to the `SLAPD_SERVICES` line, and restart `slapd`.

{{{
vi /etc/default/slapd

...
SLAPD_SERVICES="ldap:/// ldapi:/// ldaps:///"
...

service slapd restart
}}}

LDAPS can be tested the same way, using `-H ldaps://` instead of `-ZZ`:

{{{
LDAPTLS_CACERT=/etc/ssl/certs/ca.pem ldapwhoami -H ldaps://ldap.example.com -x
}}}

Again, if successful, it should just print `anonymous`.

For more information, read about TLS Options in the [[DebianMan:5/slapd-config#TLS_OPTIONS|slapd-config(5)]] man page, noting that the TLS implementation used in Debian is [[https://www.gnutls.org/|GnuTLS]]. The OpenLDAP Administrator's Guide also has a [[https://openldap.org/doc/admin24/tls.html|chapter about TLS]].

== Check and configure the database max size ==

The default database uses [[DebianMan:5/slapd-mdb|the LMDB storage backend]]. This backend requires little configuration or tuning, but there is one important parameter: the max size.

The database is stored in a sparse file, `/var/lib/ldap/data.mdb`. It has a fixed maximum size, specified by the `olcDbMaxSize` parameter. The default database has its max size configured to 1 GiB upon installation. When the database reaches its max size, writes (even updates to existing entries) will fail.

Use [[DebianMan:1/du|du(1)]] to check the actual space used by the database:

{{{
du -h /var/lib/ldap/data.mdb
}}}

To check the current max size of database #1:

{{{
ldapsearch -H ldapi:/// -Y EXTERNAL -b "olcDatabase={1}mdb,cn=config" olcDbMaxSize
}}}

To set the max size of database #1 to 10 GiB (10737418240 bytes):

{{{
ldapmodify -H ldapi:/// -Y EXTERNAL << EOF
dn: olcDatabase={1}mdb,cn=config
changetype: modify
replace: olcDbMaxSize
olcDbMaxSize: 10737418240

EOF
}}}

On 32-bit systems, the max size is constrained by address space limitations, and it may not be possible to grow the database larger than about 2 GiB. For larger databases, a 64-bit system is recommended.

For more information, read about `maxsize` in [[DebianMan:5/slapd-mdb|slapd-mdb(5)]].

== Change the administrator's password ==

The password configured during installation is saved in two places. To change the password, both values must be updated. If only one is changed, the old password can still be used. This should be fixed in the next release; see [[DebianBug:821331|Debian bug #821331]].

Use [[DebianMan:8/slappasswd|slappasswd(8)]] to hash the new password, and then use [[DebianMan:1/ldapmodify|ldapmodify(1)]] to update the hashed password in the `olcRootPW` attribute in the database configuration.

{{{
# slappasswd
New password: newpassword
Re-enter new password: newpassword
{SSHA}zYHmkowzdMxwX0KtEPNak5IbzfY8YmdQ
# ldapmodify -H ldapi:/// -Y EXTERNAL
SASL/EXTERNAL authentication started
SASL username: gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth
SASL SSF: 0
dn: olcDatabase={1}mdb,cn=config
changetype: modify
replace: olcRootPW
olcRootPW: {SSHA}zYHmkowzdMxwX0KtEPNak5IbzfY8YmdQ

modifying entry "olcDatabase={1}mdb,cn=config"

}}}

Next, use [[DebianMan:1/ldappasswd|ldappasswd(1)]] to change the password the administrator's account in the directory.

{{{
# ldappasswd -x -D cn=admin,dc=example,dc=com -W -S
New password: newpassword
Re-enter new password: newpassword
Enter LDAP Password: oldpassword
}}}

Finally, test authenticating with the old and new passwords, and confirm that only the new password can be used.

{{{
# ldapwhoami -x -D cn=admin,dc=example,dc=com -W
Enter LDAP Password: oldpassword
ldap_bind: Invalid credentials (49)
# ldapwhoami -x -D cn=admin,dc=example,dc=com -W
Enter LDAP Password: newpassword
dn:cn=admin,dc=example,dc=com
}}}

= Advanced tasks =
Line 47: Line 237:
Modify {{{/etc/ldap/slapd.conf}}} to contain the following: Create or modify {{{/etc/ldap/slapd.conf}}} to contain the following:
Line 63: Line 253:
  # /etc/init.d/slapd stop
  # slapindex
  # chown -R openldap:openldap /var/lib/ldap
  # /etc/init.d/
slapd start
  # service slapd stop
  # sudo -u openldap slapindex
  # service slapd start
Line 71: Line 260:
Create a LDIF file : olcDbIndex.ldif
{{{
dn: olcDatabase={1}hdb,cn=config
Create a LDIF file in /etc/ldap : olcDbIndex.ldif
{{{
dn: olcDatabase={1}mdb,cn=config
Line 102: Line 291:

Use ldapmodify to add this settings to the ldap :
Note: use the correct database format in the first line, the default type during installation of slapd is '''mdb'''.


Use ldapmodify to add the indexing settings to the ldap :
Line 107: Line 298:

After the execution, slapd will launch a internal task to create indexes. Don't stop slapd during this indexation.
Do not leave out the '''-''' (dash character) from the file, it is needed.
After execution of the ldapmodify command, slapd will launch a internal task to create indexes. Don't stop slapd during indexing.
Line 112: Line 303:
=== Configuring 'chsh' and 'chfn' to work with LDAP ===

==== via static configuration ====
Configuring 'chsh' and 'chfn' to work with LDAP

=== with slapd.conf ===
Line 125: Line 316:
==== via dynamic configuration ==== === with cn=config ===
Line 148: Line 339:
 aptitude install samba-doc
}}}


=== with cn=config, slapd.d (default in Squeeze): ===
Load the following ldif into your cn=config:

{{{
dn: cn=samba,cn=schema,cn=config
objectclass: olcSchemaConfig
cn: samba
olcattributetypes: {0}( 1.3.6.1.4.1.7165.2.1.24 NAME 'sambaLMPassword' DESC
 'LanManager Password' EQUALITY caseIgnoreIA5Match SYNTAX 1.3.6.1.4.1.1466.1
 15.121.1.26{32} SINGLE-VALUE )
olcattributetypes: {1}( 1.3.6.1.4.1.7165.2.1.25 NAME 'sambaNTPassword' DESC
 'MD4 hash of the unicode password' EQUALITY caseIgnoreIA5Match SYNTAX 1.3.6
 .1.4.1.1466.115.121.1.26{32} SINGLE-VALUE )
olcattributetypes: {2}( 1.3.6.1.4.1.7165.2.1.26 NAME 'sambaAcctFlags' DESC '
 Account Flags' EQUALITY caseIgnoreIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.
 1.26{16} SINGLE-VALUE )
olcattributetypes: {3}( 1.3.6.1.4.1.7165.2.1.27 NAME 'sambaPwdLastSet' DESC
 'Timestamp of the last password update' EQUALITY integerMatch SYNTAX 1.3.6.
 1.4.1.1466.115.121.1.27 SINGLE-VALUE )
olcattributetypes: {4}( 1.3.6.1.4.1.7165.2.1.28 NAME 'sambaPwdCanChange' DES
 C 'Timestamp of when the user is allowed to update the password' EQUALITY i
 ntegerMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )
olcattributetypes: {5}( 1.3.6.1.4.1.7165.2.1.29 NAME 'sambaPwdMustChange' DE
 SC 'Timestamp of when the password will expire' EQUALITY integerMatch SYNTA
 X 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )
olcattributetypes: {6}( 1.3.6.1.4.1.7165.2.1.30 NAME 'sambaLogonTime' DESC '
 Timestamp of last logon' EQUALITY integerMatch SYNTAX 1.3.6.1.4.1.1466.115.
 121.1.27 SINGLE-VALUE )
olcattributetypes: {7}( 1.3.6.1.4.1.7165.2.1.31 NAME 'sambaLogoffTime' DESC
 'Timestamp of last logoff' EQUALITY integerMatch SYNTAX 1.3.6.1.4.1.1466.11
 5.121.1.27 SINGLE-VALUE )
olcattributetypes: {8}( 1.3.6.1.4.1.7165.2.1.32 NAME 'sambaKickoffTime' DESC
  'Timestamp of when the user will be logged off automatically' EQUALITY int
 egerMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )
olcattributetypes: {9}( 1.3.6.1.4.1.7165.2.1.48 NAME 'sambaBadPasswordCount'
  DESC 'Bad password attempt count' EQUALITY integerMatch SYNTAX 1.3.6.1.4.1
 .1466.115.121.1.27 SINGLE-VALUE )
olcattributetypes: {10}( 1.3.6.1.4.1.7165.2.1.49 NAME 'sambaBadPasswordTime'
  DESC 'Time of the last bad password attempt' EQUALITY integerMatch SYNTAX
 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )
olcattributetypes: {11}( 1.3.6.1.4.1.7165.2.1.55 NAME 'sambaLogonHours' DESC
  'Logon Hours' EQUALITY caseIgnoreIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.
 1.26{42} SINGLE-VALUE )
olcattributetypes: {12}( 1.3.6.1.4.1.7165.2.1.33 NAME 'sambaHomeDrive' DESC
 'Driver letter of home directory mapping' EQUALITY caseIgnoreIA5Match SYNTA
 X 1.3.6.1.4.1.1466.115.121.1.26{4} SINGLE-VALUE )
olcattributetypes: {13}( 1.3.6.1.4.1.7165.2.1.34 NAME 'sambaLogonScript' DES
 C 'Logon script path' EQUALITY caseIgnoreMatch SYNTAX 1.3.6.1.4.1.1466.115.
 121.1.15{255} SINGLE-VALUE )
olcattributetypes: {14}( 1.3.6.1.4.1.7165.2.1.35 NAME 'sambaProfilePath' DES
 C 'Roaming profile path' EQUALITY caseIgnoreMatch SYNTAX 1.3.6.1.4.1.1466.1
 15.121.1.15{255} SINGLE-VALUE )
olcattributetypes: {15}( 1.3.6.1.4.1.7165.2.1.36 NAME 'sambaUserWorkstations
 ' DESC 'List of user workstations the user is allowed to logon to' EQUALITY
  caseIgnoreMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{255} SINGLE-VALUE )
olcattributetypes: {16}( 1.3.6.1.4.1.7165.2.1.37 NAME 'sambaHomePath' DESC '
 Home directory UNC path' EQUALITY caseIgnoreMatch SYNTAX 1.3.6.1.4.1.1466.1
 15.121.1.15{128} )
olcattributetypes: {17}( 1.3.6.1.4.1.7165.2.1.38 NAME 'sambaDomainName' DESC
  'Windows NT domain to which the user belongs' EQUALITY caseIgnoreMatch SYN
 TAX 1.3.6.1.4.1.1466.115.121.1.15{128} )
olcattributetypes: {18}( 1.3.6.1.4.1.7165.2.1.47 NAME 'sambaMungedDial' DESC
  'Base64 encoded user parameter string' EQUALITY caseExactMatch SYNTAX 1.3.
 6.1.4.1.1466.115.121.1.15{1050} )
olcattributetypes: {19}( 1.3.6.1.4.1.7165.2.1.54 NAME 'sambaPasswordHistory'
  DESC 'Concatenated MD5 hashes of the salted NT passwords used on this acco
 unt' EQUALITY caseIgnoreIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{32} )
olcattributetypes: {20}( 1.3.6.1.4.1.7165.2.1.20 NAME 'sambaSID' DESC 'Secur
 ity ID' EQUALITY caseIgnoreIA5Match SUBSTR caseExactIA5SubstringsMatch SYNT
 AX 1.3.6.1.4.1.1466.115.121.1.26{64} SINGLE-VALUE )
olcattributetypes: {21}( 1.3.6.1.4.1.7165.2.1.23 NAME 'sambaPrimaryGroupSID'
  DESC 'Primary Group Security ID' EQUALITY caseIgnoreIA5Match SYNTAX 1.3.6.
 1.4.1.1466.115.121.1.26{64} SINGLE-VALUE )
olcattributetypes: {22}( 1.3.6.1.4.1.7165.2.1.51 NAME 'sambaSIDList' DESC 'S
 ecurity ID List' EQUALITY caseIgnoreIA5Match SYNTAX 1.3.6.1.4.1.1466.115.12
 1.1.26{64} )
olcattributetypes: {23}( 1.3.6.1.4.1.7165.2.1.19 NAME 'sambaGroupType' DESC
 'NT Group Type' EQUALITY integerMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27
 SINGLE-VALUE )
olcattributetypes: {24}( 1.3.6.1.4.1.7165.2.1.21 NAME 'sambaNextUserRid' DES
 C 'Next NT rid to give our for users' EQUALITY integerMatch SYNTAX 1.3.6.1.
 4.1.1466.115.121.1.27 SINGLE-VALUE )
olcattributetypes: {25}( 1.3.6.1.4.1.7165.2.1.22 NAME 'sambaNextGroupRid' DE
 SC 'Next NT rid to give out for groups' EQUALITY integerMatch SYNTAX 1.3.6.
 1.4.1.1466.115.121.1.27 SINGLE-VALUE )
olcattributetypes: {26}( 1.3.6.1.4.1.7165.2.1.39 NAME 'sambaNextRid' DESC 'N
 ext NT rid to give out for anything' EQUALITY integerMatch SYNTAX 1.3.6.1.4
 .1.1466.115.121.1.27 SINGLE-VALUE )
olcattributetypes: {27}( 1.3.6.1.4.1.7165.2.1.40 NAME 'sambaAlgorithmicRidBa
 se' DESC 'Base at which the samba RID generation algorithm should operate'
 EQUALITY integerMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )
olcattributetypes: {28}( 1.3.6.1.4.1.7165.2.1.41 NAME 'sambaShareName' DESC
 'Share Name' EQUALITY caseIgnoreMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15
 SINGLE-VALUE )
olcattributetypes: {29}( 1.3.6.1.4.1.7165.2.1.42 NAME 'sambaOptionName' DESC
  'Option Name' EQUALITY caseIgnoreMatch SUBSTR caseIgnoreSubstringsMatch SY
 NTAX 1.3.6.1.4.1.1466.115.121.1.15{256} )
olcattributetypes: {30}( 1.3.6.1.4.1.7165.2.1.43 NAME 'sambaBoolOption' DESC
  'A boolean option' EQUALITY booleanMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1
 .7 SINGLE-VALUE )
olcattributetypes: {31}( 1.3.6.1.4.1.7165.2.1.44 NAME 'sambaIntegerOption' D
 ESC 'An integer option' EQUALITY integerMatch SYNTAX 1.3.6.1.4.1.1466.115.1
 21.1.27 SINGLE-VALUE )
olcattributetypes: {32}( 1.3.6.1.4.1.7165.2.1.45 NAME 'sambaStringOption' DE
 SC 'A string option' EQUALITY caseExactIA5Match SYNTAX 1.3.6.1.4.1.1466.115
 .121.1.26 SINGLE-VALUE )
olcattributetypes: {33}( 1.3.6.1.4.1.7165.2.1.46 NAME 'sambaStringListOption
 ' DESC 'A string list option' EQUALITY caseIgnoreMatch SYNTAX 1.3.6.1.4.1.1
 466.115.121.1.15 )
olcattributetypes: {34}( 1.3.6.1.4.1.7165.2.1.53 NAME 'sambaTrustFlags' DESC
  'Trust Password Flags' EQUALITY caseIgnoreIA5Match SYNTAX 1.3.6.1.4.1.1466
 .115.121.1.26 )
olcattributetypes: {35}( 1.3.6.1.4.1.7165.2.1.58 NAME 'sambaMinPwdLength' DE
 SC 'Minimal password length (default: 5)' EQUALITY integerMatch SYNTAX 1.3.
 6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )
olcattributetypes: {36}( 1.3.6.1.4.1.7165.2.1.59 NAME 'sambaPwdHistoryLength
 ' DESC 'Length of Password History Entries (default: 0 => off)' EQUALITY in
 tegerMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )
olcattributetypes: {37}( 1.3.6.1.4.1.7165.2.1.60 NAME 'sambaLogonToChgPwd' D
 ESC 'Force Users to logon for password change (default: 0 => off, 2 => on)'
  EQUALITY integerMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )
olcattributetypes: {38}( 1.3.6.1.4.1.7165.2.1.61 NAME 'sambaMaxPwdAge' DESC
 'Maximum password age, in seconds (default: -1 => never expire passwords)'
 EQUALITY integerMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )
olcattributetypes: {39}( 1.3.6.1.4.1.7165.2.1.62 NAME 'sambaMinPwdAge' DESC
 'Minimum password age, in seconds (default: 0 => allow immediate password c
 hange)' EQUALITY integerMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-V
 ALUE )
olcattributetypes: {40}( 1.3.6.1.4.1.7165.2.1.63 NAME 'sambaLockoutDuration'
  DESC 'Lockout duration in minutes (default: 30, -1 => forever)' EQUALITY i
 ntegerMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )
olcattributetypes: {41}( 1.3.6.1.4.1.7165.2.1.64 NAME 'sambaLockoutObservati
 onWindow' DESC 'Reset time after lockout in minutes (default: 30)' EQUALITY
  integerMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )
olcattributetypes: {42}( 1.3.6.1.4.1.7165.2.1.65 NAME 'sambaLockoutThreshold
 ' DESC 'Lockout users after bad logon attempts (default: 0 => off)' EQUALIT
 Y integerMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )
olcattributetypes: {43}( 1.3.6.1.4.1.7165.2.1.66 NAME 'sambaForceLogoff' DES
 C 'Disconnect Users outside logon hours (default: -1 => off, 0 => on)' EQUA
 LITY integerMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )
olcattributetypes: {44}( 1.3.6.1.4.1.7165.2.1.67 NAME 'sambaRefuseMachinePwd
 Change' DESC 'Allow Machine Password changes (default: 0 => off)' EQUALITY
 integerMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )
olcattributetypes: {45}( 1.3.6.1.4.1.7165.2.1.68 NAME 'sambaClearTextPasswor
 d' DESC 'Clear text password (used for trusted domain passwords)' EQUALITY
 octetStringMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.40 )
olcattributetypes: {46}( 1.3.6.1.4.1.7165.2.1.69 NAME 'sambaPreviousClearTex
 tPassword' DESC 'Previous clear text password (used for trusted domain pass
 words)' EQUALITY octetStringMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.40 )
olcobjectclasses: {0}( 1.3.6.1.4.1.7165.2.2.6 NAME 'sambaSamAccount' DESC 'S
 amba 3.0 Auxilary SAM Account' SUP top AUXILIARY MUST ( uid $ sambaSID ) MA
 Y ( cn $ sambaLMPassword $ sambaNTPassword $ sambaPwdLastSet $ sambaLogonTi
 me $ sambaLogoffTime $ sambaKickoffTime $ sambaPwdCanChange $ sambaPwdMustC
 hange $ sambaAcctFlags $ displayName $ sambaHomePath $ sambaHomeDrive $ sam
 baLogonScript $ sambaProfilePath $ description $ sambaUserWorkstations $ sa
 mbaPrimaryGroupSID $ sambaDomainName $ sambaMungedDial $ sambaBadPasswordCo
 unt $ sambaBadPasswordTime $ sambaPasswordHistory $ sambaLogonHours ) )
olcobjectclasses: {1}( 1.3.6.1.4.1.7165.2.2.4 NAME 'sambaGroupMapping' DESC
 'Samba Group Mapping' SUP top AUXILIARY MUST ( gidNumber $ sambaSID $ samba
 GroupType ) MAY ( displayName $ description $ sambaSIDList ) )
olcobjectclasses: {2}( 1.3.6.1.4.1.7165.2.2.14 NAME 'sambaTrustPassword' DES
 C 'Samba Trust Password' SUP top STRUCTURAL MUST ( sambaDomainName $ sambaN
 TPassword $ sambaTrustFlags ) MAY ( sambaSID $ sambaPwdLastSet ) )
olcobjectclasses: {3}( 1.3.6.1.4.1.7165.2.2.15 NAME 'sambaTrustedDomainPassw
 ord' DESC 'Samba Trusted Domain Password' SUP top STRUCTURAL MUST ( sambaDo
 mainName $ sambaSID $ sambaClearTextPassword $ sambaPwdLastSet ) MAY sambaP
 reviousClearTextPassword )
olcobjectclasses: {4}( 1.3.6.1.4.1.7165.2.2.5 NAME 'sambaDomain' DESC 'Samba
  Domain Information' SUP top STRUCTURAL MUST ( sambaDomainName $ sambaSID )
  MAY ( sambaNextRid $ sambaNextGroupRid $ sambaNextUserRid $ sambaAlgorithm
 icRidBase $ sambaMinPwdLength $ sambaPwdHistoryLength $ sambaLogonToChgPwd
 $ sambaMaxPwdAge $ sambaMinPwdAge $ sambaLockoutDuration $ sambaLockoutObse
 rvationWindow $ sambaLockoutThreshold $ sambaForceLogoff $ sambaRefuseMachi
 nePwdChange ) )
olcobjectclasses: {5}( 1.3.6.1.4.1.7165.2.2.7 NAME 'sambaUnixIdPool' DESC 'P
 ool for allocating UNIX uids/gids' SUP top AUXILIARY MUST ( uidNumber $ gid
 Number ) )
olcobjectclasses: {6}( 1.3.6.1.4.1.7165.2.2.8 NAME 'sambaIdmapEntry' DESC 'M
 apping from a SID to an ID' SUP top AUXILIARY MUST sambaSID MAY ( uidNumber
  $ gidNumber ) )
olcobjectclasses: {7}( 1.3.6.1.4.1.7165.2.2.9 NAME 'sambaSidEntry' DESC 'Str
 uctural Class for a SID' SUP top STRUCTURAL MUST sambaSID )
olcobjectclasses: {8}( 1.3.6.1.4.1.7165.2.2.10 NAME 'sambaConfig' DESC 'Samb
 a Configuration Section' SUP top AUXILIARY MAY description )
olcobjectclasses: {9}( 1.3.6.1.4.1.7165.2.2.11 NAME 'sambaShare' DESC 'Samba
  Share Section' SUP top STRUCTURAL MUST sambaShareName MAY description )
olcobjectclasses: {10}( 1.3.6.1.4.1.7165.2.2.12 NAME 'sambaConfigOption' DES
 C 'Samba Configuration Option' SUP top STRUCTURAL MUST sambaOptionName MAY
 ( sambaBoolOption $ sambaIntegerOption $ sambaStringOption $ sambaStringLis
 toption $ description ) )
}}}


=== with slapd.conf (old style, still possible in squeeze) ===

{{{
 zcat /usr/share/doc/samba-doc/examples/LDAP/samba.schema.gz > /etc/ldap/schema/samba.schema
}}}


Now add the following line to /etc/ldap/slapd.conf after the other includes.
 aptitude install samba
}}}

Copy example samba.schema to ldap configuration directory:
{{{
 zcat /usr/share/doc/samba/examples/LDAP/samba.schema.gz > /etc/ldap/schema/samba.schema
}}}


=== with slapd.conf ===

Add the following line to /etc/ldap/slapd.conf after the other includes.
Line 361: Line 359:
}}}

=== with cn=config ===

Create a temporary config file samba.conf:
{{{
  include /etc/ldap/schema/core.schema
  include /etc/ldap/schema/cosine.schema
  include /etc/ldap/schema/nis.schema
  include /etc/ldap/schema/inetorgperson.schema
  include /etc/ldap/schema/samba.schema
}}}

Convert samba.schema into samba.ldif with slaptest:
{{{
  # mkdir /tmp/slapd.d
  # slaptest -f samba.conf -F /tmp/slapd.d/
}}}

Load the /tmp/slapd.d/cn=config/cn=schema/cn={4}samba.ldif into your cn=config using:

{{{
  # cp "/tmp/slapd.d/cn=config/cn=schema/cn={4}samba.ldif" "/etc/ldap/slapd.d/cn=config/cn=schema"
  # chown openldap: '/etc/ldap/slapd.d/cn=config/cn=schema/cn={4}samba.ldif'
  # /etc/init.d/slapd stop
  # /etc/init.d/slapd start
}}}

and check you now see the new samba schema:

{{{
# ldapsearch -LLLQY EXTERNAL -H ldapi:/// -b cn=schema,cn=config "(objectClass=olcSchemaConfig)" dn
dn: cn=schema,cn=config

dn: cn={0}core,cn=schema,cn=config

dn: cn={1}cosine,cn=schema,cn=config

dn: cn={2}nis,cn=schema,cn=config

dn: cn={3}inetorgperson,cn=schema,cn=config

dn: cn={4}samba,cn=schema,cn=config
Line 376: Line 417:
== Configuring LDAPS ==

First, you must enable ldaps port in /etc/default/slapd :

{{{
SLAPD_SERVICES="ldap://127.0.0.1:389/ ldaps:/// ldapi:///"
}}}

Configuring the certificate (and possibly the CA used) in slapd config :

in /etc/ldap/slapd.conf:

{{{
TLSCACertificateFile /etc/ssl/certs/cacert.pem
TLSCertificateKeyFile /etc/ssl/private/server-key.pem
TLSCertificateFile /etc/ssl/certs/server-cert.pem
}}}

or add attributes to cn=config:
{{{
dn: cn=config
add: olcTLSCACertificateFile
olcTLSCACertificateFile: /etc/ssl/certs/cacert.pem
-
add: olcTLSCertificateKeyFile
olcTLSCertificateKeyFile: /etc/ssl/private/server-key.pem
-
add: olcTLSCertificateFile
olcTLSCertificateFile: /etc/ssl/certs/server-cert.pem
}}}

By default, slapd runs as user/group openldap, so it can't read the key file. On Debian Lenny, the preferred solution to this dilemma seems to be to chown the key to root:ssl-cert, set permissions to 640 and add the user openldap to group ssl-cert.
== Configuring TLS/SSL ==

By default, slapd runs as user/group openldap, so it can't read the key file. On Debian Lenny, the preferred solution to this dilemma seems to be to chown the key to root:ssl-cert, set permissions to 640 and add the user openldap to group ssl-cert:
{{{
usermod -a -G ssl-cert openldap
}}}
 In Wheezy, not adding openldap to the ssl-cert group caused this in logs:
{{{
main: TLS init def ctx failed: -1
}}}

=== Enable LDAPS (if required) ===

StartTLS is the standard operation for initiating TLS/SSL on an LDAP connection. StartTLS operates on the standard LDAP port (389) and no alternative port is necessary.

Clients using OpenLDAP libldap can be configured to use StartTLS, if they use an LDAP URL for connection configuration, by including the StartTLS extension in the URL. For example:

{{{
ldap://ldap.example.com/dc=example,dc=com????!StartTLS
}}}

The {{{ldapurl(1)}}} tool is useful for constructing correct LDAP URLs.

Some legacy LDAP clients do not support the StartTLS operation, but are able to use LDAPS (LDAP over SSL) on port 636. To support such clients, add {{{ldaps:///}}} to the {{{SLAPD_SERVICES}}} list in {{{/etc/default/slapd}}}.

{{{
SLAPD_SERVICES="ldap:/// ldapi:/// ldaps:///"
}}}
Line 422: Line 459:

  
Line 426: Line 460:
In squeeze we had the same error , and it was solved by adding openldap to the ssl-cert group.
{{{
usermod -a -G ssl-cert openldap
}}}

Line 459: Line 487:
}}}  }}}
Line 467: Line 495:
How did you generate your certificates? If you generated them using OpenSSL, you're going to run into problems. Debian switched over to using gnutls a while ago, and it doesn't play nice with OpenSSL certificates. So, to fix this, check out the next section.  How did you generate your certificates? If you generated them using OpenSSL, you're going to run into problems. Debian switched over to using gnutls a while ago, and it doesn't play nice with OpenSSL certificates. So, to fix this, check out the next section.
Line 471: Line 499:
NOTE about the above note: I don't find it to be the case, except for the CA cert. I ended up having to generate a new key & csr to sign with gnutls's certtool and then signing it with my existing openssl created CA like so:
{{{
certtool --generate-privkey --outfile ldap.gnutls.key
certtool --generate-certificate --load-privkey ldap.gnutls.key --outfile ldap.gnutls.crt --load-ca-certificate ca.crt --load-ca-privkey ca.key
}}}
Again, this allows you to keep your existing OpenSSL CA.

Line 472: Line 508:
You're going to need the gnutls certificate generator: [[http://www.gnu.org/software/gnutls/manual/html_node/Invoking-certtool.html|certtool]]. You're going to need the gnutls certificate generator: [[http://www.gnu.org/software/gnutls/manual/html_node/The-certtool-application.html|certtool]] available in DebPkg:gnutls-bin
Line 488: Line 524:
== Configuring MirrorMode LDAP Sync Replication (syncrepl) ==
See [[http://www.openldap.org/doc/admin24/replication.html]] for a clear explanation of OpenLDAP Replication. Several types of replication are possible, this section focusses on how to configure !MirrorMode Replication.

=== with slapd.conf ===
See the aforementioned [[http://www.openldap.org/doc/admin24/replication.html]] for a clear explanation on how to configure !MirrorMode LDAP Sync Replication (syncrepl) using the old slapd.conf syntax. No need to repeat this here.

=== with cn=config ===
!MirrorMode LDAP Sync Replication (syncrepl) is achieved by following the seven small steps below.

==== 1: Create a special user for the replication of the data. ====
This by default can't be done using the SASL/EXTERNAL authentication, since you will get a 'no write access to parent' error. Please use a basedn suited to your situation, in example change the "dc=nodomain" to the basedn for your server. Please see step 7 for the password chosen and use {{{slappasswd}}} command to format it.
{{{
$ ldapmodify -D "cn=admin,dc=nodomain" -W<<EOT
> dn: cn=mirrormode,dc=nodomain
> changetype: add
> objectClass: simpleSecurityObject
> objectClass: organizationalRole
> cn: mirrormode
> description: Syncrepl user for mirrormode operation
> userPassword: e1NTSEF9SktNQmpPV29zOEtPSCtaWmdDeTVUa056U3c5NWF5bis=
> EOT
Enter LDAP Password:
adding new entry "cn=mirrormode,dc=nodomain"

$
}}}

All the other steps can easily be done using the SASL/EXTERNAL authentication as explained in [[https://wiki.debian.org/LDAP/OpenLDAPSetup#Missing_slapd.conf.3F|Missing slapd.conf]]. Just save the given information in a file and load it with: $ ldapmodify -Y EXTERNAL -H ldapi:/// -f <file.ldif>

==== 2: Load the syncrepl module ====
{{{
dn: cn=module{0},cn=config
changetype: modify
add: olcModuleLoad
olcModuleLoad: syncprov
}}}


==== 3: Set up replicator privileges ====
Make sure the newly created replication user can read the data to be replicated:
{{{
dn: olcDatabase={1}hdb,cn=config
changetype: modify
delete: olcAccess
olcAccess: {0}to attrs=userPassword,shadowLastChange by self write by anonymous auth by dn="cn=admin,dc=nodomain" write by * none
-
add: olcAccess
olcAccess: {0}to attrs=userPassword,shadowLastChange by self write by anonymous auth by dn="cn=admin,dc=nodomain" write by dn="cn=mirrormode,dc=nodomain" read by * none
-
}}}

==== 4: Set up the provider slapd ====
{{{
dn: olcOverlay=syncprov,olcDatabase={1}hdb,cn=config
changeType: add
objectClass: olcOverlayConfig
objectClass: olcSyncProvConfig
olcOverlay: syncprov
olcSpCheckpoint: 100 10
olcSpSessionLog: 100
}}}

==== 5: Set up indexing for entryUUID ====
Note that using the session log requires searching on the entryUUID attribute. Setting an eq index on this attribute will greatly benefit the performance of the session log on the provider:
{{{
dn: olcDatabase={1}hdb,cn=config
changeType: modify
delete: olcDbIndex
olcDbIndex: objectClass eq
-
add: olcDbIndex
olcDbIndex: objectClass,entryCSN,entryUUID eq
-
}}}

==== 6: Set the server ID. ====
Make sure you use different ID's for different servers, in example 0, 1, etc...:
{{{
dn: cn=config
changeType: modify
add: olcServerID
olcServerID: 0
-
}}}

==== 7: Enable the replication. ====
Make sure you use the correct IP number for each ldap server and make sure they point to each other! Also, the credentials are just an example. Choose a password of your own of course:
{{{
dn: olcDatabase={1}hdb,cn=config
changeType: modify
add: olcSyncrepl
olcSyncrepl: rid=001 provider=ldap://172.16.42.74:389 bindmethod=simple binddn="cn=mirrormode,dc=nodomain" credentials=_ei7N8o.gh=o44 searchbase="dc=nodomain" schemachecking=on type=refreshAndPersist retry="60 +"
-
add: olcMirrorMode
olcMirrorMode: TRUE
-
}}}

And you're up and running. Try adding something to one of the LDAP servers and see it appear automagically at the other. Well done my friend!
Line 489: Line 625:
CategorySystemAdministration
CategorySystemAdministration | CategorySoftware | CategoryObsolete ToDo: refactor

OpenLDAP is an open source implementation of the Lightweight Directory Access Protocol. It includes libraries, clients, and a server. This page is about running the OpenLDAP Standalone LDAP Daemon slapd on Debian.

FixMe: update for (Buster/Bullseye) defaults and recommendations

ToDo: update for Buster/Bullseye; review, organize, refactor; consider moving specific topics (e.g. Samba) to separate pages

Documentation and resources

Installing and configuring the OpenLDAP server

The OpenLDAP server package is slapd. The recommended tools for configuring slapd and setting up your directory are ldap-utils.

apt install slapd ldap-utils

You will be prompted to provide a password for the database administrator.

By default, an initial database is created in /var/lib/ldap and configured using the system's DNS domain name. If your system is in the domain example.com, the database suffix is dc=example,dc=com and the administrator is named cn=admin,dc=example,dc=com. The domain name and other details can be changed by preseeding, by running the installation at a different debconf(7) priority, or by running dpkg-reconfigure slapd after installation.

To check the database suffix, once the server is running, use ldapsearch(1) to read the namingContexts attribute of the root DSE:

ldapsearch -x -s base -b "" namingContexts

Tour of the installation

The following are the key files and directories installed by the slapd package:

  • slapd(8) and the associated tools such as slapadd(8), slapcat(8), slapindex(8), and others are installed in /usr/sbin.

  • The loadable modules included with slapd are installed in /usr/lib/ldap.

  • LDAP Schema files included with slapd or other packages are installed in /etc/ldap/schema.

    • Files ending in .schema can be included into a legacy slapd.conf file. By default, the Debian setup does not use these files.

    • Files ending in .ldif can be imported into the configuration using ldapadd(1). This copies them into the configuration database and the source files are no longer used afterward.

  • The configuration database cn=config is stored in /etc/ldap/slapd.d, owned by the openldap user.

  • The default database is stored in /var/lib/ldap, owned by the openldap user.

The configuration is stored in an LDAP database rooted at cn=config. Many configuration changes can be made online, while slapd is running, using LDAP operations on this database. Debian's default access rules allow access by the system root user only. root may query or search the database using ldapsearch(1) with SASL EXTERNAL authentication:

ldapsearch -H ldapi:/// -Y EXTERNAL -b "cn=config"

The package sets up a default directory based on the system's DNS domain. Debian's default access rules allow anyone to search this directory without any authentication:

ldapsearch -x -b "dc=example,dc=com"

To connect as the database administrator, use Simple authentication, and when prompted, enter the password configured during installation:

ldapsearch -x -D "cn=admin,dc=example,dc=com" -W -b "dc=example,dc=com"

Basic tasks

Enable request logging

The server logs are sent to the system log (syslog and/or the journal). The default log level is none.

To enable basic request logging, change the log level to stats:

ldapmodify -H ldapi:/// -Y EXTERNAL << EOF
dn: cn=config
changetype: modify
replace: olcLogLevel
olcLogLevel: stats

EOF

If you wish to disable request logging later, repeat the procedure and set the log level back to none.

For more information, read about olcLogLevel in the slapd-config(5) man page.

Enable TLS/SSL

To enable TLS in slapd, you will need the server certificate and the associated private key, both in PEM format. You may also have an intermediate certificate. Clients will need the CA certificate which is the Issuer of the server or intermediate certificate.

The files must all be readable by the openldap user. It is recommended to ensure the private key is not readable by any user except openldap.

To configure the server certificate, private key, and intermediate certificate used by slapd:

ldapmodify -H ldapi:/// -Y EXTERNAL << EOF
dn: cn=config
changetype: modify
replace: olcTLSCertificateFile
olcTLSCertificateFile: /etc/ssl/certs/server.pem
-
replace: olcTLSCertificateKeyFile
olcTLSCertificateKeyFile: /etc/ssl/private/server.key
-
replace: olcTLSCACertificateFile
olcTLSCACertificateFile: /etc/ssl/certs/intermediate.pem

EOF

If you do not have an intermediate certificate, the olcTLSCACertificate lines should be omitted. The root CA does not need to be configured in slapd.

If the modifications fail with ldap_modify: Other (e.g., implementation specific) error (80), check the file paths for typos, and ensure the files are readable by the openldap user.

After applying the configuration, test a secure connection using StartTLS:

LDAPTLS_CACERT=/etc/ssl/certs/ca.pem ldapwhoami -H ldap://ldap.example.com -ZZ -x

where ca.pem is the root CA certificate and ldap.example.com is the server's name, exactly matching the Common Name (CN) or Subject Alternative Name (SAN) in the server certificate.

If the secure connection is successful, ldapwhoami should just print anonymous. If it fails, append -d 1 to the command line to enable debug output, and look for lines beginning with TLS:.

By default, slapd supports StartTLS on the standard LDAP port 389. If you wish to enable the LDAPS protocol on port 636, then edit /etc/default/slapd, add ldaps:/// to the SLAPD_SERVICES line, and restart slapd.

vi /etc/default/slapd

...
SLAPD_SERVICES="ldap:/// ldapi:/// ldaps:///"
...

service slapd restart

LDAPS can be tested the same way, using -H ldaps:// instead of -ZZ:

LDAPTLS_CACERT=/etc/ssl/certs/ca.pem ldapwhoami -H ldaps://ldap.example.com -x

Again, if successful, it should just print anonymous.

For more information, read about TLS Options in the slapd-config(5) man page, noting that the TLS implementation used in Debian is GnuTLS. The OpenLDAP Administrator's Guide also has a chapter about TLS.

Check and configure the database max size

The default database uses the LMDB storage backend. This backend requires little configuration or tuning, but there is one important parameter: the max size.

The database is stored in a sparse file, /var/lib/ldap/data.mdb. It has a fixed maximum size, specified by the olcDbMaxSize parameter. The default database has its max size configured to 1 GiB upon installation. When the database reaches its max size, writes (even updates to existing entries) will fail.

Use du(1) to check the actual space used by the database:

du -h /var/lib/ldap/data.mdb

To check the current max size of database #1:

ldapsearch -H ldapi:/// -Y EXTERNAL -b "olcDatabase={1}mdb,cn=config" olcDbMaxSize

To set the max size of database #1 to 10 GiB (10737418240 bytes):

ldapmodify -H ldapi:/// -Y EXTERNAL << EOF
dn: olcDatabase={1}mdb,cn=config
changetype: modify
replace: olcDbMaxSize
olcDbMaxSize: 10737418240

EOF

On 32-bit systems, the max size is constrained by address space limitations, and it may not be possible to grow the database larger than about 2 GiB. For larger databases, a 64-bit system is recommended.

For more information, read about maxsize in slapd-mdb(5).

Change the administrator's password

The password configured during installation is saved in two places. To change the password, both values must be updated. If only one is changed, the old password can still be used. This should be fixed in the next release; see Debian bug #821331.

Use slappasswd(8) to hash the new password, and then use ldapmodify(1) to update the hashed password in the olcRootPW attribute in the database configuration.

# slappasswd
New password: newpassword
Re-enter new password: newpassword
{SSHA}zYHmkowzdMxwX0KtEPNak5IbzfY8YmdQ
# ldapmodify -H ldapi:/// -Y EXTERNAL
SASL/EXTERNAL authentication started
SASL username: gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth
SASL SSF: 0
dn: olcDatabase={1}mdb,cn=config
changetype: modify
replace: olcRootPW
olcRootPW: {SSHA}zYHmkowzdMxwX0KtEPNak5IbzfY8YmdQ

modifying entry "olcDatabase={1}mdb,cn=config"

Next, use ldappasswd(1) to change the password the administrator's account in the directory.

# ldappasswd -x -D cn=admin,dc=example,dc=com -W -S
New password: newpassword
Re-enter new password: newpassword
Enter LDAP Password: oldpassword

Finally, test authenticating with the old and new passwords, and confirm that only the new password can be used.

# ldapwhoami -x -D cn=admin,dc=example,dc=com -W
Enter LDAP Password: oldpassword
ldap_bind: Invalid credentials (49)
# ldapwhoami -x -D cn=admin,dc=example,dc=com -W
Enter LDAP Password: newpassword
dn:cn=admin,dc=example,dc=com

Advanced tasks

Indexes

For better performance do more indexing than the default.

with slapd.conf

Create or modify /etc/ldap/slapd.conf to contain the following:

index   objectClass             eq
index   cn                      pres,sub,eq
index   sn                      pres,sub,eq
index   uid                     pres,sub,eq
index   displayName             pres,sub,eq
index   default                 sub
index   uidNumber               eq
index   gidNumber               eq
index   mail,givenName          eq,subinitial
index   dc                      eq

After any new indexes have been defined or other major database changes have been made (e.g. slapadd was used) it is best to recreate the indexes. Note that you should stop slapd before recreating the indexes and should fix the permissions afterward.

  # service slapd stop
  # sudo -u openldap slapindex
  # service slapd start

with cn=config

Create a LDIF file in /etc/ldap : olcDbIndex.ldif

dn: olcDatabase={1}mdb,cn=config
changetype: modify
add: olcDbIndex
olcDbIndex: cn pres,sub,eq
-
add: olcDbIndex
olcDbIndex: sn pres,sub,eq
-
add: olcDbIndex
olcDbIndex: uid pres,sub,eq
-
add: olcDbIndex
olcDbIndex: displayName pres,sub,eq
-
add: olcDbIndex
olcDbIndex: default sub
-
add: olcDbIndex
olcDbIndex: uidNumber eq
-
add: olcDbIndex
olcDbIndex: gidNumber eq
-
add: olcDbIndex
olcDbIndex: mail,givenName eq,subinitial
-
add: olcDbIndex
olcDbIndex: dc eq

Note: use the correct database format in the first line, the default type during installation of slapd is mdb.

Use ldapmodify to add the indexing settings to the ldap :

ldapmodify -Y EXTERNAL -H ldapi:/// -f ./olcDbIndex.ldif

Do not leave out the - (dash character) from the file, it is needed. After execution of the ldapmodify command, slapd will launch a internal task to create indexes. Don't stop slapd during indexing.

Access control

Configuring 'chsh' and 'chfn' to work with LDAP

with slapd.conf

Edit '/etc/ldap/slapd.conf' to allow access for users to update their loginShell and gecos entries by adding the following before the 'access to *' entry:

access to attrs=loginShell,gecos
      by dn="cn=admin,dc=example,dc=com" write
      by self write
      by * read

with cn=config

Create a LDIF file olcAccess.ldif with access permissions to loginShell and gecos entries for the user and admins :

dn: olcDatabase={1}hdb,cn=config
changetype: modify
add: olcAccess
olcAccess: {1}to attrs=loginShell,gecos
  by dn="cn=admin,dc=example,dc=com" write
  by self write
  by * read

Instanty apply these new permissions to ldap with :

ldapmodify -Y EXTERNAL -H ldapi:/// -f ./olcAccess.ldif

For SAMBA LDAP support

For Samba LDAP, slapd needs the Samba schema. The Debian package seems to have a samba.schema file which is old and out of date, and a samba.schema.gz file which is actually the correct one. Do the following (as root):

 # this package contains samba.schema.gz :
 aptitude install samba

Copy example samba.schema to ldap configuration directory:

 zcat /usr/share/doc/samba/examples/LDAP/samba.schema.gz > /etc/ldap/schema/samba.schema

with slapd.conf

Add the following line to /etc/ldap/slapd.conf after the other includes.

include /etc/ldap/schema/samba.schema

And restart slapd:

  # /etc/init.d/slapd restart

with cn=config

Create a temporary config file samba.conf:

  include          /etc/ldap/schema/core.schema
  include          /etc/ldap/schema/cosine.schema
  include          /etc/ldap/schema/nis.schema
  include          /etc/ldap/schema/inetorgperson.schema
  include          /etc/ldap/schema/samba.schema

Convert samba.schema into samba.ldif with slaptest:

  # mkdir /tmp/slapd.d
  # slaptest -f samba.conf -F /tmp/slapd.d/

Load the /tmp/slapd.d/cn=config/cn=schema/cn={4}samba.ldif into your cn=config using:

  # cp "/tmp/slapd.d/cn=config/cn=schema/cn={4}samba.ldif" "/etc/ldap/slapd.d/cn=config/cn=schema"
  # chown openldap: '/etc/ldap/slapd.d/cn=config/cn=schema/cn={4}samba.ldif'
  # /etc/init.d/slapd stop
  # /etc/init.d/slapd start

and check you now see the new samba schema:

# ldapsearch -LLLQY EXTERNAL -H ldapi:/// -b cn=schema,cn=config "(objectClass=olcSchemaConfig)" dn
dn: cn=schema,cn=config

dn: cn={0}core,cn=schema,cn=config

dn: cn={1}cosine,cn=schema,cn=config

dn: cn={2}nis,cn=schema,cn=config

dn: cn={3}inetorgperson,cn=schema,cn=config

dn: cn={4}samba,cn=schema,cn=config

Access controls for subtree-specific LDAP Admins

If you choose to use LDAP for many functions, such as having a single server for DNS, Authentication, and networking flat file database replacement, you may wish to have LDAP administrative users for each subtree in addition to the global admin (dn="cn=admin, dc=example, dc=com). The following example is useful when using a separate authentication tree which includes Samba.

 # The manager dn has full write access to the auth subtree
 # Everyone else has read access to not otherwise protected fields and entries
 access to dn.sub="ou=auth,dc=example,dc=com"
         by dn="cn=Manager,ou=auth,dc=example,dc=com" write
         by * read

Configuring TLS/SSL

By default, slapd runs as user/group openldap, so it can't read the key file. On Debian Lenny, the preferred solution to this dilemma seems to be to chown the key to root:ssl-cert, set permissions to 640 and add the user openldap to group ssl-cert:

usermod -a -G ssl-cert openldap
  • In Wheezy, not adding openldap to the ssl-cert group caused this in logs:

main: TLS init def ctx failed: -1

Enable LDAPS (if required)

StartTLS is the standard operation for initiating TLS/SSL on an LDAP connection. StartTLS operates on the standard LDAP port (389) and no alternative port is necessary.

Clients using OpenLDAP libldap can be configured to use StartTLS, if they use an LDAP URL for connection configuration, by including the StartTLS extension in the URL. For example:

ldap://ldap.example.com/dc=example,dc=com????!StartTLS

The ldapurl(1) tool is useful for constructing correct LDAP URLs.

Some legacy LDAP clients do not support the StartTLS operation, but are able to use LDAPS (LDAP over SSL) on port 636. To support such clients, add ldaps:/// to the SLAPD_SERVICES list in /etc/default/slapd.

SLAPD_SERVICES="ldap:/// ldapi:/// ldaps:///"

Symptoms:

In slapd debug output:

[...] TLS: could not set cipher list HIGH:MEDIUM:-SSLv2.  (or similar)

In /var/log/syslog:

[...] main: TLS init def ctx failed: -1

Diagnosis:

If you try to install the OpenLDAP server (slapd) with Debian Lenny, it comes compiled against the GnuTLS library. It means you cannot use an OpenSSL style directive like TLSCipherSuite HIGH:MEDIUM:-SSLv2 in slapd.conf.

Cure:

In /etc/ldap/slapd.conf, either comment out TLSCipherSuite option to let gnutls choose rather sane default for you, or use something like:

TLSCipherSuite NORMAL

To get all the supported GnuTLS cipher suite names:

# aptitude install gnutls-bin
# man gnutls-cli

And skip to TLS/SSL control options section of man page.

To use only 256 bit cyphers, use this (paranoiac?) setting:

TLSCipherSuite SECURE256:!AES-128-CBC:!ARCFOUR-128:!CAMELLIA-128-CBC:!3DES-CBC:!CAMELLIA-128-CBC

Another useful tool to test server-supported TLS options is to use gnutls-cli-debug. First add ldaps:/// string to the SLAPD_SERVICES option in /etc/default/slapd, restart slapd and then run

gnutls-cli-debug -p 636 <fqdn_of_you_ldap_host>

That will show you cryptographic suits your LDAP server supports.

Symptoms (round 2)

If you are getting messages such as

slapd TLS: can't connect: A TLS packet with unexpected length was received..

or

Could not negotiate a supported cipher suite.

take a wander by this.

Diagnosis:

How did you generate your certificates? If you generated them using OpenSSL, you're going to run into problems. Debian switched over to using gnutls a while ago, and it doesn't play nice with OpenSSL certificates. So, to fix this, check out the next section.

NOTE: On Debian Squeeze openldap is linked with gnutls as well, but works just fine with certificate generated by openssl.

NOTE about the above note: I don't find it to be the case, except for the CA cert. I ended up having to generate a new key & csr to sign with gnutls's certtool and then signing it with my existing openssl created CA like so:

certtool --generate-privkey --outfile ldap.gnutls.key
certtool --generate-certificate --load-privkey ldap.gnutls.key --outfile ldap.gnutls.crt --load-ca-certificate ca.crt --load-ca-privkey ca.key

Again, this allows you to keep your existing OpenSSL CA.

Procedure:

You're going to need the gnutls certificate generator: certtool available in gnutls-bin

Run these two commands to generate a new self-signed key (into the current working directory):

certtool --generate-privkey --outfile ca-key.pem
certtool --generate-self-signed --load-privkey ca-key.pem --outfile ca-cert.pem

Then, update your certificate locations in /etc/ldap/slapd.conf (TLSCertificateFile points to ca-cert.pem and TLSCertificateKeyFile points to ca-key.pem), comment out TLSCACertificateFile, and change TLSVerifyClient to never.

In /etc/ldap/ldap.conf, comment out TLS_CACERT and change TLS_REQCERT to never.

Since the certificate is self-signed, we can't have gnutls trying to verify it (hence the never), otherwise it will never run.

Then restart your services, and you're good (assuming all your links point properly to ldaps://url/).

Configuring MirrorMode LDAP Sync Replication (syncrepl)

See http://www.openldap.org/doc/admin24/replication.html for a clear explanation of OpenLDAP Replication. Several types of replication are possible, this section focusses on how to configure MirrorMode Replication.

with slapd.conf

See the aforementioned http://www.openldap.org/doc/admin24/replication.html for a clear explanation on how to configure MirrorMode LDAP Sync Replication (syncrepl) using the old slapd.conf syntax. No need to repeat this here.

with cn=config

MirrorMode LDAP Sync Replication (syncrepl) is achieved by following the seven small steps below.

1: Create a special user for the replication of the data.

This by default can't be done using the SASL/EXTERNAL authentication, since you will get a 'no write access to parent' error. Please use a basedn suited to your situation, in example change the "dc=nodomain" to the basedn for your server. Please see step 7 for the password chosen and use slappasswd command to format it.

$ ldapmodify -D "cn=admin,dc=nodomain" -W<<EOT
> dn: cn=mirrormode,dc=nodomain
> changetype: add
> objectClass: simpleSecurityObject
> objectClass: organizationalRole
> cn: mirrormode
> description: Syncrepl user for mirrormode operation
> userPassword: e1NTSEF9SktNQmpPV29zOEtPSCtaWmdDeTVUa056U3c5NWF5bis=
> EOT
Enter LDAP Password:
adding new entry "cn=mirrormode,dc=nodomain"

$

All the other steps can easily be done using the SASL/EXTERNAL authentication as explained in Missing slapd.conf. Just save the given information in a file and load it with: $ ldapmodify -Y EXTERNAL -H ldapi:/// -f <file.ldif>

2: Load the syncrepl module

dn: cn=module{0},cn=config
changetype: modify
add: olcModuleLoad
olcModuleLoad: syncprov

3: Set up replicator privileges

Make sure the newly created replication user can read the data to be replicated:

dn: olcDatabase={1}hdb,cn=config
changetype: modify
delete: olcAccess
olcAccess: {0}to attrs=userPassword,shadowLastChange by self write by anonymous auth by dn="cn=admin,dc=nodomain" write by * none
-
add: olcAccess
olcAccess: {0}to attrs=userPassword,shadowLastChange by self write by anonymous auth by dn="cn=admin,dc=nodomain" write by dn="cn=mirrormode,dc=nodomain" read by * none
-

4: Set up the provider slapd

dn: olcOverlay=syncprov,olcDatabase={1}hdb,cn=config
changeType: add
objectClass: olcOverlayConfig
objectClass: olcSyncProvConfig
olcOverlay: syncprov
olcSpCheckpoint: 100 10
olcSpSessionLog: 100

5: Set up indexing for entryUUID

Note that using the session log requires searching on the entryUUID attribute. Setting an eq index on this attribute will greatly benefit the performance of the session log on the provider:

dn: olcDatabase={1}hdb,cn=config
changeType: modify
delete: olcDbIndex
olcDbIndex: objectClass eq
-
add: olcDbIndex
olcDbIndex: objectClass,entryCSN,entryUUID eq
-

6: Set the server ID.

Make sure you use different ID's for different servers, in example 0, 1, etc...:

dn: cn=config
changeType: modify
add: olcServerID
olcServerID: 0
-

7: Enable the replication.

Make sure you use the correct IP number for each ldap server and make sure they point to each other! Also, the credentials are just an example. Choose a password of your own of course:

dn: olcDatabase={1}hdb,cn=config
changeType: modify
add: olcSyncrepl
olcSyncrepl: rid=001 provider=ldap://172.16.42.74:389 bindmethod=simple binddn="cn=mirrormode,dc=nodomain" credentials=_ei7N8o.gh=o44 searchbase="dc=nodomain" schemachecking=on type=refreshAndPersist retry="60 +"
-
add: olcMirrorMode
olcMirrorMode: TRUE
-

And you're up and running. Try adding something to one of the LDAP servers and see it appear automagically at the other. Well done my friend!


CategorySystemAdministration | CategorySoftware | CategoryObsolete ToDo: refactor