Jump to contentJump to page navigation: previous page [access key p]/next page [access key n]
ContentsContents
Security and Hardening Guide
  1. About This Guide
  2. 1 Security and Confidentiality
  3. 2 Common Criteria
  4. I Authentication
    1. 3 Authentication with PAM
    2. 4 Using NIS
    3. 5 Setting Up Authentication Clients Using YaST
    4. 6 LDAP with 389 Directory Server
    5. 7 Network Authentication with Kerberos
    6. 8 Active Directory Support
    7. 9 Setting Up a FreeRADIUS Server
  5. II Local Security
    1. 10 Physical Security
    2. 11 Software Management
    3. 12 File Management
    4. 13 Encrypting Partitions and Files
    5. 14 Storage Encryption for Hosted Applications with cryptctl
    6. 15 User Management
    7. 16 Restricting cron and at
    8. 17 Spectre/Meltdown Checker
    9. 18 Configuring Security Settings with YaST
    10. 19 Authorization with PolKit
    11. 20 Access Control Lists in Linux
    12. 21 Certificate Store
    13. 22 Intrusion Detection with AIDE
  6. III Network Security
    1. 23 X Window System and X Authentication
    2. 24 SSH: Secure Network Operations
    3. 25 Masquerading and Firewalls
    4. 26 Configuring a VPN Server
    5. 27 Improving Network Security with sysctl Variables
    6. 28 Enabling FIPS 140-2
  7. IV Confining Privileges with AppArmor
    1. 29 Introducing AppArmor
    2. 30 Getting Started
    3. 31 Immunizing Programs
    4. 32 Profile Components and Syntax
    5. 33 AppArmor Profile Repositories
    6. 34 Building and Managing Profiles with YaST
    7. 35 Building Profiles from the Command Line
    8. 36 Profiling Your Web Applications Using ChangeHat
    9. 37 Confining Users with pam_apparmor
    10. 38 Managing Profiled Applications
    11. 39 Support
    12. 40 AppArmor Glossary
  8. V SELinux
    1. 41 Configuring SELinux
  9. VI The Linux Audit Framework
    1. 42 Understanding Linux Audit
    2. 43 Setting Up the Linux Audit Framework
    3. 44 Introducing an Audit Rule Set
    4. 45 Useful Resources
  10. A Achieving PCI DSS Compliance
  11. B Licencias GNU
Navigation
Applies to SUSE Linux Enterprise Server 15 SP2

6 LDAP with 389 Directory Server

The Lightweight Directory Access Protocol (LDAP) is a protocol designed to access and maintain information directories. LDAP can be used for tasks such as user and group management, system configuration management, and address management. In SUSE Linux Enterprise Server 15 SP2 the LDAP service is provided by the 389 Directory Server, replacing OpenLDAP.

Ideally, a central server stores the data in a directory and distributes it to all clients using a well-defined protocol. The structured data allow a wide range of applications to access them. A central repository reduces the necessary administrative effort. The use of an open and standardized protocol such as LDAP ensures that as many client applications as possible can access such information.

A directory in this context is a type of database optimized for quick and effective reading and searching. The type of data stored in a directory tends to be long lived and changes infrequently. This allows the LDAP service to be optimized for high performance concurrent reads, whereas conventional databases are optimized for accepting many writes to data in a short time.

6.1 Structure of an LDAP directory tree

This section introduces the layout of an LDAP directory tree, and provides the basic terminology used with regard to LDAP. If you are familiar with LDAP, read on at Section 6.2.1, “Setting up a new 389 Directory Server instance”.

An LDAP directory has a tree structure. All entries (called objects) of the directory have a defined position within this hierarchy. This hierarchy is called the directory information tree (DIT). The complete path to the desired entry, which unambiguously identifies it, is called the distinguished name or DN. An object in the tree is identified by its relative distinguished name (RDN). The distinguished name is built from the RDNs of all entries on the path to the entry.

The relations within an LDAP directory tree become more evident in the following example, shown in Figure 6.1, “Structure of an LDAP directory”.

Structure of an LDAP directory
Figure 6.1: Structure of an LDAP directory

The complete diagram is a fictional directory information tree. The entries on three levels are depicted. Each entry corresponds to one box in the image. The complete, valid distinguished name for the fictional employee Geeko Linux, in this case, is cn=Geeko Linux,ou=doc,dc=example,dc=com. It is composed by adding the RDN cn=Geeko Linux to the DN of the preceding entry ou=doc,dc=example,dc=com.

The types of objects that can be stored in the DIT are globally determined following a Schema. The type of an object is determined by the object class. The object class determines what attributes the relevant object must or may be assigned. The Schema contains all object classes and attributes which can be used by the LDAP server. Attributes are a structured data type. Their syntax, ordering and other behavior is defined by the Schema. LDAP servers supply a core set of Schemas which can work in a broad variety of environments. If a custom Schema is required, you can upload it to an LDAP server.

Table 6.1, “Commonly used object classes and attributes” offers a small overview of the object classes from 00core.ldif and 06inetorgperson.ldif used in the example, including required attributes (Req. Attr.) and valid attribute values. After installing 389 Directory Server, these can be found in /usr/share/dirsrv/schema.

Table 6.1: Commonly used object classes and attributes

Object Class

Meaning

Example Entry

Req. Attr.

domain

name components of the domain

example

displayName

organizationalUnit

organizational unit

documentationdept

ou

nsPerson

person-related data for the intranet or Internet

Tux Linux

cn

Example 6.1, “Excerpt from CN=schema” shows an excerpt from a Schema directive with explanations.

Example 6.1: Excerpt from CN=schema
attributetype (1.2.840.113556.1.2.102 NAME 'memberOf' 1
       DESC 'Group that the entry belongs to' 2
       SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 3
       X-ORIGIN 'Netscape Delegated Administrator') 4

objectclass (2.16.840.1.113730.3.2.333 NAME 'nsPerson' 5
       DESC 'A representation of a person in a directory server' 6
       SUP top STRUCTURAL 7
       MUST ( displayName $ cn ) 8
       MAY ( userPassword $ seeAlso $ description $ legalName $ mail \
             $ preferredLanguage ) 9
       X-ORIGIN '389 Directory Server Project'
  ...

1

The name of the attribute, its unique object identifier (OID, numerical), and the abbreviation of the attribute.

2

A brief description of the attribute with DESC. The corresponding RFC, on which the definition is based, may also mentioned here.

3

The type of data that can be held in the attribute. In this case, it is a case-insensitive directory string.

4

The source of the schema element (for example, the name of the project).

5

The definition of the object class nsPerson begins with an OID and the name of the object class (like the definition of the attribute).

6

A brief description of the object class.

7

The SUP top entry indicates that this object class is not subordinate to another object class.

8

With MUST, list all attribute types that must be used with an object of the type nsPerson.

9

With MAY, list all attribute types that are optionally permitted with this object class.

6.2 Installing 389 Directory Server

Install 389 Directory Server with the following command:

tux > sudo zypper install 389-ds

After installation, set up the server as described in Section 6.2.1, “Setting up a new 389 Directory Server instance”.

6.2.1 Setting up a new 389 Directory Server instance

You will use the dscreate command to create new 389 Directory Server instances, and the dsctl command to cleanly remove them.

There are two ways to configure and create a new instance: from a custom configuration file, and from an auto-generated template file. You can use the auto-generated template without changes for a test instance, though for a production system you must carefully review it and make any necessary changes.

Then you will set up administration credentials, manage users and groups, and configure identity services.

The 389 Directory Server is controlled by three primary commands:

dsctl

Manages a local instance and requires root permissions. Requires you to be connected to a terminal which is running the directory server instance. Used for starting, stopping, backing up the database, and more.

dsconf

The primary tool used for administration and configuration of the server. Manages an instance's configuration via its external interfaces. This allows you to make configuration changes remotely on the instance.

dsidm

Used for identity management (managing users, groups, passwords, etc.). The permissions are granted by access controls, so, for example, users can reset their own password or change details of their own account.

Follow these steps to set up a simple instance for testing and development, populated with a small set of sample entries.

6.2.2 Creating a 389 Directory Server instance with a custom configuration file

You can create a new 389 Directory Server instance from a simple custom configuration file. This file must be in the INF format, and you can name it anything you like.

The default instance name is localhost. The instance name cannot be changed after it has been created. It is better to create your own instance name, rather than using the default, to avoid confusion and to enable a better understanding of how it all works. The following examples use the LDAP1 instance name, and a suffix of dc=LDAP1,dc=COM.

Example 6.2 shows an example configuration file that you can use to create a new 389 Directory Server instance. You can copy and use this file without changes.

  1. Copy the following example file, LDAP1.inf, to your home directory:

    Example 6.2: Minimal 389 Directory Server instance configuration file
    # LDAP1.inf
    
    [general]
    config_version = 2 1
    
    [slapd]
    root_password = PASSWORD2
    self_sign_cert = True 3
    instance_name = LDAP1
    
    [backend-userroot]
    sample_entries = yes 4
    suffix = dc=LDAP1,dc=COM

    1

    This line is required, indicating that this is a version 2 setup INF file.

    2

    Create a root_password for the ldap user cn=Directory Manager. This user is for connecting (binding) to the directory.

    3

    Create self-signed server certificates in /etc/dirsrv/slapd-LDAP1.

    4

    Populate the new instance with sample user and group entries.

  2. To create the 389 Directory Server instance from Example 6.2, run the following command:

    tux > sudo dscreate -v from-file LDAP1.inf | \
    tee LDAP1-OUTPUT.txt

    This shows all activity during the instance creation, stores all the messages in LDAP1-OUTPUT.txt, and creates a working LDAP server in about a minute. The verbose output contains a lot of useful information. If you do not want to save it, then delete the | tee LDAP1-OUTPUT.txt portion of the command.

  3. If the dscreate command should fail, the messages will tell you why. After correcting any issues, remove the instance (see Step 5) and create a new instance.

  4. A successful installation reports "Completed installation for LDAP1". Check the status of your new server:

    tux > sudo dsctl LDAP1 status
    Instance "LDAP1" is running
  5. The following commands are for cleanly removing the instance. The first command performs a dry run and does not remove the instance. When you are sure you want to remove it, use the second command with the --do-it option:

    tux > sudo dsctl LDAP1 remove
    Not removing: if you are sure, add --do-it
    
    tux > sudo dsctl LDAP1 remove --do-it

    This command also removes partially installed or corrupted instances. You can reliably create and remove instances as often as you want.

If you forget the name of your instance, use dsctl to list all instances:

tux > /usr/sbin/dsctl -l
slapd-LDAP1

6.2.3 Creating a 389 Directory Server instance from a template

You can auto-create a template for a new 389 Directory Server instance with the dscreate command. This creates a template that you can use without making any changes, for testing. For production systems, review and change it to suit your own requirements. All of the defaults are documented in the template file, and commented out. To make changes, uncomment the default and enter your own value. All options are well documented.

The following example prints the template to stdout:

tux > dscreate create-template

This is good for a quick review of the template, but you must create a file to use in creating your new 389 Directory Server instance. You can name this file anything you want:

tux > dscreate create-template TEMPLATE.txt

This is a snippet from the new file:

# full_machine_name (str)
# Description: Sets the fully qualified hostname (FQDN) of this system. When
# installing this instance with GSSAPI authentication behind a load balancer, set
# this parameter to the FQDN of the load balancer and, additionally, set
# "strict_host_checking" to "false".
# Default value: ldapserver1.test.net
;full_machine_name = ldapserver1.test.net

# selinux (bool)
# Description: Enables SELinux detection and integration during the installation
# of this instance. If set to "True", dscreate auto-detects whether SELinux is
# enabled. Set this parameter only to "False" in a development environment.
# Default value: True
;selinux = True

It automatically configures some options from your existing environment, for example, the system's fully-qualified domain name, which is called full_machine_name in the template. Use this file with no changes to create a new instance:

tux > sudo dscreate from-file TEMPLATE.txt

This creates a new instance named localhost, and automatically starts it after creation:

tux > sudo dsctl localhost status
Instance "localhost" is running

The default values create a fully operational instance, but there are some values you might want to change.

The instance name cannot be changed after it has been created. It is better to create your own instance name, rather than using the default, to avoid confusion and to enable a better understanding of how it all works. To do this, uncomment the ;instance_name = localhost line and change localhost to your chosen name. In the following examples, the instance name is LDAP1.

Another useful change is to populate your new instance with sample users and groups. Uncomment ;sample_entries = no and change no to yes. This creates the demo_user and demo_group.

Set your own password by uncommenting ;root_password, and replacing the default password with your own.

The template does not create a default suffix, so you should configure your own on the suffix line, like the following example:

suffix = dc=LDAP1,dc=COM

You can cleanly remove any instance and start over with dsctl:

tux > sudo dsctl LDAP1 remove --do-it

6.2.4 Stopping and starting 389 Directory Server

The following examples use LDAP1 as the instance name. Use systemd to manage your 389 Directory Server instance. Get the status of your instance:

tux > systemctl status --no-pager --full dirsrv@LDAP1.service
   ● dirsrv@LDAP1.service - 389 Directory Server LDAP1.
     Loaded: loaded (/usr/lib/systemd/system/dirsrv@.service; enabled; vendor preset: disabled)
     Active: active (running) since Thu 2021-03-11 08:55:28 PST; 2h 7min ago
    Process: 4451 ExecStartPre=/usr/lib/dirsrv/ds_systemd_ask_password_acl 
       /etc/dirsrv/slapd-LDAP1/dse.ldif (code=exited, status=0/SUCCESS)
   Main PID: 4456 (ns-slapd)
     Status: "slapd started: Ready to process requests"
      Tasks: 26
     CGroup: /system.slice/system-dirsrv.slice/dirsrv@LDAP1.service
             └─4456 /usr/sbin/ns-slapd -D /etc/dirsrv/slapd-LDAP1 -i /run/dirsrv/slapd-LDAP1.pid

Start, stop, and restart your LDAP server:

tux > sudo systemctl start dirsrv@LDAP1.service
tux > sudo systemctl stop dirsrv@LDAP1.service
tux > sudo systemctl restart dirsrv@LDAP1.service

See Chapter 15, The systemd Daemon for more information on using systemctl.

The dsctl command also starts and stops your server:

tux > sudo dsctl LDAP1 status
tux > sudo dsctl LDAP1 stop
tux > sudo dsctl LDAP1 restart
tux > sudo dsctl LDAP1 start

6.2.5 Configuring admin credentials for local administration

For local administration of the 389 Directory Server, you can create a .dsrc configuration file in the /root directory, allowing root and sudo users to administer the server without typing connection details with every command. Example 6.3 shows an example for local administration on the server, using LDAP1 and com for the suffix.

After creating your /root/.dsrc file, try a few administration commands, such as creating new users (see Section 6.5, “Managing LDAP users and groups”).

Example 6.3: A .dsrc file for local administration
# /root/.dsrc file for administering the LDAP1 instance

[LDAP1] 1

uri = ldapi://%%2fvar%%2frun%%2fslapd-LDAP1.socket 2
basedn = dc=LDAP1,dc=COM
binddn = cn=Directory Manager

1

This must specify your exact instance name.

2

ldapi detects the UID and GID of the user attempting to log in to the server. If the UID/GID are 0/0 or dirsrv:dirsrv, ldapi binds the user as the directory server root dn, which is cn=Directory Manager.

In the URI, the slashes are replaced with %%2f, so in this example the path is /var/run/slapd-LDAP1.socket.

6.3 Firewall configuration

The default TCP ports for 389 Directory Server are 389 and 636. TCP 389 is for unencrypted connections, and STARTTLS. 636 is for encrypted connections over TLS.

firewalld is the default firewall manager for SUSE Linux Enterprise. The following rules activate the ldap and ldaps firewall services:

tux > sudo firewall-cmd --add-service=ldap --zone=internal
tux > sudo firewall-cmd --add-service=ldaps --zone=internal
tux > sudo firewall-cmd --runtime-to-permanent

Replace the zone with the appropriate zone for your server. See Section 6.8, “Importing TLS server certificates and keys” for information on securing your connections with TLS, and Section 25.3, “Firewalling Basics” to learn about firewalld.

6.4 Backing up and restoring 389 Directory Server

389 Directory Server supports making offline and online backups. The dsctl command makes offline database backups, and the dsconf command makes online database backups. Back up the LDAP server configuration directory, to enable complete restoration in case of a major failure.

6.4.1 Backing up the LDAP server configuration

Your LDAP server configuration is in the directory /etc/dirsrv/slapd-INSTANCE_NAME. This directory contains certificates, keys, and the dse.ldif file. Make a compressed backup of this directory with the tar command:

tux > sudo tar caf \
config_slapd-INSTANCE_NAME-$(date +%Y-%m-%d_%H-%M-%S).tar.gz \
/etc/dirsrv/slapd-INSTANCE_NAME/
Note

When running tar, you may see the harmless informational message tar: Removing leading `/' from member names.

To restore a previous configuration, unpack it to the same directory:

  1. (Optional) To avoid overwriting an existing configuration, move it:

    tux > sudo old /etc/dirsrv/slapd-INSTANCE_NAME/
  2. Unpack the backup archive:

    tux > sudo tar -xvzf \
    config_slapd-INSTANCE_NAME-DATE.tar.gz
  3. Copy it to /etc/dirsrv/slapd-INSTANCE_NAME:

    tux > sudo cp -r etc/dirsrv/slapd-INSTANCE_NAME \ 
    /etc/dirsrv/slapd-INSTANCE_NAME

6.4.2 Creating an offline backup of the LDAP database and restoring from it

The dsctl command makes offline backups. Stop the server:

tux > sudo dsctl INSTANCE_NAME stop
Instance "INSTANCE_NAME" has been stopped

Then make the backup using your instance name. The following example creates a backup archive at /var/lib/dirsrv/slapd-INSTANCE_NAME/bak/INSTANCE_NAME-DATE:

tux > sudo dsctl INSTANCE_NAME db2bak
db2bak successful

For example, on a test instance named ldap1 it looks like this:

/var/lib/dirsrv/slapd-ldap1/bak/ldap1-2021_10_25_13_03_17

Restore from this backup, naming the directory containing the backup archive:

tux > sudo dsctl INSTANCE_NAME bak2db \
/var/lib/dirsrv/slapd-INSTANCE_NAME/bak/INSTANCE_NAME-DATE/
bak2db successful

Then start the server:

tux > sudo dsctl INSTANCE_NAME start
Instance "INSTANCE_NAME" has been started

You can also create LDIF backups:

tux > sudo dsctl INSTANCE_NAME db2ldif --replication userRoot
ldiffile: /var/lib/dirsrv/slapd-INSTANCE_NAME/ldif/INSTANCE_NAME-userRoot-DATE.ldif
db2ldif successful

Restore an LDIF backup with the name of the archive, then start the server:

tux > sudo dsctl ldif2db userRoot \
/var/lib/dirsrv/slapd-INSTANCE_NAME/ldif/INSTANCE_NAME-userRoot-DATE.ldif
tux > sudo dsctl INSTANCE_NAME start

6.4.3 Creating an online backup of the LDAP database and restoring from it

Use the dsconf to make an online backup of your LDAP database:

tux > sudo dsconf INSTANCE_NAME backup create
The backup create task has finished successfully

This creates /var/lib/dirsrv/slapd-INSTANCE_NAME/bak/INSTANCE_NAME-DATE.

Restore it:

tux > sudo dsconf INSTANCE_NAME backup restore \
/var/lib/dirsrv/slapd-INSTANCE_NAME/bak/INSTANCE_NAME-DATE

6.5 Managing LDAP users and groups

Users and groups are created and managed with the dsidm command.

The following examples use the instance name LDAP1. Replace this with your instance name.

List your existing users and groups:

tux > sudo dsidm LDAP1 user list
tux > sudo dsidm LDAP1 group list

List all information on a single user:

tux > sudo dsidm LDAP1 user get USER

List all information on a single group:

tux > sudo dsidm LDAP1 group get GROUP

List members of a group:

tux > sudo dsidm LDAP1 group members GROUP

In the following example we add one user, wilber. The example server instance is named LDAP1, and the instance's suffix is dc=LDAP1,dc=COM.

Procedure 6.1: Creating LDAP users

The following example creates the user Wilber Fox on your 389 DS instance:

  1. tux > sudo dsidm LDAP1 user create --uid wilber \
      --cn wilber --displayName 'Wilber Fox' --uidNumber 1001 --gidNumber 101 \
      --homeDirectory /home/wilber
  2. Verify by looking up your new user's distinguished name (fully qualified name to the directory object, which is guaranteed unique):

    tux > sudo dsidm LDAP1 user get wilber
    dn: uid=wilber,ou=people,dc=LDAP1,dc=COM
    [...]

    You need the distinguished name for actions such as changing the password for a user.

  3. Create a password for new user wilber:

    1. tux > sudo dsidm LDAP1 account reset_password \
        uid=wilber,ou=people,dc=LDAP1,dc=COM
    2. Enter the new password for wilber twice.

      If the action was successful, you get the following message:

      reset password for uid=wilber,ou=people,dc=LDAP1,dc=COM

      Use the same command to change an existing password.

  4. Verify that the user's password works:

    tux > ldapwhoami -D uid=wilber,ou=people,dc=LDAP1,dc=COM -W
    Enter LDAP Password: PASSWORD
    dn: uid=wilber,ou=people,dc=LDAP1,dc=COM

The following example deletes the user wilber:

tux > sudo dsidm LDAP1 user delete
   Enter dn to delete : uid=wilber,ou=people,dc=LDAP1,dc=COM
   Deleting nsUserAccount uid=wilber,ou=people,dc=LDAP1,dc=COM :
   Type 'Yes I am sure' to continue: Yes I am sure
   Successfully deleted uid=wilber,ou=people,dc=LDAP1,dc=COM
Procedure 6.2: Creating LDAP groups and assigning users to them

In the following examples, we create a group, server_admins, and assign the user wilber to this group. The example server instance is named LDAP1, and the instance's suffix is dc=LDAP1,dc=COM.

  1. Create the group:

    tux > sudo dsidm LDAP1 group create

    You will be prompted for a group name. Enter your chosen group name, which in the following example is SERVER_ADMINS:

    Enter value for cn : SERVER_ADMINS
  2. Add the user wilber to the group:

    tux > sudo dsidm LDAP1 group add_member SERVER_ADMINS \
    uid=wilber,ou=people,dc=LDAP1,dc=COM
    added member: uid=wilber,ou=people,dc=LDAP1,dc=COM

6.6 Using SSSD to manage authentication

The System Security Services Daemon (SSSD) manages authentication, identification, and access controls for remote clients. This section describes how to use SSSD to manage authentication and identification for your 389 Directory Server.

SSSD mediates between your LDAP server and clients. It supports several provider back-ends, such as LDAP, Active Directory, and Kerberos. SSSD supports services, including SSH, PAM, NSS, and sudo. SSSD provides performance benefits and resilience through caching user IDs and credentials. Caching reduces the number of requests to your 389 DS server, and provides authentication and identity services when the back-ends are unavailable.

If the Name Services Caching Daemon (ncsd) is running on your network, you should disable or remove it. ncsd caches only the common name service requests, such as passwd, group, hosts, service, and netgroup, and will conflict with SSSD.

Your LDAP server is the provider, and your SSSD instance is the client of the provider. You may install SSSD on your 389 DS server, but installing it on a separate machine provides some resilience in case the 389 DS server becomes unavailable. Use the following procedure to install and configure an SSSD client.

  1. Install the sssd and sssd-ldap packages:

    tux > sudo zypper in sssd sssd-ldap
  2. Back up the default /etc/sssd/sssd.conf file:

    tux > sudo old /etc/sssd/sssd.conf
  3. Create your new SSSD configuration. The following example creates a basic client configuration:

    tux > sudo dsidm INSTANCE_NAME client_config /etc/sssd/sssd.conf
  4. Review the output and make any necessary changes to suit your environment.

  5. Edit the /etc/nsswitch.conf configuration file on the SSSD server to include the following lines:

    passwd: compat sss
    group:  compat sss
    shadow: compat sss
  6. Edit the PAM configuration on the SSSD server, modifying common-account-pc, common-auth-pc, common-password-pc, and common-session-pc. SUSE Linux Enterprise provides a command to modify all of these files at once, pam-config:

    tux > sudo pam-config -a --sss
  7. Verify the modified configuration:

    tux > sudo pam-config -q --sss
    auth:
    account:
    password:
    session:
  8. Copy /etc/dirsrv/slapd-INSTANCE_NAME/ca.crt from the 389 DS server to /etc/openldap/certs on your SSSD server, then rehash it:

    tux > sudo c_rehash /etc/openldap/certs
  9. Enable and start SSSD:

    tux > sudo systemctl enable --now sssd

6.7 Managing modules

Use the following command to list all available modules, enabled and disabled. Use your server's hostname rather than the instance name of your 389 Directory Server server, like the following example hostname of LDAPSERVER1:

tux > sudo dsconf -D "cn=Directory Manager" ldap://LDAPSERVER1 plugin list
Enter password for cn=Directory Manager on ldap://LDAPSERVER1: PASSWORD

7-bit check
Account Policy Plugin
Account Usability Plugin
ACL Plugin
ACL preoperation
[...]

The following command enables the MemberOf plugin referenced in Section 6.6, “Using SSSD to manage authentication”:

tux > sudo dsconf -D "cn=Directory Manager" ldap://LDAPSERVER1 plugin memberof enable

Note that the plugin names used in commands are lowercase, so they are different from how they appear when you list them. If you make a mistake with a plugin name, you will see a helpful error message:

dsconf instance plugin: error: invalid choice: 'MemberOf' (choose from
'memberof', 'automember', 'referential-integrity', 'root-dn', 'usn',
'account-policy', 'attr-uniq', 'dna', 'linked-attr', 'managed-entries',
'pass-through-auth', 'retro-changelog', 'posix-winsync', 'contentsync', 'list',
'show', 'set')

After enabling a plugin, it is necessary to restart the server:

tux > sudo systemctl restart dirsrv@LDAPSERVER1.service

To avoid having to restart the server, set the nsslapd-dynamic-plugins parameter to on:

tux > sudo dsconf -D "cn=Directory Manager" ldap://LDAPSERVER1 config replace \
nsslapd-dynamic-plugins=on
Enter password for cn=Directory Manager on ldap://LDAPSERVER1: PASSWORD

Successfully replaced "nsslapd-dynamic-plugins"

6.8 Importing TLS server certificates and keys

You can manage your CA certificates and keys for 389 Directory Server with the following command line tools: certutil, openssl, and pk12util.

For testing purposes, you can use the self-signed certificate that dscreate creates when you create a new 389 DS instance. Find the certificate at /etc/dirsrv/slapd-INSTANCE-NAME/ca.crt.

For production environments, it is a best practice to use a third-party certificate authority, such as Let's Encrypt, CAcert.org, SSL.com, or whatever CA you choose. Request a server certificate, a client certificate, and a root certificate.

Before you can import an existing private key and certificate into the NSS database, you need to create a bundle of the private key and the server certificate. This results in a *.p12 file.

Important
Important: *.p12 file and friendly name

When creating the PKCS12 bundle, you must encode Server-Cert as the friendly name in the *.p12 file. Otherwise the TLS connection will fail, because the 389 Directory Server searches for this exact string.

The friendly name cannot be changed after you import the *.p12 file into the NSS database.

  1. Use the following command to create the PKCS12 bundle with the required friendly name:

    tux > sudo openssl pkcs12 -export -in SERVER.crt \ 
    -inkey SERVER.key \
    -out SERVER.p12 -name Server-Cert

    Replace SERVER.crt with the server certificate and SERVER.key with the private key to be bundled. Use -out to specify the name of the *.p12 file. Use -name to set the friendly name, which must be Server-Cert.

  2. Before you can import the file into the NSS database, you need to obtain its password. To do this, use the following command:

    tux > sudo pk12util -i SERVER.p12 \
    -d sql:PATH_TO_NSS_DB -n Server-Cert -W PASSWORD

    You can then find the password in the pwdfile.txt file in the PATH_TO_NSS_DB directory.

  3. Now import the SERVER.p12 file into your 389 DS NSS database:

    tux > sudo pk12util -i SERVER.p12 \
    -d /etc/dirsrv/slapd-INSTANCE-NAME/cert9.db

6.9 Setting up replication

389 Directory Server supports replicating its database content between multiple servers. According to the type of replication, this provides:

  • Faster performance and response times

  • Fault tolerance and failover

  • Load balancing

  • High availability

A database is the smallest unit of a directory that can be replicated. You can replicate an entire database, but not a subtree within a database. One database must correspond to one suffix. You cannot replicate a suffix that is distributed over two or more databases.

A replica that sends data to another replica is a supplier. A replica that receives data from a supplier is a consumer. Replication is always initiated by the supplier, and a single supplier can send data to multiple consumers. Usually the supplier is a read-write replica, and the consumer is read-only, except in the case of multi-supplier replication. In multi-supplier replication the suppliers are both suppliers and consumers of the same data.

6.9.1 Asynchronous writes

389 DS manages replication differently than other databases. Replication is asynchronous, and eventually consistent. This means:

  • Any write or change to a single server is immediately accepted.

  • There is a delay between a write finishing on one server, and then replicating and being visible on other servers.

  • If that write conflicts with writes on other servers, it may be rolled back at some point in the future.

  • Not all servers may show identical content at the same time due to replication delay.

In general, as LDAP is "low-write", these factors mean that all servers are at least up to a common baseline of a known consistent state. Small changes occur on top of this baseline, so many of these aspects of delayed replication are not perceived in day to day usage.

6.9.2 Designing your topology

Consider the following factors when you are designing your replication topology.

  • The need for replication: high availability, geo-location, read scaling, or a combination of all.

  • How many replicas (nodes, servers) you plan to have in your topology.

  • Direction of data flows, both inside of the topology, and data flowing into the topology.

  • How clients will balance across nodes of the topology for their requests (multiple ldap URIs, SRV records, load balancers).

These factors all affect how you may create your topology. (See Section 6.9.3, “Example replication topologies” for some topology examples.)

6.9.3 Example replication topologies

The following sections provide examples of replication topologies, using two to six 389 Directory Server nodes. The maximum number of supported supplier replicas in a topology is twenty. Operational experience shows the optimal number for replication efficiency is a maximum of eight.

6.9.3.1 Two replicas

Example 6.4: Two supplier replicas
┌────┐       ┌────┐
│ S1 │◀─────▶│ S2 │
└────┘       └────┘

In Example 6.4, “Two supplier replicas” there are two replicas, S1 and S2, which replicate bi-directionally between each other, so they are both suppliers and consumers. S1 and S2 could be in separate data centers, or in the same data center. Clients can balance across the servers using LDAP URIs, a load balancer, or DNS SRV records. This is the simplest topology for high availability. Note that each server needs to be able to provide 100% of client load, in case the other server is offline for any reason. A two-node replication is generally not adequate for horizontal read scaling, as a single node will handle all read requests if the other node is offline.

Note
Note: Default topology

The two-node topology should be considered the default topology, because it is the simplest to manage. You can expand your toplogy, over time, as necessary.

6.9.3.2 Four supplier replicas

Example 6.5: Four supplier replicas
┌────┐       ┌────┐
│ S1 │◀─────▶│ S2 │
└────┘       └────┘
   ▲            ▲  
   │            │  
   ▼            ▼  
┌────┐       ┌────┐
│ S3 │◀─────▶│ S4 │
└────┘       └────┘

Example 6.5, “Four supplier replicas” has four supplier replicas, which all synchronize to each other. These could be in four datacenters, or two servers per datacenter. In the case of one node per data center, each node should be able to support 100% of client load. When there are two per datacenter, each one only needs to scale to 50% of the client load.

6.9.3.3 Six replicas

Example 6.6: Six replicas
                  ┌────┐       ┌────┐                   
                  │ S1 │◀─────▶│ S2 │                   
                  └────┘       └────┘                   
                     ▲            ▲                     
                     │            │                     
   ┌────────────┬────┴────────────┴─────┬────────────┐  
   │            │                       │            │  
   ▼            ▼                       ▼            ▼  
┌────┐       ┌────┐                  ┌────┐       ┌────┐
│ S3 │◀─────▶│ S4 │                  │ S5 │◀─────▶│ S6 │
└────┘       └────┘                  └────┘       └────┘

In Example 6.6, “Six replicas”, each pair is in a separate location. S1 and S2 are the suppliers, and S3, S4, S5, and S6 are consumers of S1 and S2. Each pair of servers replicate to each other. S3, S4, S5, and S6 can accept writes, though most of the replication is done through S1 and S2. This setup provides geographic separation for high availability and scaling.

6.9.3.4 Six replicas with read-only consumers

Example 6.7: Six replicas with read-only consumers
             ┌────┐       ┌────┐             
             │ S1 │◀─────▶│ S2 │             
             └────┘       └────┘             
                │            │               
                │            │               
   ┌────────────┼────────────┼────────────┐  
   │            │            │            │  
   ▼            ▼            ▼            ▼  
┌────┐       ┌────┐       ┌────┐       ┌────┐
│ S3 │       │ S4 │       │ S5 │       │ S6 │
└────┘       └────┘       └────┘       └────┘

In Example 6.7, “Six replicas with read-only consumers”, S1 and S2 are the suppliers, and the other four servers are read-only consumers. All changes occur on S1 and S2, and are propagated to the four replicas. Read-only consumers can be configured to store only a subset of the database, or partial entries, to limit data exposure. You could have a fractional read-only server in a DMZ, for example, so that if data is exposed, changes can not propagate back to the other replicas.

6.9.4 Terminology

In the example topologies we have seen that 389 DS can take on a number of roles in a topology. The following list clarifies the terminology.

Replica

An instance of 389 DS with an attached database.

Read-write replica

A replica with a full copy of a database, that accepts read and write operations.

Read-only replica

A replica with a full copy of a database, that only accepts read operations.

Fractional read-only replica

A replica with a partial copy of a database, that only accepts read- only operations.

Supplier

A replica that supplies data from its database to another replica.

Consumer

A replica that receives data from another replica to write into its database.

Replication agreement

The configuration of a server defining its supplier and consumer relation to another replica.

Topology

A set of replicas connected via replication agreements.

Replica ID

A unique identifier of the 389 Directory Server instance within the replication topology.

Replication manager

An account with replication rights in the directory.

6.9.5 Configuring replication

The first example sets up a two node bi-directional replication with a single read-only server, as a minimal starting example. In the following examples, the host names of the two read-write nodes are RW1 and RW2, and the read-only server is RO1. (Of course you must use your own host names.)

All servers should have a backend with an identical suffix. Only one server, RW1, needs an initial copy of the database.

6.9.5.1 Configuring two-node replication

The following commands configure the read-write replicas in a two-node setup (Example 6.4, “Two supplier replicas”), with the hostnames RW1 and RW2. (Remember to use your own hostnames.)

Warning
Warning: Create a strong replication manager password

The replication manager should be considered equivalent to the directory manager, in terms of security and access, and should have a very strong password.

If you create different replication manager passwords for each server, be sure to keep track of which password belongs to which server. For example, when you configure the outbound connection in RW1's replication agreement, you need to set the replication manager password to the RW2 replication manager password.

First, configure RW1:

tux > sudo dsconf INSTANCE-NAME replication create-manager
tux > sudo dsconf INSTANCE-NAME replication enable \ 
--suffix dc=example,dc=com \
--role supplier --replica-id 1 --bind-dn "cn=replication manager,cn=config"

Configure RW2:

tux > sudo dsconf INSTANCE-NAME replication create-manager
tux > sudo dsconf INSTANCE-NAME replication enable \
--suffix dc=example,dc=com \ 
--role supplier --replica-id 2 --bind-dn "cn=replication manager,cn=config"

This will create the replication metadata required on RW1 and RW2. Note the difference in the replica-id between the two servers. This also creates the replication manager account, which is an account with replication rights for authenticating between the two nodes.

RW1 and RW2 are now both configured to have replication metadata. The next step is to create the first agreement for outbound data from RW1 to RW2.

tux > sudo dsconf INSTANCE-NAME repl-agmt create \
--suffix dc=example,dc=com \
--host=RW2 --port=636 --conn-protocol LDAPS --bind-dn "cn=replication manager,cn=config" \
--bind-passwd PASSWORD --bind-method SIMPLE RW1_to_RW2

Data will not flow from RW1 to RW2 until after a full synchronization of the database, which is called an initialization or reinit. This will reset all database content on RW2 to match the content of RW1. Run the following command to trigger a reinit of the data:

tux > sudo dsconf INSTANCE-NAME repl-agmt init \
--suffix dc=example,dc=com RW1_to_RW2

Check the status by running this command on RW1:

tux > sudo dsconf INSTANCE-NAME repl-agmt init-status \
--suffix dc=example,dc=com RW1_to_RW2

When it is finished, you should see a "Agreement successfully initialized" message. If you get an error message, check the errors log. Otherwise, you should see the identical content from RW1 on RW2.

Finally, to make this bi-directional, configure a replication agreement from RW2 outbound to RW1:

tux > sudo dsconf INSTANCE-NAME repl-agmt create \
--suffix dc=example,dc=com \
--host=RW1 --port=636 --conn-protocol LDAPS \
--bind-dn "cn=replication manager,cn=config" --bind-passwd PASSWORD \
--bind-method SIMPLE RW2_to_RW1

Changes made on either RW1 or RW2 will now be replicated to the other. Check replication status on either server with the following command:

tux > sudo dsconf INSTANCE-NAME repl-agmt status \
--suffix dc=example,dc=com \
--bind-dn "cn=replication manager,cn=config" \
--bind-passwd PASSWORD RW2_to_RW1

6.9.5.2 Configuring a read-only node

To create a read-only node, start by creating the replication manager account and metadata. The hostname of the example server is RO3:

Warning
Warning: Create a strong replication manager password

The replication manager should be considered equivalent to the directory manager, in terms of security and access, and should have a very strong password.

If you create different replication manager passwords for each server, be sure to keep track of which password belongs to which server. For example, when you configure the outbound connection in RW1's replication agreement, you need to set the replication manager password to the RW2 replication manager password.

tux > sudo dsconf INSTANCE_NAME replication create-manager
tux > sudo  dsconf INSTANCE_NAME \
replication enable --suffix dc=EXAMPLE,dc=COM \
--role consumer --bind-dn "cn=replication manager,cn=config"

Note that for a read-only replica you do not provide a replica-id, and the role is set to consumer. This allocates a special read-only replica-id for all read-only replicas. After the read-only replica is created, add the replication agreements from RW1 and RW2 to the read-only instance. The following example is on RW1:

tux > sudo dsconf INSTANCE_NAME \
repl-agmt create --suffix dc=EXAMPLE,dc=COM \
--host=RO3 --port=636 --conn-protocol LDAPS \ 
--bind-dn "cn=replication manager,cn=config" --bind-passwd PASSWORD 
--bind-method SIMPLE RW1_to_RO3

The following example, on RW2, configures the replication agreement between RW2 and RO3:

tux > sudo dsconf INSTANCE_NAME repl-agmt create \
--suffix dc=EXAMPLE,dc=COM \
--host=RO3 --port=636 --conn-protocol LDAPS \
--bind-dn "cn=replication manager,cn=config" --bind-passwd PASSWORD \
--bind-method SIMPLE RW2_to_RO3

After these steps are completed, you can use either RW1 or RW2 to perform the initialization of the database on RO3. The following example initalizes RO3 from RW2:

tux > sudo dsconf INSTANCE_NAME repl-agmt init
--suffix dc=EXAMPLE,dc=COM RW2_to_RO3

6.9.6 Monitoring and healthcheck

The dsconf command includes a monitoring option. You can check the status of each replica status directly on the replicas, or from other hosts. The following example commands are run on RW1, checking the status on two remote replicas, and then on itself:

tux > sudo dsconf -D "cn=Directory Manager" ldap://RW2 replication monitor
tux > sudo dsconf -D "cn=Directory Manager" ldap://RO3 replication monitor
tux > sudo dsconf -D "cn=Directory Manager" ldap://RW1 replication monitor

The dsctl command has a healthcheck option. The following example runs a replication healthcheck on the local 389 DS instance:

tux > sudo dsctl INSTANCE_NAME healthcheck --check replication

Use the -v option for verbosity, to see what the healthcheck examines:

tux > sudo dsctl -v INSTANCE_NAME healthcheck --check replication

Run dsctl INSTANCE_NAME healthcheck with no options for a general health check.

Run the following command to see a list of the checks that healthcheck performs:

tux > sudo dsctl INSTANCE_NAME healthcheck --list-checks
config:hr_timestamp
config:passwordscheme
backends:userroot:cl_trimming
backends:userroot:mappingtree
backends:userroot:search
backends:userroot:virt_attrs
encryption:check_tls_version
fschecks:file_perms
[...]

You can run one or more of the individual checks:

tux > sudo dsctl INSTANCE_NAME healthcheck \
--check monitor-disk-space:disk_space tls:certificate_expiration

6.9.7 Making backups

When replication is enabled you need to adjust your 389 Directory Server backup strategy (see Section 6.4, “Backing up and restoring 389 Directory Server” to learn about making backups). If you are using db2ldif you must add the --replication flag to ensure that replication metadata is backed up. You should backup all servers in the topology. When restoring from backup, start by restoring a single node of the topology, then reinitialize all other nodes as new instances.

6.9.8 Pausing and resuming replication

You can pause replication during maintenance windows, or anytime you need to stop it. A node of the topology can only be offline for a maximum of days up to the limit of the changelog (see Section 6.9.9, “ Changelog max-age”).

Use the repl-agmt command to pause replication. The following example is on RW2:

tux > sudo dsconf INSTANCE_NAME repl-agmt disable \
--suffix dc=EXAMPLE,dc=COM RW2_to_RW1

The following example re-enables replication:

tux > sudo dsconf INSTANCE_NAME repl-agmt enable \
--suffix dc=EXAMPLE,dc=COM RW2_to_RW1

6.9.9 Changelog max-age

A replica can be offline for up to the length of time defined by the changelog max-age option. max-age defines the maximum age of any entry in the changelog. Any items older than the max-age value are automatically removed.

After the replica comes back online it will synchronize with the other replicas. If it is offline for longer than the max-age value, the replica will need to be re-initialised, and will refuse to accept or provide changes to other nodes, as they may be inconsistent. The following example sets the max-age to seven days:

tux > sudo dsconf INSTANCE_NAME \
replication set-changelog --max-age 7d \
--suffix dc=EXAMPLE,dc=COM

6.9.10 Removing a replica

To remove a replica, first fence the node to prevent any incoming changes or reads. Then, find all servers that have incoming replication agreements with the node you are removing, and remove them. The following example removes RW2. Start by disabling the outbound replication agreement on RW1:

tux > sudo dsconf INSTANCE_NAME repl-agmt delete \
--suffix dc=EXAMPLE,dc=COM RW1_to_RW2

On the replica you are removing, which in the following example is RW2, remove all outbound agreements:

tux > sudo dsconf INSTANCE_NAME repl-agmt delete \
--suffix dc=EXAMPLE,dc=COM RW2_to_RW1
tux > sudo dsconf INSTANCE_NAME repl-agmt delete \
--suffix dc=EXAMPLE,dc=COM RW2_to_RO3

Stop the instance on RW2:

tux > sudo systemctl stop dirsrv@INSTANCE_NAME.service

Then run the cleanallruv command to remove the replica ID from the topology. The following example is run on RW1:

tux > sudo dsconf INSTANCE_NAME repl-tasks cleanallruv \
--suffix dc=EXAMPLE,dc=COM --replica-id 2
tux > sudo dsconf INSTANCE_NAME repl-tasks list-cleanruv-tasks

6.10 More information

For more information about 389 Directory Server, see:

Print this page