Setting up an LDAP System in an AWS Cluster
- Joseph

- 3 days ago
- 8 min read
Updated: 22 hours ago
This is the sixth part of an eight- part series on how to set up an HPC cluster on AWS. This document explains how to setup LDAP in the cluster
The cluster has seven virtual machines (VMs)
One head / control node (node1)
One login node (node2)
Three compute nodes (node3, node4, node 5)
Two storage nodes (node6, node7)
All the VMs will have the OS Rocky Linux 9.6 (Blue Onyx)
Lightweight Directory Access Protocol (LDAP) is a protocol used for accessing and managing directory services over a network. It is commonly used for centralised authentication and authorisation in enterprise environments. By integrating LDAP with a PBS cluster, user authentication and management can be centralised, making it easier to handle user accounts and permissions across multiple nodes in the cluster.
LDAP has two types of nodes
LDAP server - Head node (node1)
LDAP clients - Login node (node2)
To avoid this discrepancy when installing packages, follow the steps outlined in the second part of this series. That document also explains how to disable SELinux. Also, make sure passwordless SSH access between all the nodes in the cluster is set up. Check out the third part of this series on how to do this.
LDAP Server Configuration
On the head node (node1), install OpenLDAP packages.
sudo dnf install openldap-servers openldap-clientsYou can now start the srever
sudo systemctl start slapd
sudo systemctl enable slapd
sudo systemctl status slapdThe slappasswd command is a utility in OpenLDAP used to generate encrypted (hashed) passwords that can be safely stored in the LDAP directory. It’s not for changing passwords directly inside LDAP — rather, it creates a secure password hash that you can then manually add or update in an LDAP entry (for example, in olcRootPW or userPassword attributes). One thing to note is that slappasswd generates different hashes for the same password each time because it uses a salted hashing algorithm. In the next step, find the hash of the password you want to use as the LDAP admin password.
slappasswdIn this setup, we are using the password ldappassword. Let us assume the hash generated for password ldappassword is {SSHA}UNHjdYvrkQIhD9vRlShjlADjmJF/hhcm. Now we use this hash in the following LDIF file to set the LDAP admin password. In LDAP (Lightweight Directory Access Protocol), an LDIF (LDAP Data Interchange Format) file is a plain-text file used to represent directory data and configuration in a standard, portable format. So we use the following LDIF file (changerootpass.ldif) to set the admin password for LDAP.
dn: olcDatabase={0}config,cn=config
changetype: modify
add: olcRootPW
olcRootPW: {SSHA}UNHjdYvrkQIhD9vRlShjlADjmJF/hhcmLine | Meaning |
dn: olcDatabase={0}config,cn=config | This specifies the Distinguished Name (DN) of the LDAP entry being modified — in this case, it’s the configuration database itself. {0}config is the internal configuration backend used by slapd (the LDAP daemon). |
changetype: modify | Tells LDAP you’re performing a modification (not adding or deleting an entire entry). |
add: olcRootPW | You’re adding a new attribute named olcRootPW to this configuration entry. |
olcRootPW: {SSHA}UNHjdYvrkQIhD9vRlShjlADjmJF/hhcm | This is the hashed password (generated using slappasswd) that becomes the root bind password for this configuration database. |
Now we run the command
sudo ldapadd -Y EXTERNAL -H ldapi:/// -f changerootpass.ldifThis command applies configuration changes from changerootpass.ldif to the local LDAP server. It connects via the local UNIX socket (`ldapi:///`) and authenticates as the system user using SASL EXTERNAL. SASL (Simple Authentication and Security Layer) is a framework that allows LDAP to use different authentication methods. The EXTERNAL mechanism means the authentication is done outside of LDAP, using the identity provided by the connection itself (root).
The next step is to add the necessary LDAP schemas. In LDAP schema defines the structure, rules, and types of data that can be stored in the directory. Schemas specify which object classes and attributes are allowed and how they relate to each other. Without loading the necessary schemas, LDAP wouldn’t know how to handle common entries like users, groups, or email addresses.
In this case, we are loading three schemas:
cosine.ldif: Provides general-purpose internet-related attributes and object classes for users and groups.
nis.ldif: Adds UNIX/Linux account and group attributes for system integration.
inetorgperson.ldif: Defines detailed human user attributes for directories and identity management.
To add the schemas to LDAP, use the commands.
sudo ldapadd -Y EXTERNAL -H ldapi:/// -f /etc/openldap/schema/cosine.ldif
sudo ldapadd -Y EXTERNAL -H ldapi:/// -f /etc/openldap/schema/nis.ldif
sudo ldapadd -Y EXTERNAL -H ldapi:/// -f /etc/openldap/schema/inetorgperson.ldifThen restart the LDAP service
sudo systemctl restart slapdThe next step is to set the domain and configure the LDAP database. Create a file named setdomain.ldif with the following content:
# Give local root (UID 0) and Manager read access to the monitor database
dn: olcDatabase={1}monitor,cn=config
changetype: modify
replace: olcAccess
olcAccess: {0}to *
by dn.base="gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth" read
by dn.base="cn=Manager,dc=cluster,dc=lan" read
by * none
# Set the LDAP database suffix (your domain)
dn: olcDatabase={2}mdb,cn=config
changetype: modify
replace: olcSuffix
olcSuffix: dc=cluster,dc=lan
# Define the root DN (admin user for LDAP)
dn: olcDatabase={2}mdb,cn=config
changetype: modify
replace: olcRootDN
olcRootDN: cn=Manager,dc=cluster,dc=lan
# Add root password (replace with your own SSHA hash)
dn: olcDatabase={2}mdb,cn=config
changetype: modify
add: olcRootPW
olcRootPW: {SSHA}UNHjdYvrkQIhD9vRlShjlADjmJF/hhcm
# Set access control rules for users and the admin
dn: olcDatabase={2}mdb,cn=config
changetype: modify
add: olcAccess
olcAccess: {0}to attrs=userPassword,shadowLastChange
by dn="cn=Manager,dc=cluster,dc=lan" write
by anonymous auth
by self write
by * none
olcAccess: {1}to dn.base="" by * read
olcAccess: {2}to *
by dn="cn=Manager,dc=cluster,dc=lan" write
by * readLet us break down the different aspects of the LDIF file.
dn: olcDatabase={1}monitor,cn=config
changetype: modify
replace: olcAccess
olcAccess: {0}to *
by dn.base="gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth" read
by dn.base="cn=Manager,dc=cluster,dc=lan" read
by * noneThis secures the monitor database so that only trusted users (local root or LDAP admin) can read it. Protects sensitive runtime information from unauthorised users. In the above In OpenLDAP, a database (different from a SQL database) is a storage backend for LDAP entries. Each backend can have its own configuration, root DN, access controls, and data.
dn: olcDatabase={2}mdb,cn=config
changetype: modify
replace: olcSuffix
olcSuffix: dc=cluster,dc=lanThis sets the LDAP domain for the main database. It defines the LDAP root for the main database and establishes the domain name under which all directory entries (users, groups, organisational units) are stored. Changing this is effectively changing the LDAP domain (cluster.lan).
Main LDAP Database (olcDatabase={2}mdb)
├─ Suffix / LDAP Domain: dc=cluster,dc=lan
├─ Root DN: cn=Manager,dc=cluster,dc=lan
├─ Purpose: Store actual directory data (users, groups, OUs)
├─ Access: Controlled by olcAccess rules
├─ Contains:
│ ├─ Admin user:
│ │ └─ cn=Manager,dc=cluster,dc=lan
│ ├─ Users:
│ │ ├─ uid=user1,dc=cluster,dc=lan
│ │ └─ uid=user2,dc=cluster,dc=lan
│ ├─ Groups:
│ │ ├─ cn=admins,dc=cluster,dc=lan
│ │ └─ cn=users,dc=cluster,dc=lan
│ └─ Organizational Units:
│ ├─ ou=People,dc=cluster,dc=lan
│ └─ ou=Groups,dc=cluster,dc=lan
dn: olcDatabase={2}mdb,cn=config
changetype: modify
replace: olcRootDN
olcRootDN: cn=Manager,dc=cluster,dc=lanThis modifies another existing database ({2}mdb) in LDAP, and it changes the admin account for that database. The root user (administrator) for that database is now cn=Manager,dc=cluster,dc=lan.
In an OpenLDAP server, the {2}mdb and {1}monitor databases serve distinctly different purposes. The {2}mdb database is the primary directory backend, storing all real LDAP entries such as users, groups, and organizational units under the domain defined by its suffix (e.g., `dc=cluster,dc=lan`). It has a defined root DN (`cn=Manager`) with full administrative privileges and supports read and write operations controlled by access control rules. In contrast, the {1}monitor database is a special read-only system database that provides internal monitoring information about the LDAP server, such as active connections, operations per second, and cache statistics.
Access to {1}monitor is strictly limited to the local root user or the LDAP admin for security purposes, and it does not contain or manage actual directory entries. While {2}mdb is essential for the functioning of the directory and user management, {1}monitor exists solely for server monitoring and operational insight.
dn: olcDatabase={2}mdb,cn=config
changetype: modify
add: olcAccess
olcAccess: {0}to attrs=userPassword,shadowLastChange
by dn="cn=Manager,dc=cluster,dc=lan" write
by anonymous auth
by self write
by * none
olcAccess: {1}to dn.base="" by * read
olcAccess: {2}to *
by dn="cn=Manager,dc=cluster,dc=lan" write
by * readThis snippet defines access control rules (ACLs) for the main LDAP database ({2}mdb) to control who can read or write entries and attributes.
Main LDAP Database (olcDatabase={2}mdb)
├─ Sensitive Attributes: userPassword, shadowLastChange
│ ├─ Admin (cn=Manager) → write
│ ├─ Self (the user owning the entry) → write
│ ├─ Anonymous → auth only
│ └─ Everyone else → none
│
├─ Root of Database: dn.base=""
│ └─ Everyone → read
│
├─ All Entries (*)
│ ├─ Admin (cn=Manager) → write
│ └─ Everyone else → read
In summary, the above configuration sets the LDAP domain to cluster.lan, defines the admin user, sets the databases, and establishes access control rules. Now apply the configuration using the following commands:
sudo ldapmodify -Y EXTERNAL -H ldapi:/// -f setdomain.ldifVerify the naming contexts to ensure the domain is set correctly:
sudo ldapsearch -H ldap:// -x -s base -b "" -LLL "namingContexts"The next step is to add organizational units (OUs) to the LDAP directory. For this, create a file named addou.ldif with the following content:
dn: dc=cluster,dc=lan
objectClass: top
objectClass: dcObject
objectClass: organization
o: Cluster Organisation
dc: cluster
dn: cn=Manager,dc=cluster,dc=lan
objectClass: organizationalRole
cn: Manager
description: OpenLDAP Manager
dn: ou=People,dc=cluster,dc=lan
objectClass: organizationalUnit
ou: People
dn: ou=Group,dc=cluster,dc=lan
objectClass: organizationalUnit
ou: GroupLet us break down the ldif file:
dn: dc=cluster,dc=lan
objectClass: top
objectClass: dcObject
objectClass: organization
o: Cluster Organisation
dc: clusterThis entry creates the root of your LDAP directory tree for the domain cluster.lan, serving as the parent for all other entries such as users, groups, and organisational units, while also providing organisational information for the directory.
dn: cn=Manager,dc=cluster,dc=lan
objectClass: organizationalRole
cn: Manager
description: OpenLDAP ManagerThis entry creates the Manager role in LDAP, which acts as the administrative user (Root DN) for the database. It is used to perform all privileged operations, such as adding or modifying users, groups, and organisational units.
dn: ou=People,dc=cluster,dc=lan
objectClass: organizationalUnit
ou: People
dn: ou=Group,dc=cluster,dc=lan
objectClass: organizationalUnit
ou: GroupThese entries create two organisational units under the LDAP root:
ou=People: container for user accounts.
ou=Group: container for group entries.
Using OUs keeps the LDAP directory structured and manageable, allowing hierarchical organisation of users and groups.
LDAP Directory Tree
└─ dc=cluster,dc=lan (Root Entry)
├─ ou=People,dc=cluster,dc=lan → Organizational Unit for users
│ ├─ uid=user1,ou=People,dc=cluster,dc=lan
│ └─ uid=user2,ou=People,dc=cluster,dc=lan
│
└─ ou=Group,dc=cluster,dc=lan → Organizational Unit for groups
├─ cn=admins,ou=Group,dc=cluster,dc=lan
└─ cn=users,ou=Group,dc=cluster,dc=lan
Apply the changes using the following command:
sudo ldapadd -x -D cn=Manager,dc=cluster,dc=lan -W -f addou.ldifFinally we add a user calles testuser1 to the LDAP directory. First, generate a password hash for the user using slappasswd.
slappasswdIn this setup, we use the password testuser. Let's assume the hash generated is {SSHA}yJcv+xLWUvgAWu+fdNN/K6V4cdS4PC5E. Then create a file named user1.ldif with the following content:
dn: uid=testuser1,ou=People,dc=cluster,dc=lan
objectClass: inetOrgPerson
objectClass: posixAccount
objectClass: shadowAccount
cn: testuser1
sn: user
userPassword: {SSHA}yJcv+xLWUvgAWu+fdNN/K6V4cdS4PC5E
loginShell: /bin/bash
uidNumber: 2001
gidNumber: 2001
homeDirectory: /scratch/userhome/testuser1
shadowLastChange: 0
shadowMax: 0
shadowWarning: 0
dn: cn=testuser1,ou=Group,dc=cluster,dc=lan
objectClass: posixGroup
cn: testuser1
gidNumber: 2001
memberUid: testuser1This LDIF file creates the user testuser1 belongs to the group testuser1 (gidNumber=2001). This setup is typical for LDAP-based UNIX/Linux accounts, where each user has a private group. Add the user using the following command:
sudo ldapadd -x -D cn=Manager,dc=cluster,dc=lan -W -f user1.ldifVerify that the user has been added successfully:
sudo ldapsearch -x -b "ou=People,dc=cluster,dc=lan"Next we will enable TLS for secure LDAP communication. First, generate a self-signed TLS
certificate:
sudo openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout /etc/pki/tls/ldapserver.key -out /etc/pki/tls/ldapserver.crt
sudo chown ldap:ldap /etc/pki/tls/{ldapserver.crt,ldapserver.key}Then create a file named tls.ldif with the following content:
dn: cn=config
changetype: modify
replace: olcTLSCACertificateFile
olcTLSCACertificateFile: /etc/pki/tls/ldapserver.crt
-
replace: olcTLSCertificateFile
olcTLSCertificateFile: /etc/pki/tls/ldapserver.crt
-
replace: olcTLSCertificateKeyFile
olcTLSCertificateKeyFile: /etc/pki/tls/ldapserver.keyThe ldif file specifies the paths to the TLS certificate and key files. Next apply the TLS
configuration using the command:
sudo ldapadd -Y EXTERNAL -H ldapi:/// -f tls.ldifThen make sure the /etc/openldap/ldap.conf file is configured to use TLS:
TLS_CACERT /etc/pki/tls/cert.pem
TLS_REQCERT neverLDAP Client Configuration
Now that the LDAP server is set up and running , we can setup the LDAP client. Ideally, an HPC system should have a file system to manage user home directories. In our case, we will host all the user home directories under the /scratch file system. In the /scratch directory, create a directory userhome to be used as the base home
directory for LDAP users:
sudo mkdir -p /scratch/userhome
sudo chown root:root /scratch/userhome
sudo chmod 755 /scratch/userhomeOn the client nodes, install and configure the LDAP client:
sudo dnf install openldap-clients sssd sssd-ldap oddjob-mkhomedir -y
sudo authselect select sssd with-mkhomedir --forceEnable and start the oddjobd service to support home directory creation:
sudo systemctl enable --now oddjobd.service
sudo systemctl status oddjobd.serviceThen configure the LDAP client by editing the /etc/openldap/ldap.conf file:
URI ldap://node1/
BASE dc=cluster,dc=lanAfter this, configure SSSD by editing the /etc/sssd/sssd.conf file:
[domain/default]
id_provider = ldap
autofs_provider = ldap
auth_provider = ldap
chpass_provider = ldap
ldap_uri = ldap://node1/
ldap_search_base = dc=cluster,dc=lan
ldap_id_use_start_tls = True
ldap_tls_cacertdir = /etc/openldap/certs
cache_credentials = True
ldap_tls_reqcert = allow
[sssd]
services = nss, pam, autofs
domains = default
nss]
homedir_substring = /scratch/userhome/%uOnce the configuration is done, set the appropriate permissions for the /etc/sssd/sssd.conf file and start the service:
sudo chmod 0600 /etc/sssd/sssd.conf
sudo systemctl start sssd
sudo systemctl enable sssd
sudo systemctl status sssd
sudo sss_cache -EThen verify that LDAP user created on the LDAP serever (node1) can be resolved from the LDAP client (node2):
getent passwd testuser1Then try to log in to the client node using the LDAP user:
su - testuser1If SELinux is not disabled, it can interfere with LDAP authentication. Especially the home directory creation. Now, you should be able to log in using the LDAP user credentials. Try logging in via SSH (from the local system):
ssh testuser1@<ip of the login node>The next part outlines the steps to set up a Prometheus and Grafana in the AWS cluster. The main GitHub repo is available here.

Comments