Getting Started With Openldap
This LDAP setup uses Ubuntu 20.04 Linux.
To install the needed packages, do the following:
sudo apt -y update
sudo apt install -y slapd ldap-utils #Requires human intervention to enter the OpenLDAP admin password
sudo apt install -y net-tools #For netstat
#sudo apt-get install -y ca-certificates #This was already installed
Next, we generate a self-signed certificate:
openssl genrsa -out ldap_server.key1
openssl pkcs8 -topk8 -in ldap_server.key1 -out ldap_server.key -nocrypt
openssl req -new -key ldap_server.key -out ldap_server.csr -subj "/C=AE/ST=Dubai/O=PocketTheories/OU=IT/CN=$(hostname -f)"
openssl x509 -in ldap_server.csr -out ldap_server.crt -req -signkey ldap_server.key -days 3650
We then put the certificates where they are accessible. The OpenLDAP client libraries get the certificate for verification from the path specified in the config file /etc/ldap/ldap.conf
sudo mv ldap_server.* /etc/ssl/private/
sudo chmod a+rx /etc/ssl/private/
sudo chown -R openldap. /etc/ssl/private/*
sudo sed -i 's/^TLS_CACERT.*$/TLS_CACERT \/etc\/ssl\/private\/ldap_server.crt/' /etc/ldap/ldap.conf
To get other applications to trust the certificate, we add the certificate to the OS repository (this step is different on RHEL):
#sudo openssl x509 -inform der -outform pem -in local-ca.der -out local-ca.crt
sudo cp /etc/ssl/private/ldap_server.crt /usr/local/share/ca-certificates
sudo update-ca-certificates
On RedHat Linux, the certificates are added to the OS certificate authority trust store with:
cp ca.cert /etc/pki/ca-trust/source/anchors/
update-ca-trust force-enable
update-ca-trust extract
We then create the LDIFs for the data to be added into the LDAP server:
echo '
dn: ou=people,dc=ap-south-1,dc=compute,dc=internal
objectClass: organizationalUnit
ou: people
dn: ou=groups,dc=ap-south-1,dc=compute,dc=internal
objectClass: organizationalUnit
ou: groups
' > basedn.ldif
echo '
dn: uid=user1,ou=people,dc=ap-south-1,dc=compute,dc=internal
objectClass: inetOrgPerson
objectClass: posixAccount
objectClass: shadowAccount
cn: user1
sn: Person1
loginShell: /bin/bash
uidNumber: 1001
gidNumber: 1001
homeDirectory: /home/user1' > ldapUser.ldif
echo "userPassword: $(sudo slappasswd -s 1)" >> ldapUser.ldif
#Add multiple gidNumber lines for multiple group memberships
echo 'dn: cn=user1,ou=groups,dc=ap-south-1,dc=compute,dc=internal
objectClass: posixGroup
cn: user1
gidNumber: 1001
memberUid: user1
dn: cn=admins,ou=groups,dc=ap-south-1,dc=compute,dc=internal
objectClass: groupofnames
cn: admins
description: Admin users
member: cn=user1,ou=groups,dc=ap-south-1,dc=compute,dc=internal
' >> ldapUser.ldif
echo '
dn: cn=config
changetype: modify
add: olcTLSCACertificateFile
#replace: olcTLSCACertificateFile
olcTLSCACertificateFile: /etc/ssl/private/ldap_server.crt
-
replace: olcTLSCertificateFile
olcTLSCertificateFile: /etc/ssl/private/ldap_server.crt
-
replace: olcTLSCertificateKeyFile
olcTLSCertificateKeyFile: /etc/ssl/private/ldap_server.key
' > ldap_ssl.ldif
# This LDIF is to prevent anonymous requests to the LDAP Server
echo '
dn: cn=config
changetype: modify
#replace: olcDisallows
#delete: olcDisallows
add: olcDisallows
olcDisallows: bind_anon
dn: cn=config
changetype: modify
add: olcRequires
#replace: olcRequires
#delete: olcRequires
olcRequires: authc
dn: olcDatabase={-1}frontend,cn=config
changetype: modify
add: olcRequires
#replace: olcRequires
#delete: olcRequires
olcRequires: authc
' > disable-anon.ldif
Next, we put the LDIFs into the LDAP server. When using ldapadd, the LDIF contains the record as it needs to be inserted. When using ldapmodify, the LDIF needs the changetype and the add/replace/delete to be specified. To use simple authentication, we use -x with the -D specifying the DN and -w specifying the password; to prompt for the password, use -W instead of -w. In the example below, we use the credentials that were entered when installing OpenLDAP (with “apt install -y slapd”). Instead of simple authentication, we can use external authentication with -Y EXTERNAL.
ldapadd -x -D cn=admin,dc=ap-south-1,dc=compute,dc=internal -w 1 -f basedn.ldif # The -w specifies the password as "1"
# ldapadd -x -D cn=admin,dc=ap-south-1,dc=compute,dc=internal -W -f basedn.ldif # This is to prompt the user for the password
ldapadd -x -D cn=admin,dc=ap-south-1,dc=compute,dc=internal -w 1 -f ldapUser.ldif
sudo ldapadd -Y EXTERNAL -H ldapi:/// -f ldap_ssl.ldif
#sudo ldapmodify -Y EXTERNAL -H ldapi:/// -f disable-anon.ldif # Some systems will not work with this
We can use the self-signed certificate for LDAPS (LDAP over SSL) by editing the SLAPD_SERVICES setting in /etc/default/slapd config file and restarting the service:
# Add ldaps:/// to SLAPD_SERVICES in /etc/default/slapd
sudo vi /etc/default/slapd
sudo /etc/init.d/slapd restart
You can check if the OpenLDAP service is back online with one of the following:
sudo slapcat
ldapwhoami -H ldapi:/// -x -ZZ
netstat -an | grep tcp | grep LISTEN # Should see port 636
At this point, OpenLDAP has pretty much everything that you would need to run Linux authentications. However, some applications need a bit more than the gidNumber-memberUid group membership that OpenLDAP provides by default. To get the memberOf-member attributes (memberOf for the user and member for the groupOfNames), we run the following:
cat <<EOF > memberof_load_configure.ldif
dn: cn=module{1},cn=config
cn: module{1}
objectClass: olcModuleList
olcModuleLoad: memberof
olcModulePath: /usr/lib/ldap
dn: olcOverlay={0}memberof,olcDatabase={1}mdb,cn=config
objectClass: olcConfig
objectClass: olcMemberOf
objectClass: olcOverlayConfig
objectClass: top
olcOverlay: memberof
olcMemberOfDangling: ignore
olcMemberOfRefInt: TRUE
olcMemberOfGroupOC: groupOfNames
olcMemberOfMemberAD: member
olcMemberOfMemberOfAD: memberOf
EOF
cat <<EOF > refint1.ldif
dn: cn=module{1},cn=config
add: olcmoduleload
olcmoduleload: refint
EOF
cat <<EOF > refint2.ldif
dn: olcOverlay={1}refint,olcDatabase={1}mdb,cn=config
objectClass: olcConfig
objectClass: olcOverlayConfig
objectClass: olcRefintConfig
objectClass: top
olcOverlay: {1}refint
olcRefintAttribute: memberof member manager owner
EOF
sudo ldapadd -Q -Y EXTERNAL -H ldapi:/// -f memberof_load_configure.ldif
sudo ldapmodify -Q -Y EXTERNAL -H ldapi:/// -f refint1.ldif
sudo ldapadd -Q -Y EXTERNAL -H ldapi:/// -f refint2.ldif
We can then add the following in an LDIF:
# Put the following into a .ldif file and "ldapadd" it
dn: ou=users,dc=ldap,dc=pockettheories,dc=local
objectClass: organizationalunit
dn: uid=nitin,ou=users,dc=ldap,dc=pockettheories,dc=local
objectClass: inetorgperson
cn: nitin
sn: katkam
dn: ou=groups,dc=ldap,dc=pockettheories,dc=local
objectClass: organizationalunit
dn: cn=admins,ou=groups,dc=ldap,dc=pockettheories,dc=local
objectClass: groupofnames
cn: admins
description: All users
member: uid=nitin,ou=users,dc=ldap,dc=pockettheories,dc=local
dn: cn=users,ou=groups,dc=ldap,dc=pockettheories,dc=local
objectClass: groupofnames
cn: admins
description: All users
member: uid=nitin,ou=users,dc=ldap,dc=pockettheories,dc=local
To query the LDAP server, Apache Directory Studio is a GUI eclipse plugin and slapcat and ldapsearch are popular CLI tools:
ldapsearch -h $(hostname -f) -D 'cn=admin,dc=ap-south-1,dc=compute,dc=internal' -w '1' -b 'base-dn-here' -s base # Search only the base DN
ldapsearch -H ldapi:/// -D 'cn=admin,dc=ap-south-1,dc=compute,dc=internal' -w '1' -b 'base-dn-here' -s one "(uid=user.2004)" # Search one level below the DN
ldapsearch -H ldapi:/// -D 'cn=admin,dc=ap-south-1,dc=compute,dc=internal' -w '1' -b 'DC=pockettheories,DC=com' -s sub "sAMAccountName=katkam" cn name distinguishedName memberOf # Search recursively in lower levels, and return only the fields "cn name distinguishedName memberOf"