Rewrite the LDAP server section of the handbook.

The Lightweight Directory Access Protocol (LDAP) section of the handbook
contains several errors (typos, wrong steps) and was in need of updates
to reflect current versions of the software. Rocky Hotas provided a patch
for review that fixes many of those bugs and extends the instructions in
the first part. The second part received a complete rewrite, providing
working example configuration files and steps to get the server running.

I made only a few cleanups and corrections to the patch to fit our
documentation guidelines. Most of the work was done by the submitter, big
thanks for his work and patience!

PR:		219142
Submitted by:	rockyhotas@post.com
Reviewed by:	remko, wollman, wblock, myself, others
Approved by:	bcr
Differential Revision:	https://reviews.freebsd.org/D10600
This commit is contained in:
Benedict Reuschling 2018-12-20 21:54:05 +00:00
parent c612a62a78
commit 53ebf4051c
Notes: svn2git 2020-12-08 03:00:23 +00:00
svn path=/head/; revision=52704

View file

@ -1000,7 +1000,7 @@ Exports list on foobar:
<para>The &man.autofs.5; map format is the same as in other
operating systems. Information about this format from other
sources can be useful, like the <link
sources can be useful, like the <link
xlink:href="http://web.archive.org/web/20160813071113/http://images.apple.com/business/docs/Autofs.pdf">Mac
OS X document</link>.</para>
@ -2248,9 +2248,18 @@ TWO (,hotel,test-domain)
<firstname>Tom</firstname>
<surname>Rhodes</surname>
</personname>
<contrib>Written by </contrib>
<contrib>Originally contributed by </contrib>
</author>
</authorgroup>
<authorgroup>
<author>
<personname>
<firstname>Rocky</firstname>
<surname>Hotas</surname>
</personname>
<contrib>Updates by </contrib>
</author>
</authorgroup>
</info>
<indexterm><primary>LDAP</primary></indexterm>
@ -2340,32 +2349,35 @@ result: 0 Success
<indexterm><primary>LDAP Server</primary></indexterm>
<para>&os; does not provide a built-in <acronym>LDAP</acronym>
server. Begin the configuration by installing the <package
role="port">net/openldap24-server</package> package or port.
Since the port has many configurable options, it is
recommended that the default options are reviewed to see if
the package is sufficient, and to instead compile the port if
any options should be changed. In most cases, the defaults
are fine. However, if SQL support is needed, this option must
be enabled and the port compiled using the instructions in
<xref linkend="ports-using"/>.</para>
server. Begin the configuration by installing <package
role="port">net/openldap-server</package> package or
port:</para>
<para>Next, create the directories to hold the data and to store
the certificates:</para>
<screen>&prompt.root; <userinput>pkg install openldap-server</userinput></screen>
<screen>&prompt.root; <userinput>mkdir /var/db/openldap-data</userinput>
&prompt.root; <userinput>mkdir /usr/local/etc/openldap/private</userinput></screen>
<para>There is a large set of default options enabled in the
<link xlink:href="&url.articles.linux-users;/software.html">
package</link>. Review them by running
<command>pkg info openldap-server</command>. If they are not
sufficient (for example if SQL support is needed), please
consider recompiling the port using the appropriate <link
xlink:href="&url.books.handbook;/ports-using.html">framework</link>.</para>
<para>Copy over the database configuration file:</para>
<para>The installation creates the directory
<filename>/var/db/openldap-data</filename> to hold the data.
The directory to store the certificates must be
created:</para>
<screen>&prompt.root; <userinput>cp /usr/local/etc/openldap/DB_CONFIG.example /var/db/openldap-data/DB_CONFIG</userinput></screen>
<screen>&prompt.root; <userinput>mkdir /usr/local/etc/openldap/private</userinput></screen>
<para>The next phase is to configure the certificate authority.
<para>The next phase is to configure the Certificate Authority.
The following commands must be executed from
<filename>/usr/local/etc/openldap/private</filename>. This is
important as the file permissions need to be restrictive and
users should not have access to these files. To create the
certificate authority, start with this command and follow the
users should not have access to these files. More detailed
information about certificates and their parameters can be
found in <xref linkend="openssl"/>. To create the
Certificate Authority, start with this command and follow the
prompts:</para>
<screen>&prompt.root; <userinput>openssl req -days <replaceable>365</replaceable> -nodes -new -x509 -keyout ca.key -out ../ca.crt</userinput></screen>
@ -2375,7 +2387,7 @@ result: 0 Success
<literal>Common Name</literal>. This entry must be
<emphasis>different</emphasis> than the system hostname. If
this will be a self signed certificate, prefix the hostname
with <literal>CA</literal> for certificate authority.</para>
with <literal>CA</literal> for Certificate Authority.</para>
<para>The next task is to create a certificate signing request
and a private key. Input this command and follow the
@ -2385,7 +2397,9 @@ result: 0 Success
<para>During the certificate generation process, be sure to
correctly set the <literal>Common Name</literal> attribute.
Once complete, sign the key:</para>
The Certificate Signing Request must be signed with the
Certificate Authority in order to be used as a valid
certificate:</para>
<screen>&prompt.root; <userinput>openssl x509 -req -days <replaceable>365</replaceable> -in server.csr -out ../server.crt -CA ../ca.crt -CAkey ca.key -CAcreateserial</userinput></screen>
@ -2398,172 +2412,351 @@ result: 0 Success
<para>Remember to use the same <literal>Common Name</literal>
attribute when prompted. When finished, ensure that a total
of eight (8) new files have been generated through the
proceeding commands. If so, the next step is to edit
<filename>/usr/local/etc/openldap/slapd.conf</filename> and
add the following options:</para>
proceeding commands.</para>
<programlisting>TLSCipherSuite HIGH:MEDIUM:+SSLv3
TLSCertificateFile /usr/local/etc/openldap/server.crt
TLSCertificateKeyFile /usr/local/etc/openldap/private/server.key
TLSCACertificateFile /usr/local/etc/openldap/ca.crt</programlisting>
<para>The daemon running the OpenLDAP server is
<filename>slapd</filename>. Its configuration is performed
through <filename>slapd.ldif</filename>: the old
<filename>slapd.conf</filename> has been deprecated by
OpenLDAP.</para>
<para>Then, edit
<filename>/usr/local/etc/openldap/ldap.conf</filename> and add
the following lines:</para>
<para><link
xlink:href="http://www.openldap.org/doc/admin24/slapdconf2.html">Configuration
examples</link> for <filename>slapd.ldif</filename> are
available and can also be found in
<filename>/usr/local/etc/openldap/slapd.ldif.sample</filename>.
Options are documented in slapd-config(5). Each section
of <filename>slapd.ldif</filename>, like all the other LDAP
attribute sets, is uniquely identified through a DN. Be sure
that no blank lines are left between the
<literal>dn:</literal> statement and the desired end of the
section. In the following example, TLS will be used to
implement a secure channel. The first section represents the
global configuration:</para>
<programlisting>TLS_CACERT /usr/local/etc/openldap/ca.crt
TLS_CIPHER_SUITE HIGH:MEDIUM:+SSLv3</programlisting>
<programlisting>#
# See slapd-config(5) for details on configuration options.
# This file should NOT be world readable.
#
dn: cn=config
objectClass: olcGlobal
cn: config
#
#
# Define global ACLs to disable default read access.
#
olcArgsFile: /var/run/openldap/slapd.args
olcPidFile: /var/run/openldap/slapd.pid
olcTLSCertificateFile: /usr/local/etc/openldap/server.crt
olcTLSCertificateKeyFile: /usr/local/etc/openldap/private/server.key
olcTLSCACertificateFile: /usr/local/etc/openldap/ca.crt
#olcTLSCipherSuite: HIGH
olcTLSProtocolMin: 3.1
olcTLSVerifyClient: never</programlisting>
<para>While editing this file, uncomment the following entries
and set them to the desired values: <option>BASE</option>,
<option>URI</option>, <option>SIZELIMIT</option> and
<option>TIMELIMIT</option>. Set the <option>URI</option> to
contain <option>ldap://</option> and
<option>ldaps://</option>. Then, add two entries pointing to
the certificate authority. When finished, the entries should
look similar to the following:</para>
<para>The Certificate Authority, server certificate and server
private key files must be specified here. It is recommended
to let the clients choose the security cipher and omit option
<literal>olcTLSCipherSuite</literal> (incompatible with TLS
clients other than <filename>openssl</filename>). Option
<literal>olcTLSProtocolMin</literal> lets the server require a
minimum security level: it is recommended. While
verification is mandatory for the server, it is not for the
client: <literal>olcTLSVerifyClient: never</literal>.</para>
<programlisting>BASE dc=example,dc=com
URI ldap:// ldaps://
<para>The second section is about the backend modules and can be
configured as follows:</para>
SIZELIMIT 12
TIMELIMIT 15
<programlisting>#
# Load dynamic backend modules:
#
dn: cn=module,cn=config
objectClass: olcModuleList
cn: module
olcModulepath: /usr/local/libexec/openldap
olcModuleload: back_mdb.la
#olcModuleload: back_bdb.la
#olcModuleload: back_hdb.la
#olcModuleload: back_ldap.la
#olcModuleload: back_passwd.la
#olcModuleload: back_shell.la</programlisting>
TLS_CACERT /usr/local/etc/openldap/ca.crt
TLS_CIPHER_SUITE HIGH:MEDIUM:+SSLv3</programlisting>
<para>The third section is devoted to load the needed
<literal>ldif</literal> schemas to be used by the databases:
they are essential.</para>
<para>The default password for the server should then be
changed:</para>
<programlisting>dn: cn=schema,cn=config
objectClass: olcSchemaConfig
cn: schema
<screen>&prompt.root; <userinput>slappasswd -h "{SHA}" &gt;&gt; /usr/local/etc/openldap/slapd.conf</userinput></screen>
include: file:///usr/local/etc/openldap/schema/core.ldif
include: file:///usr/local/etc/openldap/schema/cosine.ldif
include: file:///usr/local/etc/openldap/schema/inetorgperson.ldif
include: file:///usr/local/etc/openldap/schema/nis.ldif</programlisting>
<para>This command will prompt for the password and, if the
process does not fail, a password hash will be added to the
end of <filename>slapd.conf</filename>. Several hashing
formats are supported. Refer to the manual page for
<command>slappasswd</command> for more information.</para>
<para>Next, the frontend configuration section:</para>
<para>Next, edit
<filename>/usr/local/etc/openldap/slapd.conf</filename> and
add the following lines:</para>
<programlisting># Frontend settings
#
dn: olcDatabase={-1}frontend,cn=config
objectClass: olcDatabaseConfig
objectClass: olcFrontendConfig
olcDatabase: {-1}frontend
olcAccess: to * by * read
#
# Sample global access control policy:
# Root DSE: allow anyone to read it
# Subschema (sub)entry DSE: allow anyone to read it
# Other DSEs:
# Allow self write access
# Allow authenticated users read access
# Allow anonymous users to authenticate
#
#olcAccess: to dn.base="" by * read
#olcAccess: to dn.base="cn=Subschema" by * read
#olcAccess: to *
# by self write
# by users read
# by anonymous auth
#
# if no access controls are present, the default policy
# allows anyone and everyone to read anything but restricts
# updates to rootdn. (e.g., "access to * by * read")
#
# rootdn can always read and write EVERYTHING!
#
olcPasswordHash: {SSHA}
# {SSHA} is already the default for olcPasswordHash</programlisting>
<programlisting>password-hash {sha}
allow bind_v2</programlisting>
<para>Another section is devoted to the <emphasis>configuration
backend</emphasis>, the only way to later access the
OpenLDAP server configuration is as a global
super-user.</para>
<para>The <option>suffix</option> in this file must be updated
to match the <option>BASE</option> used in
<filename>/usr/local/etc/openldap/ldap.conf</filename> and
<option>rootdn</option> should also be set. A recommended
value for <option>rootdn</option> is something like
<option>cn=Manager</option>. Before saving this file, place
the <option>rootpw</option> in front of the password output
from <command>slappasswd</command> and delete the old
<option>rootpw</option>. The end result should
look similar to this:</para>
<programlisting>dn: olcDatabase={0}config,cn=config
objectClass: olcDatabaseConfig
olcDatabase: {0}config
olcAccess: to * by * none
olcRootPW: {SSHA}iae+lrQZILpiUdf16Z9KmDmSwT77Dj4U</programlisting>
<programlisting>TLSCipherSuite HIGH:MEDIUM:+SSLv3
TLSCertificateFile /usr/local/etc/openldap/server.crt
TLSCertificateKeyFile /usr/local/etc/openldap/private/server.key
TLSCACertificateFile /usr/local/etc/openldap/ca.crt
rootpw {SHA}W6ph5Mm5Pz8GgiULbPgzG37mj9g=</programlisting>
<para>The default administrator username is
<literal>cn=config</literal>. Type
<filename>slappasswd</filename> in a shell, choose a password
and use its hash in <literal>olcRootPW</literal>. If this
option is not specified now, before
<filename>slapd.ldif</filename> is imported, no one will be
later able to modify the
<emphasis>global configuration</emphasis> section.</para>
<para>Finally, enable the <application>OpenLDAP</application>
service in <filename>/etc/rc.conf</filename> and set the
<acronym>URI</acronym>:</para>
<para>The last section is about the database backend:</para>
<programlisting>slapd_enable="YES"
slapd_flags="-4 -h ldaps:///"</programlisting>
<programlisting>#######################################################################
# LMDB database definitions
#######################################################################
#
dn: olcDatabase=mdb,cn=config
objectClass: olcDatabaseConfig
objectClass: olcMdbConfig
olcDatabase: mdb
olcDbMaxSize: 1073741824
olcSuffix: dc=domain,dc=example
olcRootDN: cn=mdbadmin,dc=domain,dc=example
# Cleartext passwords, especially for the rootdn, should
# be avoided. See slappasswd(8) and slapd-config(5) for details.
# Use of strong authentication encouraged.
olcRootPW: {SSHA}X2wHvIWDk6G76CQyCMS1vDCvtICWgn0+
# The database directory MUST exist prior to running slapd AND
# should only be accessible by the slapd and slap tools.
# Mode 700 recommended.
olcDbDirectory: /var/db/openldap-data
# Indices to maintain
olcDbIndex: objectClass eq</programlisting>
<para>At this point the server can be started and tested:</para>
<para>This database hosts the <emphasis>actual
contents</emphasis> of the <acronym>LDAP</acronym>
directory. Types other than <literal>mdb</literal> are
available. Its super-user, not to be confused with the global
one, is configured here: a (possibly custom) username in
<literal>olcRootDN</literal> and the password hash in
<literal>olcRootPW</literal>; <filename>slappasswd</filename>
can be used as before.</para>
<screen>&prompt.root; <userinput>service slapd start</userinput></screen>
<para>This <link
xlink:href="http://www.openldap.org/devel/gitweb.cgi?p=openldap.git;a=tree;f=tests/data/regressions/its8444;h=8a5e808e63b0de3d2bdaf2cf34fecca8577ca7fd;hb=HEAD">repository</link>
contains four examples of <filename>slapd.ldif</filename>. To
convert an existing <filename>slapd.conf</filename> into
<filename>slapd.ldif</filename>, refer to <link
xlink:href="http://www.openldap.org/doc/admin24/slapdconf2.html">this
page</link> (please note that this may introduce some
unuseful options).</para>
<para>If everything is configured correctly, a search of the
directory should show a successful connection with a single
response as in this example:</para>
<para>When the configuration is completed,
<filename>slapd.ldif</filename> must be placed in an empty
directory. It is recommended to create it as:</para>
<screen>&prompt.root; <userinput>ldapsearch -Z</userinput>
<screen>&prompt.root; <userinput>mkdir /usr/local/etc/openldap/slapd.d/</userinput></screen>
<para>Import the configuration database:</para>
<screen>&prompt.root; <userinput>/usr/local/sbin/slapadd -n0 -F /usr/local/etc/openldap/slapd.d/ -l /usr/local/etc/openldap/slapd.ldif</userinput></screen>
<para>Start the <filename>slapd</filename> daemon:</para>
<screen>&prompt.root; <userinput>/usr/local/libexec/slapd -F /usr/local/etc/openldap/slapd.d/</userinput></screen>
<para>Option <literal>-d</literal> can be used for debugging,
as specified in slapd(8). To verify that the server is
running and working:</para>
<screen>&prompt.root; <userinput>ldapsearch -x -b '' -s base '(objectclass=*)' namingContexts</userinput>
# extended LDIF
#
# LDAPv3
# base &lt;dc=example,dc=com&gt; (default) with scope subtree
# base &lt;&gt; with scope baseObject
# filter: (objectclass=*)
# requesting: ALL
# requesting: namingContexts
#
#
dn:
namingContexts: dc=domain,dc=example
# search result
search: 3
result: 32 No such object
# numResponses: 1</screen>
<note>
<para>If the command fails and the configuration looks
correct, stop the <command>slapd</command> service and
restart it with debugging options:</para>
<screen>&prompt.root; <userinput>service slapd stop</userinput>
&prompt.root; <userinput>/usr/local/libexec/slapd -d -1</userinput></screen>
</note>
<para>Once the service is responding, the directory can be
populated using <command>ldapadd</command>. In this example,
a file containing this list of users is first created. Each
user should use the following format:</para>
<programlisting>dn: dc=<replaceable>example</replaceable>,dc=<replaceable>com</replaceable>
objectclass: dcObject
objectclass: organization
o: <replaceable>Example</replaceable>
dc: <replaceable>Example</replaceable>
dn: cn=<replaceable>Manager</replaceable>,dc=<replaceable>example</replaceable>,dc=<replaceable>com</replaceable>
objectclass: organizationalRole
cn: <replaceable>Manager</replaceable></programlisting>
<para>To import this file, specify the file name. The following
command will prompt for the password specified earlier and the
output should look something like this:</para>
<screen>&prompt.root; <userinput>ldapadd -Z -D "cn=<replaceable>Manager</replaceable>,dc=<replaceable>example</replaceable>,dc=<replaceable>com</replaceable>" -W -f <replaceable>import.ldif</replaceable></userinput>
Enter LDAP Password:
adding new entry "dc=example,dc=com"
adding new entry "cn=Manager,dc=example,dc=com"</screen>
<para>Verify the data was added by issuing a search on the
server using <command>ldapsearch</command>:</para>
<screen>&prompt.user; <userinput>ldapsearch -Z</userinput>
# extended LDIF
#
# LDAPv3
# base &lt;dc=example,dc=com&gt; (default) with scope subtree
# filter: (objectclass=*)
# requesting: ALL
#
# example.com
dn: dc=example,dc=com
objectClass: dcObject
objectClass: organization
o: Example
dc: Example
# Manager, example.com
dn: cn=Manager,dc=example,dc=com
objectClass: organizationalRole
cn: Manager
# search result
search: 3
search: 2
result: 0 Success
# numResponses: 3
# numEntries: 2</screen>
# numResponses: 2
# numEntries: 1</screen>
<para>At this point, the server should be configured and
functioning properly.</para>
<para>The server must still be trusted. If that has never been
done before, follow these instructions. Install the OpenSSL
package or port:</para>
<screen>&prompt.root; <userinput>pkg install openssl</userinput></screen>
<para>From the directory where <filename>ca.crt</filename> is
stored (in this example,
<filename>/usr/local/etc/openldap</filename>), run:</para>
<screen>&prompt.root; <userinput>c_rehash .</userinput></screen>
<para>Both the CA and the server certificate are now correctly
recognized in their respective roles. To verify this, run
this command from the <filename>server.crt</filename>
directory:</para>
<screen>&prompt.root; <userinput>openssl verify -verbose -CApath . server.crt</userinput></screen>
<para>If <filename>slapd</filename> was running, restart it. As
stated in <filename>/usr/local/etc/rc.d/slapd</filename>, to
properly run <filename>slapd</filename> at boot the
following lines must be added to
<filename>/etc/rc.conf</filename>:</para>
<programlisting>lapd_enable="YES"
slapd_flags='-h "ldapi://%2fvar%2frun%2fopenldap%2fldapi/
ldap://0.0.0.0/"'
slapd_sockets="/var/run/openldap/ldapi"
slapd_cn_config="YES"</programlisting>
<para><filename>slapd</filename> does not provide debugging at
boot. Check <filename>/var/log/debug.log</filename>,
<filename>dmesg -a</filename> and
<filename>/var/log/messages</filename> for this
purpose.</para>
<para>The following example adds the group
<literal>team</literal> and the user <literal>john</literal>
to the <systemitem
class="systemname">domain.example</systemitem>
<acronym>LDAP</acronym> database, which is still empty.
First, create the file
<filename>domain.ldif</filename>:</para>
<screen>&prompt.root; <userinput>cat domain.ldif</userinput>
dn: dc=domain,dc=example
objectClass: dcObject
objectClass: organization
o: domain.example
dc: domain
dn: ou=groups,dc=domain,dc=example
objectClass: top
objectClass: organizationalunit
ou: groups
dn: ou=users,dc=domain,dc=example
objectClass: top
objectClass: organizationalunit
ou: users
dn: cn=team,ou=groups,dc=domain,dc=example
objectClass: top
objectClass: posixGroup
cn: team
gidNumber: 10001
dn: uid=john,ou=users,dc=domain,dc=example
objectClass: top
objectClass: account
objectClass: posixAccount
objectClass: shadowAccount
cn: John McUser
uid: john
uidNumber: 10001
gidNumber: 10001
homeDirectory: /home/john/
loginShell: /usr/bin/bash
userPassword: secret</screen>
<para>See the OpenLDAP documentation for more details. Use
<filename>slappasswd</filename> to replace the plain text
password <literal>secret</literal> with a hash in
<literal>userPassword</literal>. The path specified as
<literal>loginShell</literal> must exist in all the systems
where <literal>john</literal> is allowed to login. Finally,
use the <literal>mdb</literal> administrator to modify the
database:</para>
<screen>&prompt.root; <userinput>ldapadd -W -D "cn=mdbadmin,dc=domain,dc=example" -f domain.ldif</userinput></screen>
<para>Modifications to the <emphasis>global
configuration</emphasis> section can only be performed by
the global super-user. For example, assume that the option
<literal>olcTLSCipherSuite: HIGH:MEDIUM:SSLv3</literal> was
initially specified and must now be deleted. First, create a
file that contains the following:</para>
<screen>&prompt.root; <userinput>cat <replaceable>global_mod</replaceable></userinput>
dn: cn=config
changetype: modify
delete: olcTLSCipherSuite</screen>
<para>Then, apply the modifications:</para>
<screen>&prompt.root; <userinput>ldapmodify -f global_mod -x -D "cn=config" -W</userinput></screen>
<para>When asked, provide the password chosen in the
<emphasis>configuration backend</emphasis> section. The
username is not required: here, <literal>cn=config</literal>
represents the DN of the database section to be modified.
Alternatively, use <literal>ldapmodify</literal> to delete a
single line of the database, <literal>ldapdelete</literal> to
delete a whole entry.</para>
<para>If something goes wrong, or if the global super-user
cannot access the configuration backend, it is possible to
delete and re-write the whole configuration:</para>
<screen>&prompt.root; <userinput>rm -rf /usr/local/etc/openldap/slapd.d/</userinput></screen>
<para><filename>slapd.ldif</filename> can then be edited and
imported again. Please, follow this procedure only when no
other solution is available.</para>
<para>This is the configuration of the server only. The same
machine can also host an LDAP client, with its own separate
configuration.</para>
</sect2>
</sect1>
@ -2810,7 +3003,7 @@ host fantasia {
<callout arearefs="default-lease-time">
<para>The default lease expiry time in seconds. A client
can be configured to override this value. </para>
can be configured to override this value.</para>
</callout>
<callout arearefs="max-lease-time">
@ -4088,7 +4281,7 @@ Starting smbd.</screen>
<filename>/etc/ntp.conf</filename>:</para>
<example>
<title> Sample <filename>/etc/ntp.conf</filename></title>
<title>Sample <filename>/etc/ntp.conf</filename></title>
<programlisting>server ntplocal.example.com prefer
server timeserver.example.org
@ -4177,7 +4370,7 @@ driftfile /var/db/ntp.drift</programlisting>
directives in <filename>/etc/ppp/ppp.conf</filename>. For
example:</para>
<programlisting> set filter dial 0 deny udp src eq 123
<programlisting>set filter dial 0 deny udp src eq 123
# Prevent NTP traffic from initiating dial out
set filter dial 1 permit 0 0
set filter alive 0 deny udp src eq 123