top of page
Recent Posts

POC on Red Hat Directory Server (RHDS)

Updated: Jan 26, 2023

Today we are going do some POC activities (Proof of Concept) on Red Hat Directory Server (RHDS). Because we have found there are few Directory Server available in the market, but our customers are facing some challenges in their Day2 operation with those Directory Servers.


That why, Our customer are looking for better alternative on that. And because of better support and future roadmap, Customer are willing to migrate their Directory Server in RHDS.


Here I will focus below area in my POC for our customer feasibility study:

  • Download & install RHDS

  • Configure and Import data

  • Configure Replication

  • Customised Attributes

  • Attributes Indexing

For our visualization, we will use below topology for our RHDS POC.

Now, let's start.


Download & install RHDS:

1. How to Download Red Hat Directory Server.

2. Pre Installation Preparations.

To verify hostname and other network settings:

[root@localhost ~]#  hostnamectl set-hostname RHDS01.example.com
[root@localhost ~]#  hostname
RHDS01.example.com
[root@RHDS01 ~]# hostnamectl
  Static hostname: RHDS01.example.com
--- intentionally discarded some output ---
[root@RHDS01 ~]# cat /etc/hosts  
--- intentionally discarded some output ---
172.16.20.205 RHDS01.example.com RHDS01
172.16.20.206 RHDS02.example.com RHDS02
[root@RHDS01 ~]# ip r
default via 192.168.121.1 dev enp1s0 proto static metric 100
192.168.121.0/24 dev enp1s0 proto kernel scope link src 192.168.121.192 metric 100
192.168.122.0/24 dev virbr0 proto kernel scope link src 192.168.122.1 linkdown
[root@localhost ~]# hostnamectl set-hostname RHDS02.example.com
[root@localhost ~]# hostname
RHDS02.example.com
[root@RHDS02 ~]# hostnamectl  
  Static hostname: RHDS02.example.com
--- intentionally discarded some output ---
[root@RHDS02 ~]# cat /etc/hosts  
--- intentionally discarded some output ---
172.16.20.205 RHDS01.example.com RHDS01
172.16.20.206 RHDS02.example.com RHDS02
[root@RHDS02 ~]# ip r
default via 192.168.121.1 dev enp1s0 proto static metric 100
192.168.121.0/24 dev enp1s0 proto kernel scope link src 192.168.121.191 metric 100
192.168.122.0/24 dev virbr0 proto kernel scope link src 192.168.122.1 linkdown
[root@RHDS02 ~]# ping RHDS02.example.com -c2
PING RHDS02.example.com (192.168.121.192) 56(84) bytes of data.
64 bytes from RHDS02.example.com (192.168.121.192): icmp_seq=1 ttl=64 time=0.407 ms
64 bytes from RHDS02.example.com (192.168.121.192): icmp_seq=2 ttl=64 time=0.274 ms
--- intentionally discarded some output ---

[root@RHDS02 ~]# ping RHDS01.example.com -c2
PING RHDS01.example.com (192.168.121.191) 56(84) bytes of data.
64 bytes from RHDS01.example.com (192.168.121.191): icmp_seq=1 ttl=64 time=0.029 ms
64 bytes from RHDS01.example.com (192.168.121.191): icmp_seq=2 ttl=64 time=0.040 ms
--- intentionally discarded some output ---

To verify Firewall Settings on both Hosts:

[root@RHDS02 ~]# firewall-cmd --permanent --add-port={389/tcp,636/tcp,9090/tcp}
success
[root@RHDS02 ~]# firewall-cmd --reload
success
[root@RHDS02 ~]# firewall-cmd --list-all
public (active)
--- intentionally discarded some output ---
 services: cockpit dhcpv6-client ssh
 ports: 389/tcp 636/tcp 9090/tcp
--- intentionally discarded some output ---

To verify NTP (Chronyd) Settings on both Hosts:

[root@RHDS02 ~]# systemctl start chronyd
[root@RHDS02 ~]# systemctl enable chronyd
Created symlink /etc/systemd/system/multi-user.target.wants/chronyd.service → /usr/lib/systemd/system/chronyd.service.
[root@RHDS01 ~]# systemctl status chronyd
● chronyd.service - NTP client/server
   Loaded: loaded (/usr/lib/systemd/system/chronyd.service; enabled; vendor preset: enabled)
   Active: active (running) since Fri 2020-12-04 14:29:40 +08; 1h 48min ago
     Docs: man:chronyd(8)
           man:chrony.conf(5)
 Main PID: 5348 (chronyd)
    Tasks: 1 (limit: 101624)
   Memory: 1.8M
   CGroup: /system.slice/chronyd.service
           └─5348 /usr/sbin/chronyd

Dec 04 14:29:40 RHDS01 systemd[1]: Starting NTP client/server...
--- intentionally discarded some output ---
[root@RHDS02 ~]# cat /etc/chrony.conf
--- intentionally discarded some output ---
# Please consider joining the pool (http://www.pool.ntp.org/join.html).
pool 2.rhel.pool.ntp.org iburst

# Record the rate at which the system clock gains/losses time.
driftfile /var/lib/chrony/drift
--- intentionally discarded some output ---

[root@RHDS02 ~]# systemctl restart chronyd
[root@RHDS02 ~]# chronyc sources
MS Name/IP address     	Stratum Poll Reach LastRx Last sample          	 
===============================================================================
^* 2.rhel.pool.ntp.org       	2   6 	7 	2   +125us[  -71us] +/-   45ms
^+ 2.rhel.pool.ntp.org       	2   6 	7 	2   -189us[ -385us] +/-   78ms

[root@RHDS02 ~]# chronyc tracking
Reference ID	: 679DC605 (2.rhel.pool.ntp.org)
Stratum     	: 3
Ref time (UTC)  : Wed Jan 25 07:26:58 2023
System time 	: 0.000000153 seconds slow of NTP time
Last offset 	: +0.000146637 seconds
RMS offset  	: 0.000146637 seconds
Frequency   	: 10.057 ppm slow
Residual freq   : -0.209 ppm
Skew        	: 0.143 ppm
Root delay  	: 0.024207743 seconds
Root dispersion : 0.033127308 seconds
Update interval : 2.0 seconds
Leap status 	: Normal

3. Installation Of RHDS.

If you have direct internet connectivity then you can configure the Red Hat Subscription Management and enable the required repository.


Alternatively, you can download the RHEL8 ISO and the RHDS ISO and configure you local repo according afyer the iso mount. Sample local repo file, as below:

[root@RHDS02 ~]# cat /etc/yum.repos.d/local.repo 
[AppStream]
name=RHEL8 AppStream
baseurl=file:///mnt/rhel/AppStream
gpgcheck=0
enabled=1
[BaseOS]
name=RHEL8 BaseOS
baseurl=file:///mnt/rhel/BaseOS
gpgcheck=0
enabled=1
[DS]
name=RHDS 11
baseurl=file:///mnt/ds
gpgcheck=0
enabled=1
Note: How to mount a .iso file in RHEL, https://access.redhat.com/solutions/37072

Install RHDS 11 rpms on both Hosts:

[root@RHDS01 ~]# yum module install redhat-ds:11
 Verifying        : perl-Archive-Tar-2.30-1.el8.noarch             5/21 
  Verifying        : perl-Compress-Raw-Bzip2-2.081-1.el8.x86_6     6/21 
  Verifying        : perl-Compress-Raw-Zlib-2.081-1.el8.x86_64     7/21 
  Verifying        : perl-IO-Compress-2.081-1.el8.noarch           8/21 
--- intentionally discarded some output ---
Installed:
  389-ds-base-1.4.2.12-2.module+el8dsrv+6428+6e54c518.x86_64                                                        
  389-ds-base-libs-1.4.2.12-2.module+el8dsrv+6428+6e54c518.x86_64                                                   
  cockpit-389-ds-1.4.2.12-2.module+el8dsrv+6428+6e54c518.noarch                                                     
  cyrus-sasl-md5-2.1.27-1.el8.x86_64                                                                                
  nss-tools-3.44.0-15.el8.x86_64                                                                                    
  openldap-clients-2.4.46-11.el8.x86_64                                                                             
  openssl-perl-1:1.1.1c-15.el8.x86_64                                                                               
  perl-Algorithm-Diff-1.1903-9.el8.noarch                                                                           
  perl-Archive-Tar-2.30-1.el8.noarch                                                                                
  perl-Compress-Raw-Bzip2-2.081-1.el8.x86_64                                                                        
  perl-Compress-Raw-Zlib-2.081-1.el8.x86_64                                                                         
  perl-DB_File-1.842-1.el8.x86_64                                                                                   
  perl-IO-Compress-2.081-1.el8.noarch                                                                               
  perl-IO-Zlib-1:1.10-416.el8.noarch                                                                                
  perl-Text-Diff-1.45-2.el8.noarch                                                                                  
  python3-argcomplete-1.9.3-6.el8.noarch                                                                            
  python3-distro-1.4.0-2.module+el8.1.0+3334+5cb623d7.noarch                                                        
  python3-ldap-3.1.0-5.el8.x86_64                                                                                   
  python3-lib389-1.4.2.12-2.module+el8dsrv+6428+6e54c518.noarch                                                     
  python3-pyasn1-0.3.7-6.el8.noarch                                                                                 
  python3-pyasn1-modules-0.3.7-6.el8.noarch                                                                         

Complete!

Configure and Import data

1. Basic Configure on RHDS01 using CLI (Command Line Interface).

Instance creation (RHDS01):

[root@RHDS01 ~]# mkdir RHDS01
[root@RHDS01 ~]# cd RHDS01/
[root@RHDS01 RHDS01]# dscreate create-template rhds01.inf
[root@csv-vm-rhds02 installation]# ll
total 12
-rw-------. 1 root root 9634 Dec  4 03:59 mbbmyrhds01.inf

[root@RHDS01 RHDS01]# cat /root/rhds/installation/rhds02.inf 
[general]
--- intentionally discarded some output ---
;full_machine_name = RHDS01.example.com
--- intentionally discarded some output ---
[slapd]
--- intentionally discarded some output ---
instance_name = rhds01
--- intentionally discarded some output --- 
root_password = redhat123

[root@RHDS01 RHDS01]# dscreate from-file rhds01.inf
Starting installation ...
Validate installation settings ...
Create file system structures ...
Create self-signed certificate database ...
Perform SELinux labeling ...
Perform post-installation tasks ...
Completed installation for instance: slapd-rhds01

[root@RHDS01 RHDS01]# dsctl --list
slapd-rhds01

Creating Root Suffix (RHDS01):

[root@RHDS01 RHDS01]# dsconf -D "cn=Directory Manager" ldap://RHDS01.example.com backend create --suffix "o=example" --be-name="example"
Enter password for cn=Directory Manager on ldap://RHDS01.example.com:
The database was sucessfully created

Creating Root Entries (RHDS01):

[root@RHDS01 RHDS01]# ldapmodify -D "cn=Directory Manager" -W -p 389 -h RHDS01.example.com -x
Enter LDAP Password:
dn: o=example
changetype: add
objectClass: top
objectClass: domain
dc: cm

adding new entry "o=example"

2. Import Data from .ldif Files (RHDS01).

[root@RHDS01 RHDS01]# cat >> people-root-entry.ldif << END
dn: ou=People,o=example
uid: user
givenName: given_name
objectClass: top
objectClass: person
objectClass: organizationalPerson
objectClass: inetorgperson
sn: surname
cn: user
END

[root@RHDS01 RHDS01]# cat >> group-root-entry.ldif << END
dn: ou=Group,o=example
uid: user
givenName: given_name
objectClass: top
objectClass: person
objectClass: organizationalPerson
objectClass: inetorgperson
sn: surname
cn: user
END

[root@RHDS01 RHDS01]# cat >> services-root-entry.ldif << END
dn: ou=services,o=example
uid: user
givenName: given_name
objectClass: top
objectClass: person
objectClass: organizationalPerson
objectClass: inetorgperson
sn: surname
cn: user
END

[root@RHDS01 RHDS01]# cat >> admin1-user.ldif << END 
dn: uid=admin1,ou=People,o=example
uid: admin1
objectClass: top
objectClass: person
objectClass: organizationalPerson
objectClass: inetorgperson
cn: admin1
sn: Administrator
ou: People
userPassword: redhat123
END
[root@RHDS01 RHDS01]# ldapmodify -a -D "cn=Directory Manager" -W -p 389 -h RHDS01.example.com -x -f people-root-entry.ldif
Enter LDAP Password:
adding new entry "ou=People,o=example"

[root@RHDS01 RHDS01]# ldapmodify -a -D "cn=Directory Manager" -W -p 389 -h RHDS01.example.com -x -f group-root-entry.ldif
Enter LDAP Password:
adding new entry "ou=Group,o=example"

[root@RHDS01 RHDS01]# ldapmodify -a -D "cn=Directory Manager" -W -p 389 -h RHDS01.example.com -x -f services-root-entry.ldif
Enter LDAP Password:
adding new entry "ou=services,o=example"

[root@RHDS01 RHDS01]# ldapmodify -a -D "cn=Directory Manager" -W -p 389 -h RHDS01.example.com -x -f admin1-user.ldif
Enter LDAP Password:
adding new entry "uid=admin1,ou=People,o=example"

Allow admin1 user to read and search entries:

[root@RHDS01 RHDS01]#  ldapmodify -D "cn=Directory Manager" -W -p 389 -h RHDS01.example.com -x
Enter LDAP Password:  
dn: ou=people,o=example
changetype: modify
add: aci
aci: (targetattr = "*") (target = "ldap:///ou=People,o=example") (version 3.0;
 acl "Allow admin1 to read and search entries"; allow (all)
 (userdn = "ldap:///uid=admin1,ou=People,o=example");)

modifying entry "ou=People,o=example"

To verify admin1 user can read and search entries:

[root@RHDS01 RHDS01]# ldapsearch -D "uid=admin1,ou=people,o=example" -W -p 389 -h RHDS01.example.com -b "ou=People,o=example" -s sub -x "(objectclass=*)"       
Enter LDAP Password:
# extended LDIF
#
# LDAPv3
# base <ou=People,o=example> with scope subtree
# filter: (objectclass=*)
# requesting: ALL
#
# People, example
dn: ou=People,o=example
uid: user
givenName: given_name
objectClass: top
objectClass: person
objectClass: organizationalPerson
objectClass: inetorgperson
sn: surname
cn: user
ou: People

# admin1, People, example
dn: uid=admin1,ou=People,o=example
uid: admin1
objectClass: top
objectClass: person
objectClass: organizationalPerson
objectClass: inetorgperson
cn: admin1
sn: sso
ou: People
userPassword:: e1BCS0RGMl9TSEEyNTZ9QUFBSUFLUzlpMkJST2dxWTU4ZnF1UlRKSy8zcGVZV3R
 rUG5ybTFRTDl6Q0FqTkpuRlloWUVIQ2NtWmhEU3Zzb1ZNNnJWamR0NEFHTUNZSjV4T0xINm4vSGRO
 NXRUQXFteEYyajBCVzZBVmpJZHYwSHpMYjRFT3NQNkpTVUs1MHNWMUw5YTF3Q1RRUnRHWTl0SEtLR
 DgzQ0JsS1dUK2F6djVPSm9FQ2ZUNzFwOVNsYVpYcDZ4aXZBQ0I5TnVHZVNiYnFCalExaTFVR09jcX
 hTWllibkRUY3d4SGRhNWtzMFdFNDhFQmhXRUZxbmpJR1Q0S1pOR2dDWE9BamtaTW90dkl5bGZKS2J
 UVGQ4dWN1MkVqSTB6S0x4TE1QSWwwUUxaMWRoZWxDYVdXTnhTdXlWdE95dCswdmkvSmdXaGVEQmZX
 MzlYdUNYMnAraHdyZDhGL2dkdnd2TU81aUpna09VWHExaWEvUWlSZGJjeDBvMkhmajJWOHNqMzBIW
 XdyUjF3L2dCNkNZRFNuN0ZiSFJSc1hkcFpmQy8yUi9QSTZiZzk1MGN1MEYzeGR3TkUzVXVD

# search result
search: 2
result: 0 Success

# numResponses: 3
# numEntries: 2

How to modify LDAP entry using LDAP Client Tools:

Red Hat Directory Server uses the LDAP tools (such as ldapsearch and ldapmodify) supplied with OpenLDAP. And we can modify, search entries, if reqruired. Here are some exmple and refer below link for more details. https://access.redhat.com/documentation/en-us/red_hat_directory_server/11/html/administration_guide/ldap-tools-examples

  • To replace an Attribute to an Entry:

[root@RHDS01 RHDS01]# ldapmodify -D "cn=Directory Manager" -W -p 389 -h RHDS01.example.com -x
Enter LDAP Password:
dn: uid=admin1,ou=People,o=example
changetype: modify
replace: sn
sn: Administrator

modifying entry "uid=admin1,ou=People,o=example"
  • To add an Attribute to an Entry

[root@RHDS01 RHDS01]# ldapmodify -D "cn=Directory Manager" -W -p 389 -h RHDS01.example.com -x
Enter LDAP Password:
dn: uid=admin1,ou=People,o=example
changetype: modify
add: pwdUpdateTime
pwdUpdateTime: 20230105074359Z

modifying entry "uid=admin1,ou=People,o=example"

3. Configure Password Policy (RHDS01).

[root@RHDS01 RHDS01]# dsconf -D "cn=Directory Manager" ldap://RHDS01.example.com pwpolicy get
Enter password for cn=Directory Manager on ldap://RHDS01.example.com:
Global Password Policy: cn=config
--- intentionally discarded some output --- 
nsslapd-pwpolicy-local: off
passwordstoragescheme: PBKDF2_SHA256
passwordchange: on
passwordmustchange: off
passwordhistory: off
passwordinhistory: 6
passwordadmindn:
passwordtrackupdatetime: off
passwordwarning: 86400
passwordisglobalpolicy: off
passwordexp: off
passwordmaxage: 8640000
passwordminage: 0
passwordgracelimit: 0
passwordsendexpiringtime: off
--- intentionally discarded some output --- 
passworddictpath:
nsslapd-allow-hashed-passwords: off
nsslapd-pwpolicy-inherit-global: off
passwordTPRMaxUse: -1
passwordTPRDelayExpireAt: -1
passwordTPRDelayValidFrom: -1

### PASSWORD RULES ###
[root@RHDS01 RHDS01]#  dsconf -D "cn=Directory Manager" ldap://RHDS01.example.com pwpolicy set --pwdchecksyntax=on --pwdminlen=12 --pwdmindigits=2 --pwdminuppers=2 --pwdminlowers=2 --pwdminspecials=2
Enter password for cn=Directory Manager on ldap://RHDS01.example.com:
Successfully updated global password policy

### CHANGED TO 30 FOR TESTING ###
[root@RHDS01 RHDS01]# dsconf -D "cn=Directory Manager" ldap://RHDS01.example.com pwpolicy set --pwdexpire=on --pwdmaxage=31536000
Enter password for cn=Directory Manager on ldap://RHDS01.example.com:
Successfully updated global password policy

### DISABLED FOR NOW ###
[root@RHDS01 RHDS01]# dsconf -D "cn=Directory Manager" ldap://RHDS01.example.com pwpolicy set --pwdmustchange=on
Enter password for cn=Directory Manager on ldap://RHDS01.example.com:
Successfully updated global password policy
Note: You can manage Password Policy from the GUI (web Console) as well. And it need to configure other RHDS host (or all the host) individually.
will have more on GUI (web Console) later on.

4. Configure SSL (RHDS01):

To create a certificate signing request (CSR) for RHDS01:

[root@RHDS01 RHDS01]# dsctl rhds01 tls generate-server-cert-csr \
--subject " \
CN=RHDS01.example.com, \
O=EXAMPLE, \
OU=ITSEC, \
MAIL=it@example.com, \
L=KL, \
ST=KL, \
C=MY \
" \
RHDS01.example.com

/etc/dirsrv/slapd-rhds01/Server-Cert.csr

To verify the certificate signing request (CSR) for RHDS01:

[root@RHDS01 RHDS01]#  openssl req -text -noout -verify -in /etc/dirsrv/slapd-rhds01/Server-Cert.csr
[root@RHDS01 RHDS01]# openssl req -text -noout -verify -in /etc/dirsrv/slapd-rhds01/Server-Cert.csr
verify OK
Certificate Request:
	Data:
    	Version: 1 (0x0)
    	Subject: C = MY, ST = KL, L = KL, mail = it@example.com, OU = ITSEC, O = EXAMPLE, CN = RHDS01.example.com
    	Subject Public Key Info:
        	Public Key Algorithm: rsaEncryption
            	RSA Public-Key: (4096 bit)
            	Modulus:
                	00:bf:60:ee:44:a1:d0:8f:3f:0c:ef:ae:38:ad:b1:
--- intentionally discarded some output --- 
                	dd:83:34:b2:b7:9d:b2:49:59:43:bc:1a:7e:cd:2f:
                	f4:b7:e3
            	Exponent: 65537 (0x10001)
    	Attributes:
    	Requested Extensions:
        	X509v3 Subject Alternative Name:
            	DNS:RHDS01.example.com
        	Netscape Cert Type:
            	SSL Client, SSL Server
        	X509v3 Extended Key Usage:
            	TLS Web Client Authentication, TLS Web Server Authentication
        	X509v3 Key Usage:
            	Digital Signature, Non Repudiation, Key Encipherment, Data Encipherment
	Signature Algorithm: sha256WithRSAEncryption
     	b6:3c:df:05:5e:a2:15:d0:5b:0c:25:ac:30:c1:67:8f:72:a7:
 --- intentionally discarded some output --- 
     	07:f1:71:c5:05:d7:ea:43:c8:52:41:00:3b:9b:f7:2e:b7:dc:
     	f5:5b:f5:51:3f:a4:52:70
[root@RHDS01 RHDS01]#

To add root ca certificate and the signined certificate for RHDS01:

[root@RHDS01 RHDS01]# dsconf rhds01 security ca-certificate add --file /root/internalca/rootCACert.pem --name "Root CA"

[root@RHDS01 RHDS01]# dsconf rhds01 security certificate add --file /root/internalca/certs/RHDS01.pem --name "RHDS01.example.com" --primary-cert
Note: How to install a CA certificate on Red Hat Enterprise Linux 7 and later. https://access.redhat.com/solutions/5868401

To enable the TLS for RHDS01:

[root@RHDS01 RHDS01]# dsconf -D "cn=Directory Manager" ldap://RHDS01.example.com config replace nsslapd-securePort=636 nsslapd-security=on
Enter password for cn=Directory Manager on ldap://RHDS01.example.com:
Successfully replaced "nsslapd-securePort"
Successfully replaced "nsslapd-security"
You can delete the self-signed certificate, To list the existing certificates # dsconf -D "cn=Directory Manager" ldap://RHDS01.example.com security certificate list
Certificate Name: Server-Cert
Subject DN: CN=server.example.com
Issuer DN: CN=Example CA
Expires: 2022-07-29 11:10:14
Trust Flags: ,,
and to deltete the certificates: # dsconf -D "cn=Directory Manager" ldap://RHDS01.example.com security certificate del Server-Cert

To edit certificate trust flags:

[root@RHDS01 certs]#  dsconf -D "cn=Directory Manager" ldap://RHDS01.example.com security rsa set --tls-allow-rsa-certificates on --nss-token "internal (software)" --nss-cert-name RHDS01.example.com

To restart the RHDS instances (rhds01):

[root@RHDS01 certs]# dsctl rhds01 restart
Instance "rhds01" has been restarted

5. Instance Creation on RHDS02 using gui (web console).

Login to https://RHDS01.example.com:9090 cockpit web console:

Note: In case you don't know that how to install Cockpit on RHEL 8 and RHEL 9 https://access.redhat.com/solutions/4386921

and navigate and click the "Red Hat Directory Server" from the left hand side menu bar as below:

To create a Instance (rhds02).

Click "Create New Instance"

and fill-up the minimum required field to create new Instance as below:

To create a suffix (rhds02).

Click the "Database" tab and click "Create Suffix", as below:

and fill-up the minimum required field to create new suffix database, as below:


Configure Replication

To enabled replication on RHDS02:

[root@RHDS02 ~]# dsconf -D "cn=Directory Manager" ldap://RHDS02.example.com replication \
    enable --suffix="o=example" --role="supplier" --replica-id=202 \
    --bind-dn="cn=replication manager,cn=config" --bind-passwd="redhat123"
Enter password for cn=Directory Manager on ldap://RHDS02.example.com:
Replication successfully enabled for "o=example"

To enabled replication on RHDS01:

[root@RHDS01 ~]# dsconf -D "cn=Directory Manager" ldap://RHDS01.example.com replication \
    enable --suffix="o=example" --role="supplier" --replica-id=201 \
    --bind-dn="cn=replication manager,cn=config" --bind-passwd="redhat123"
Enter password for cn=Directory Manager on ldap://RHDS01.example.com:
Replication successfully enabled for "o=example"

To create a replication agreements from RHDS01 to RHDS02 on RHDS01 and initialized:

[root@RHDS01 ~]# dsconf -D "cn=Directory Manager" ldap://RHDS01.example.com repl-agmt \
     create --suffix="o=example" --host="RHDS02.example.com" --port=636 \
     --conn-protocol=LDAPS --bind-dn="cn=replication manager,cn=config" \
     --bind-passwd="redhat123" --bind-method=SIMPLE --init \
     master1-to-master2
Enter password for cn=Directory Manager on ldap://RHDS01.example.com:
Successfully created replication agreement "master1-to-master2"
Agreement initialization started...

To verify the replication agreements status and list:

[root@RHDS01 ~]# dsconf -D "cn=Directory Manager" ldap://RHDS01.example.com repl-agmt  list --suffix "o=example"
Enter password for cn=Directory Manager on ldap://RHDS01.example.com:
dn: cn=master1-to-master2,cn=replica,cn=o\3Dexample,cn=mapping tree,cn=config
cn: master1-to-master2
description: master1-to-master2
nsDS5ReplicaBindDN: cn=replication manager,cn=config
nsDS5ReplicaBindMethod: simple
nsDS5ReplicaCredentials: {AES-TUhNR0NTcUdTSWIzRFFFRkRUQm1NRVVHQ1NxR1NJYjNEUUVGRERBNEJDUTBaRGt6WlRnd1ppMDJNems1TXpnMg0KWWkxaE5XRm1ZbU00TnkwNFlXUmhZamMyWlFBQ0FRSUNBU0F3Q2dZSUtvWklodmNOQWdjd0hRWUpZSVpJQVdVRA0KQkFFcUJCQkNmZkdKMi9wYXpCVEd4N0EvQWtNSQ==}/WeswCdzHZ041gfoYYInFA==
nsDS5ReplicaHost: RHDS02.example.com
nsDS5ReplicaPort: 636
nsDS5ReplicaRoot: o=example
nsDS5ReplicaTransportInfo: LDAPS
nsds5replicaChangesSentSinceStartup:: MjAxOjcvMCA=
nsds5replicaLastInitEnd: 20230125091949Z
nsds5replicaLastInitStart: 20230125091947Z
nsds5replicaLastInitStatus: Error (0) Total update succeeded
nsds5replicaLastInitStatusJSON: {"state": "green", "ldap_rc": "0", "ldap_rc_text": "Success", "repl_rc": "0", "repl_rc_text": "replica acquired", "conn_rc": "0", "conn_rc_text": "operation success", "date": "2023-01-25T09:19:50Z", "message": "Error (0) Total update succeeded"}
nsds5replicaLastUpdateEnd: 20230125094951Z
nsds5replicaLastUpdateStart: 20230125094951Z
nsds5replicaLastUpdateStatus: Error (0) Replica acquired successfully: Incremental update succeeded
nsds5replicaLastUpdateStatusJSON: {"state": "green", "ldap_rc": "0", "ldap_rc_text": "Success", "repl_rc": "0", "repl_rc_text": "replica acquired", "date": "2023-01-25T09:49:51Z", "message": "Error (0) Replica acquired successfully: Incremental update succeeded"}
nsds5replicaUpdateInProgress: FALSE
nsds5replicareapactive: 0
objectClass: top
objectClass: nsds5replicationagreement
[root@RHDS01 certs]# dsconf -D "cn=Directory Manager" ldap://RHDS01.example.com repl-agmt  status --suffix="o=example" --bind-dn="cn=replication manager,cn=config"  --bind-passwd="redhat123" master1-to-master2
Enter password for cn=Directory Manager on ldap://RHDS01.example.com:
Status For Agreement: "master1-to-master2" (RHDS02.example.com:636)
Replica Enabled: on
Update In Progress: FALSE
Last Update Start: 20230125094951Z
Last Update End: 20230125094951Z
Number Of Changes Sent: 201:7/0
Number Of Changes Skipped: None
Last Update Status: Error (0) Replica acquired successfully: Incremental update succeeded
Last Init Start: 20230125091947Z
Last Init End: 20230125091949Z
Last Init Status: Error (0) Total update succeeded
Reap Active: 0
Replication Status: Not in Synchronization: supplier (63d0f433000200c90000) consumer (Unavailable) State (green) Reason (error (0) replica acquired successfully: incremental update succeeded)
Replication Lag Time: unavailable
[root@RHDS01 certs]# dsconf -D "cn=Directory Manager" ldap://RHDS01.example.com replication status --suffix="o=example"
Enter password for cn=Directory Manager on ldap://RHDS01.example.com:
{'agmt-name': ['master1-to-master2'], 'replica': ['RHDS02.example.com:636'], 'replica-enabled': ['on'], 'update-in-progress': ['FALSE'], 'last-update-start': ['20230125095451Z'], 'last-update-end': ['20230125095451Z'], 'number-changes-sent': ['201:8/0 '], 'number-changes-skipped': ['unavailable'], 'last-update-status': ['Error (0) Replica acquired successfully: Incremental update succeeded'], 'last-init-start': ['20230125091947Z'], 'last-init-end': ['20230125091949Z'], 'last-init-status': ['Error (0) Total update succeeded'], 'reap-active': ['0'], 'replication-status': ['Not in Synchronization: supplier (63d0f433000200c90000) consumer (Unavailable) State (green) Reason (error (0) replica acquired successfully: incremental update succeeded)'], 'replication-lag-time': ['unavailable']}

To verify the replication tasks:

[root@RHDS01 certs]# dsconf -D "cn=Directory Manager" ldap://RHDS01.example.com repl-tasks list-abortruv-tasks --suffix="o=example"
Enter password for cn=Directory Manager on ldap://RHDS01.example.com:
No CleanAllRUV abort tasks found
[root@RHDS01 certs]# dsconf -D "cn=Directory Manager" ldap://RHDS01.example.com repl-tasks list-cleanruv-tasks --suffix="o=example"
Enter password for cn=Directory Manager on ldap://RHDS01.example.com:
No CleanAllRUV tasks found

To verify the replication configuration and status for the gui (web console):

The replication agreements Configuration:

The replication agreements status:

Once replication initialized and enabled the agreements, afterward all the entries will be replicated from rhds01 host to rhds02 host. And we can nevigate the LDAP Tree from the gui (web Console) under the "LDAP Browser", as below:

Initially, we have create only suffix "o=example" and now it has populated with all the remaining entries from the rhds01 host.


Attributes Indexing

To add custom attributes and objectClass in the schema:

The custom object classes and attributes are defined in the 99user.ldif file. Each individual instance maintains its own 99user.ldif file in the /etc/dirsrv/slapd-instance_name/schema/ directory.


We are going update the /etc/dirsrv/slapd-instance_name/schema/99user.ldif, but

It is also possible to create custom schema files and dynamically reload the schema into the server. Please refer the links below:


To update 99user.ldif file:

[root@RHDS01 RHDS01]# vi /etc/dirsrv/slapd-rhds01/schema/99user.ldif 
 --- intentionally discarded some output --- 
# User-defined schema
#
dn: cn=schema
attributeTypes: ( GenderFlag-oid NAME 'GenderFlag' DESC 'user gender identity' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE X-ORIGIN 'user defined')
objectClasses: ( userGender-oid NAME 'userGender' DESC 'user gender identity' SUP top STRUCTURAL MUST ( GenderFlag ) X-ORIGIN 'user  defined')
attributeTypes: ( nid-oid NAME 'nid' DESC 'User National ID' SYNTAX  1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE X-ORIGIN 'user defined' )
objectClasses: ( nationalID-oid NAME 'nationalID' DESC 'User National ID' SUP top STRUCTURAL MUST ( nid ) MAY ( cn $ uid ) X-ORIGIN 'user defined')

To reload schema once updated completed:

[root@RHDS01 ~]# dsconf -D "cn=Directory Manager" ldap://RHDS01.example.com schema reload
Enter password for cn=Directory Manager on ldap://RHDS01.example.com:
Attempting to add task entry... This will fail if Schema Reload plug-in is not enabled.
Successfully added task entry cn=schema_reload_2023-01-25T09:11:06.357224,cn=schema reload task,cn=tasks,cn=config
To verify that the schema reload operation was successful, please check the error logs.
Note: we can run "dsconf rhds01 schema reload" to reload schema as well.

To verify the error logs for reload schema activities:

[root@RHDS01 RHDS01]# tail /var/log/dirsrv/slapd-rhds01/errors
 --- intentionally discarded some output --- 
[26/Jan/2023:01:16:33.762155940 -0500] - INFO - schemareload - schemareload_thread - Schema reload task starts (schema dir: default) ...
[26/Jan/2023:01:16:33.797712377 -0500] - INFO - schemareload - schemareload_thread - Schema validation passed.
[26/Jan/2023:01:16:33.826328497 -0500] - INFO - schemareload - schemareload_thread - Schema reload task finished.
Note: you need to do the same on other (all the RHDS hosts). And If there is any error found the the sample messages would be as below:
[26/Jan/2023:01:19:02.468968577 -0500] - INFO - schemareload - schemareload_thread - Schema reload task starts (schema dir: default) ...
[26/Jan/2023:01:19:02.502239279 -0500] - ERR - dse_read_one_file - The entry cn=schema in file /etc/dirsrv/slapd-rhds01/schema/99user.ldif (lineno: 1) is invalid, error code 21 (Invalid syntax) - object class ( nationalID-oid NAME 'nationalID' DESC 'User National ID' SUP top STRUCTUR AL MUST ( nid ) MAY ( cn $ uid ) X-ORIGIN 'user defined'): Failed to parse objectclass, error(2) at ( AL MUST ( nid ) MAY ( cn $ uid ) X-ORIGIN 'user defined'))
[26/Jan/2023:01:19:02.503798980 -0500] - ERR - schema_reload - slapi_validate_schema_files failed
[26/Jan/2023:01:19:02.505038078 -0500] - ERR - schemareload - schemareload_thread - Schema validation failed.

To create a ldif file for import a new user entry with new two attributes:

[root@RHDS01 RHDS01]# cat ldap-user.ldif
dn: uid=mhaque,ou=People,o=example
uid: mhaque
objectClass: top
objectClass: person
objectClass: organizationalPerson
objectClass: inetorgperson
objectClass: nationalID
objectClass: userGender
GenderFlag: M
nid: 24245353553
cn: mhaque
sn: mhaque
ou: People
userPassword: redhat123

To import that new user entry:

[root@RHDS01 RHDS01]# ldapmodify -a -D "cn=Directory Manager" -W -p 389 -h RHDS01.example.com -x -f ldap-user.ldif
Enter LDAP Password:
adding new entry "uid=mhaque,ou=People,o=example"

To create a new indexing using NID attribute from gui (web console):

Click the suffix "o=eample" from the Database tab and click create index.

Find the nid attribute and check the required index type. And check "Index attribute after creation" box to indexing after creation.


Hopefully this article will help you do POC in your environment and play around with your actual data migration. will comeback on the client side configuration in my next post. have a nice weekend.

600 views1 comment
Log In to Connect With Members
View and follow other members, leave comments & more.
bottom of page