Index: chapter.xml =================================================================== --- chapter.xml +++ chapter.xml @@ -2249,6 +2249,11 @@ Rhodes Written by + + Rocky + Hotas + + Updated by @@ -2340,230 +2345,508 @@ LDAP Server &os; does not provide a built-in LDAP - server. Begin the configuration by installing the net/openldap24-server 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 - . + server. Begin the configuration by installing the net/openldap24-server package or port. Be sure to run all the commands + listed from now on as the user root. + This + + &prompt.root; pkg install openldap24-server + + installs the needed package, which is a particular kind of port: + the one with all options set to default. + In most cases, the defaults are fine and so the package is too. + But if for example SQL support is needed, + the relative option must be enabled and the port compiled using the instructions in + . There are many other configurable options, so it is + recommended that the defaults are reviewed to see if + the package is sufficient, and to instead compile the port if + any options should be changed. - Next, create the directories to hold the data and to store - the certificates: + If not already existent, create the directories to hold the + data and to store the certificates. &prompt.root; mkdir /var/db/openldap-data &prompt.root; mkdir /usr/local/etc/openldap/private - Copy over the database configuration file: + The database configuration file is - &prompt.root; cp /usr/local/etc/openldap/DB_CONFIG.example /var/db/openldap-data/DB_CONFIG + /usr/local/etc/openldap/DB_CONFIG.example - The next phase is to configure the certificate authority. + If it is not present after the installation of net/openldap24-server, + here + is available for download. + Further information about this file and its parameters can be found in + the OpenLDAP FAQs. + + Once downloaded, copy the database configuration file in an appropriate directory: + + &prompt.root; cp DB_CONFIG.example /var/db/openldap-data/DB_CONFIG + + When dealing with a brand new configuration, being not in a big + company or infrastructure who can buy or own several Certificate Authorities, + the cheapest and easiest thing to do is to create a free, brand new Certificate Authority. + It is a self-signed certificate, which will be the root, invisibile certificate that + will be use to sign all the other ones. + Further information about this procedure can be found in &man.openssl.1;, &man.req.1; and in the OpenLDAP 2.4 Administrator's Guide. The following commands must be executed from - /usr/local/etc/openldap/private. This is + /usr/local/etc/openldap/private. 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 - prompts: + users should not have access to these files. Here, &man.openssl.1; will be used + to create the Certificate Authority, with the syntax shown below. + Several questions must be answered to and &man.openssl.1; will gather specific + information to embed in the certificate. As regards the OpenLDAP server installation, + all but one of these questions are irrelevant. + The only important question is the one about the Common Name. + All the other answers may even be arbitrarily chosen or left empty; instead, + the Common Name should be carefully + chosen: for the Certificate Authority, it should be a name that will be never + used again. It can be CAdomain.example or anyone else, but + all the next certificates, that will be created and signed with this one, + must have a different Common Name. &prompt.root; openssl req -days 365 -nodes -new -x509 -keyout ca.key -out ../ca.crt - The entries for the prompts may be generic - except for the - Common Name. This entry must be - different than the system hostname. If - this will be a self signed certificate, prefix the hostname - with CA for certificate authority. - - The next task is to create a certificate signing request - and a private key. Input this command and follow the - prompts: + With this command, a Certificate Authority called ca.crt is created in + /usr/local/etc/openldap and its private key ca.key is + placed in /usr/local/etc/openldap/private. + + A certificate (and a private key) for the LDAP server is now needed: + it will be initially called a "Certificate Signing Request"; then, after being + signed with the Certificate Authority, it will actually be a certificate. + Only the Common Name attribute is important here like before: + if for the Certificate Authority CAdomain.example was chosen, now + the full hostname of the server domain.example can be used. + This is a trivial way to choose two different Common Names without effort. &prompt.root; openssl req -days 365 -nodes -new -keyout server.key -out server.csr - During the certificate generation process, be sure to - correctly set the Common Name attribute. - Once complete, sign the key: + This Certificate Signing Request must be signed with the + Certificate Authority in order to be used as a valid certificate: &prompt.root; openssl x509 -req -days 365 -in server.csr -out ../server.crt -CA ../ca.crt -CAkey ca.key -CAcreateserial - The final part of the certificate generation process is to - generate and sign the client certificates: + In /usr/local/etc/openldap a file called + server.crt has been created + and it will be the server certificate: it is trusted + because it is signed with the Certificate Authority. + It is now possible to create even the client + Certificate Signing Request and to sign it with the same Certificate Authority as before + (only this way also the client certificate will be trusted). + If the client and the server are the same machine, the same Common + Name as for server.csr must be used. Otherwise, whatever name can be + choosen, as far as it is different from the Certificate Authority + Common Name CAdomain.example. &prompt.root; openssl req -days 365 -nodes -new -keyout client.key -out client.csr &prompt.root; openssl x509 -req -days 3650 -in client.csr -out ../client.crt -CA ../ca.crt -CAkey ca.key - Remember to use the same Common Name - 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 - /usr/local/etc/openldap/slapd.conf and - add the following options: - - 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 - - Then, edit - /usr/local/etc/openldap/ldap.conf and add - the following lines: - - TLS_CACERT /usr/local/etc/openldap/ca.crt -TLS_CIPHER_SUITE HIGH:MEDIUM:+SSLv3 - - While editing this file, uncomment the following entries - and set them to the desired values: , - , and - . Set the to - contain and - . Then, add two entries pointing to - the certificate authority. When finished, the entries should - look similar to the following: - - BASE dc=example,dc=com -URI ldap:// ldaps:// - -SIZELIMIT 12 -TIMELIMIT 15 - -TLS_CACERT /usr/local/etc/openldap/ca.crt -TLS_CIPHER_SUITE HIGH:MEDIUM:+SSLv3 - - The default password for the server should then be - changed: - - &prompt.root; slappasswd -h "{SHA}" >> /usr/local/etc/openldap/slapd.conf - - This command will prompt for the password and, if the - process does not fail, a password hash will be added to the - end of slapd.conf. Several hashing - formats are supported. Refer to the manual page for - slappasswd for more information. - - Next, edit - /usr/local/etc/openldap/slapd.conf and - add the following lines: - - password-hash {sha} -allow bind_v2 - - The in this file must be updated - to match the used in - /usr/local/etc/openldap/ldap.conf and - should also be set. A recommended - value for is something like - . Before saving this file, place - the in front of the password output - from slappasswd and delete the old - . The end result should - look similar to this: - - 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= - - Finally, enable the OpenLDAP - service in /etc/rc.conf and set the - URI: - - slapd_enable="YES" -slapd_flags="-4 -h ldaps:///" - - At this point the server can be started and tested: - - &prompt.root; service slapd start - - If everything is configured correctly, a search of the - directory should show a successful connection with a single - response as in this example: - - &prompt.root; ldapsearch -Z -# extended LDIF -# -# LDAPv3 -# base <dc=example,dc=com> (default) with scope subtree -# filter: (objectclass=*) -# requesting: ALL -# - -# search result -search: 3 -result: 32 No such object - -# numResponses: 1 - - - If the command fails and the configuration looks - correct, stop the slapd service and - restart it with debugging options: - - &prompt.root; service slapd stop -&prompt.root; /usr/local/libexec/slapd -d -1 - - - Once the service is responding, the directory can be - populated using ldapadd. In this example, - a file containing this list of users is first created. Each - user should use the following format: + When finished, be sure that eight new files have been created: the + certificates ca.crt, server.crt + and client.crt in + /usr/local/etc/openldap and ca.key, + client.csr, client.key, + server.csr, server.key in + /usr/local/etc/openldap/private. + + The daemon running the OpenLDAP server is called slapd + and it must be configured. + Such a configuration can be performed in two ways: through a + slapd.conf configuration file, or through a database file + slapd.ldif. The former way is deprecated by OpenLDAP and the + use of a ldif file is strongly recommended. The structure of this file is not trivial. A + configuration example can be found here, in + paragraph 5.3. The directory /usr/local/etc/openldap contains + a slapd.ldif.sample file in order to ease the configuration. + A full example of the slapd.ldif will be provided below, + with some comments. The file is divided into several parts: each of them is uniquely identified through + a dn: (Distinguished Name). The first one is the global + configuration entry. Be sure that no blank lines are between the + dn: statement and the desired end of the section, otherwise an + error will be generated. + In the global section, options regarding the execution of slapd and + security can be specified. + The statements are generally the same as in slapd.conf, but preceeded + by "olc". The beginning of the slapd.ldif file + is reported here: in this section, the certificate file, its key, and the + Certificate Authority file should be specified, if a secure connection + for communications is required. In this example, TLS will be used to + implement a secure channel. All the following options (and more) are + documented in &man.slapd-config.5;, which is recommended to be consulted + during configuration. + + + # + # 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 + olcTLSProtocolMin: 3.1 + #olcTLSCipherSuite: HIGH:MEDIUM:+SSLv3 + olcTLSVerifyClient: never + + + An option olcTLSCipherSuite can specified; + previously, it + was suggested to have the value HIGH:MEDIUM:+SSLv3. It should be + noted however that SSLv3 has been deprecated by IETF and that the + syntax HIGH:MEDIUM is related to openssl; when clients with + different Operating Systems try to connect to this server, they may + not be able to parse this value. In order to connect to an LDAP server using TLS, + each client machine must run a TLS client. Linux machines, for example, + use gnutls as TLS client instead of openssl. + An error is generated if the option olcTLSCipherSuite: HIGH:MEDIUM:+SSLv3 + is used with the shown syntax. Otherwise all the clients + won't run FreeBSD, it is recommended to omit such a line, and + let the client OS choose the security cipher: this way, the server configuration can be + done and acceptable, regardless of the TLS clients that will connect. + The security cipher will be choosen according to + the available ciphers in the client machine, hopefully being the most + secure at the present time: it is not advisable that the server force it + and this is another benefit when omitting the olcTLSCipherSuite. + The security of the client ciphers is demanded to the package + maintainers of the TLS clients. + Nonetheless, the LDAP server Administrator can specify a minimum security + level required by the server, and this is done with the recommended option + olcTLSProtocolMin. + Server must always be verified, while clients can or can not be + verified: here it has been choosen to not verify them with + olcTLSVerifyClient. + + The second part is about the backend modules and can be configured as + follows: + + + # + # 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 + + + The third part is devoted to load the needed ldif schemas to be used + by the databases: they are essential. + + + dn: cn=schema,cn=config + objectClass: olcSchemaConfig + cn: schema + + 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 + + + Then, the frontend configuration follows: + + + # 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 + + + The following section describes the configuration backend: this will + be the only way to access the global configuration for the system + administrator, once this procedure is completed. Thus, it is extremely + important that all the needed options are here specified. In particular, + a root password must be choosen: together with the default + administrator username cn=config, it will let the server administrator + to later edit the configuration as the super-user. Note that without + the specification of a olcRootPW here, after this file is imported as + a configuration file for slapd, no one will be able to modify this global + configuration. This is highly undesirable. + If anyway something is wrong with the actual configuration, later will be shown a way + to delete (and hopefully replace) it. + A password can be generated using &man.slappasswd.8C; in a shell and its + entire output must be used as a value for olcRootPW. + + + dn: olcDatabase={0}config,cn=config + objectClass: olcDatabaseConfig + olcDatabase: {0}config + olcAccess: to * by * none + olcRootPW: {SSHA}iae+lrQZILpiUdf16Z9KmDmSwT77Dj4U + + + The last section showed here is about the database backend, used for + the actual contents of the LDAP directory. This database can be used + to add new groups and users as regards the domain domain.example. + Here, the database type mdb is used and another super-user is + specified: it will be only able to modify this database and not the + previous sections of slapd.ldif. Here, a username + olcRootDN can be specified, being related to the domain. + A password can be generated as before. + + + ####################################################################### + # 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 + + + Inthis repository, four examples of slapd.ldif files are available (they are used as a 4-way multi master + LDAP server). At the bottom of this page, + section 5.4, also a way to convert an existing slapd.conf into a valid + slapd.ldif is presented. This may introduce some unuseful options. + + Once the slapd.ldif configuration is completed, this file must be + imported in an empty directory. It is recommended to create it with the following name + and location: + + + &prompt.root; mkdir /usr/local/etc/openldap/slapd.d/ + + The commands suggested at points 9 and 10 in the OpenLDAP Quick Start guide + (which can anyway be considered as a reference for all the other + operations) are currently wrong: instead, it is advisable to use: + + &prompt.root; /usr/local/sbin/slapadd -n0 -F /usr/local/etc/openldap/slapd.d/ -l /usr/local/etc/openldap/slapd.ldif + + This will import the configuration database. +To start the slapd daemon, - dn: dc=example,dc=com -objectclass: dcObject -objectclass: organization -o: Example -dc: Example + &prompt.root; /usr/local/libexec/slapd -F /usr/local/etc/openldap/slapd.d/ -dn: cn=Manager,dc=example,dc=com -objectclass: organizationalRole -cn: Manager + Option -d can be used for debugging, as specified in &man.slapd.8;. - 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: +To verify that the server is running and working, - &prompt.root; ldapadd -Z -D "cn=Manager,dc=example,dc=com" -W -f import.ldif -Enter LDAP Password: -adding new entry "dc=example,dc=com" - -adding new entry "cn=Manager,dc=example,dc=com" - - Verify the data was added by issuing a search on the - server using ldapsearch: - - &prompt.user; ldapsearch -Z + &prompt.root; ldapsearch -x -b '' -s base '(objectclass=*)' namingContexts # extended LDIF # # LDAPv3 -# base <dc=example,dc=com> (default) with scope subtree +# base <> with scope baseObject # filter: (objectclass=*) -# requesting: ALL +# requesting: namingContexts # -# 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 +# +dn: +namingContexts: dc=domain,dc=example # search result -search: 3 +search: 2 result: 0 Success -# numResponses: 3 -# numEntries: 2 +# numResponses: 2 +# numEntries: 1 + + + The server won't still be recognized by any client as trusted, anyway. + The certificates were created in non-standard directories from the + point of view of openssl. In order for openssl + to work, the directories + where the certificates are stored must contain symbolic links (whose names are composed by + a hash) to the certificates. Even if some openssl commands are + already available in a FreeBSD base system, it is necessary now to + explicitly install the package: + + &prompt.root; pkg install openssl + + This will provide the &man.c_rehash.1; tool. Now run + + &prompt.root; c_rehash . + + from the directory where the CA is stored (in this example, + /usr/local/etc/openldap, which contains the file + ca.crt). This utility + must create a symlink for each .pem, + .crt, .crl or + .cer file in the + directory. Only this way server.crt can be recognized as a valid, + trusted and acceptable certificate. + After having verified that symlinks have been created, in order to + verify if the server certificate is trusted (and this is the + operation each LDAP client does before accessing the server), run + (from the server.crt directory): + + &prompt.root; openssl verify -verbose -CApath . server.crt + + If slapd was running, it must now be restarted before using the server. + + Please, carefully read the /usr/local/etc/rc.d/slapd file in order to + make a correct configuration to run slapd at boot. + An additional option is needed if the cn=config style (that is: the + file slapd.ldif) is used for configuration. You could put in + /etc/rc.conf the following lines: + + + 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" + + + slapddoesn't provide debugging at boot, but dmesg -a, +/var/log/messages and (in particular) /var/log/debug.log can be +checked. + + The LDAP users database is still empty. An example, which adds a group + called team and a user called john to + the domain.example database + is here provided. + + &prompt.root; cat domain.ldif +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 + + + Instead of being secret, the password in the + domain.ldif file for + john can be generated with + &man.slappasswd.8C;. Be careful about the default shell path: if it doesn't + exist in the system where the user tries to log in, an error can be + generated and the user could not be able to actually log in. A symlink + can be created, or a different shell can be used to avoid this. For the structure of the + ldif files and the LDAP directory, see the OpenLDAP documentation. + Such data can be added to the database using the mdb administrator: + + &prompt.root; ldapadd -W -D "cn=mdbadmin,dc=domain,dc=example" -f domain.ldif + + If instead a global option is to be modified, a different user must be + considered: as anticipated, it is the global super-user. Let's assume + that the option olcTLSCipherSuite: HIGH:MEDIUM:SSLv3 was specified + before and now it must be deleted. The instructions for the + modification can be store in the file global_mod. + It must not contain the previous value of the option to be deleted in + the last line, that is olcTLSCipherSuite: HIGH:MEDIUM:SSLv3 must + not be included as last line. + + &prompt.root; cat global_mod +dn: cn=config +changetype: modify +delete: olcTLSCipherSuite + + + The modifications can be applied with + + &prompt.root; ldapmodify -f global_mod -x -D "cn=config" -W + + cn=config is the dn (Distinguished Name) + of the entry (section) of the database to be modified. + Use ldapmodify to delete a single line of the database; + ldapdelete is used to delete an entire entry (section) instead. + Each database section has its own administrator and it + must be specified while applying a modification. + The global super-user, whose name is by default cn=config, should + have a password set by olcRootPW in the + dn: olcDatabase={0}config,cn=config section. It is the one who must + used here. If something goes wrong, or if this root administrator + cannot access the configuration backend, it is possible to completeley delete + the current configuration. It can be done by removing the directory that was previously created: + + &prompt.root; rm -rf /usr/local/etc/openldap/slapd.d/ + + The slapd.ldif file can then be edited and imported again. + Please note that this procedure is not to be considered as ordinary, nor normal: + it won't have side effects, but it should be followed only when no other solution is feasible. + + This is the configuration of the server only. The client, which can be + the server itself, or another machine, relies upon other configuration + files: a dedicated guide must be followed for them. - At this point, the server should be configured and - functioning properly.