- Requirements
- Notes
- Utility
- Installation
- Configuration
- Password Policies
- PhpLdapAdmin (PLA) - optional
- Debian 11 (Buster) or Ubuntu 20.04 (Local Fossa) or Debian 12 (Bookworm)
This HOWTO uses example.org
to provide this guide with example values.
Please remember to replace all occurencences of the example.org
domain name with the domain name of your institution.
- Simple Bash script useful to convert a Domain Name into a Distinguished Name of LDAP: domain2dn.sh
-
System Update:
sudo apt update ; sudo apt upgrade
-
Automate SLAPD installation (Change all "_CHANGEME" values):
-
sudo apt install debconf-utils
-
sudo vim /root/debconf-slapd.conf
slapd slapd/password1 password <LDAP-ROOT-PW_CHANGEME> slapd slapd/password2 password <LDAP-ROOT-PW_CHANGEME> slapd slapd/move_old_database boolean true slapd slapd/domain string <INSTITUTE-DOMAIN_CHANGEME> slapd shared/organization string <ORGANIZATION-NAME_CHANGEME> slapd slapd/no_configuration boolean false slapd slapd/purge_database boolean false slapd slapd/allow_ldap_v2 boolean false slapd slapd/backend select MDB
-
sudo cat /root/debconf-slapd.conf | sudo debconf-set-selections
NOTES: The HOWTO considers the following values:
<LDAP-ROOT-PW_CHANGEME>
==>ciaoldap
<INSTITUTE-DOMAIN_CHANGEME>
==>example.org
<ORGANIZATION-NAME_CHANGEME>
==>Example Org
-
-
Install required package:
sudo apt install slapd ldap-utils ldapscripts rsyslog
-
Check
/etc/hosts
to be sure to have the correct FQDN for OpenLDAP server -
Create Certificate/Key (This HOWTO will use Self Signed Certificate for LDAP):
-
Self Signed (4096 bit - 3 years before expiration):
-
sudo openssl req -newkey rsa:4096 -x509 -nodes -out /etc/ldap/$(hostname -f).crt -keyout /etc/ldap/$(hostname -f).key -days 1095 -subj "/CN=$(hostname -f)"
sudo chown openldap:openldap /etc/ldap/$(hostname -f).crt
sudo chown openldap:openldap /etc/ldap/$(hostname -f).key
sudo chown openldap:openldap /etc/ldap/$(hostname -f).crt /etc/ldap/$(hostname -f).key
-
-
Signed (Do not use if you are not a NREN GARR Member):
-
Add CA Cert into
/etc/ssl/certs
-
If you use GARR TCS or GEANT TCS:
sudo wget -O /etc/ssl/certs/GEANT_OV_RSA_CA_4.pem https://crt.sh/?d=2475254782 sudo wget -O /etc/ssl/certs/SectigoRSAOrganizationValidationSecureServerCA.crt https://crt.sh/?d=924467857 sudo cat /etc/ssl/certs/SectigoRSAOrganizationValidationSecureServerCA.crt >> /etc/ssl/certs/GEANT_OV_RSA_CA_4.pem sudo rm /etc/ssl/certs/SectigoRSAOrganizationValidationSecureServerCA.crt
-
If you use ACME (Let's Encrypt):
sudo ln -s /etc/letsencrypt/live/<SERVER_FQDN>/chain.pem /etc/ssl/certs/ACME-CA.pem
-
-
Generate CSR(Certificate Signing Request) and the KEY:
-
sudo openssl req -new -newkey rsa:4096 -nodes -out /etc/ssl/certs/$(hostname -f).csr -keyout /etc/ssl/private/$(hostname -f).key -subj "/C=IT/ST=/L=Rome/O=Consortium GARR/CN=$(hostname -f)"
sudo cp /etc/ssl/certs/$(hostname -f).crt /etc/ldap/$(hostname -f).crt
sudo cp /etc/ssl/private/$(hostname -f).key /etc/ldap/$(hostname -f).key
sudo chown openldap:openldap /etc/ldap/$(hostname -f).crt /etc/ldap/$(hostname -f).key
-
-
-
-
Enable SSL for LDAP:
-
sudo sed -i "s/TLS_CACERT.*/TLS_CACERT\t\/etc\/ldap\/$(hostname -f).crt/g" /etc/ldap/ldap.conf
sudo chown openldap:openldap /etc/ldap/ldap.conf
On Debian 12 - Bookworm:
-
sudo echo -e "TLS_CACERT\t/etc/ldap/$(hostname -f).crt" >> /etc/ldap/ldap.conf
sudo chown openldap:openldap /etc/ldap/ldap.conf
-
-
Restart OpenLDAP:
sudo service slapd restart
-
Create
scratch
directory:sudo mkdir /etc/ldap/scratch
-
Configure LDAP for SSL:
sudo bash -c 'cat > /etc/ldap/scratch/olcTLS.ldif <<EOF dn: cn=config changetype: modify replace: olcTLSCACertificateFile olcTLSCACertificateFile: /etc/ldap/$(hostname -f).crt - replace: olcTLSCertificateFile olcTLSCertificateFile: /etc/ldap/$(hostname -f).crt - replace: olcTLSCertificateKeyFile olcTLSCertificateKeyFile: /etc/ldap/$(hostname -f).key EOF'
-
Apply with:
sudo ldapmodify -Y EXTERNAL -H ldapi:/// -f /etc/ldap/scratch/olcTLS.ldif
-
Create the 3 main Organizational Unit (OU),
people
,groups
andsystem
.Example: if the domain name is
example.org
than the distinguish name will bedc=example,dc=org
:Be carefull! Replace
dc=example,dc=org
with distinguish name (DN) of your domain name and<LDAP-ROOT-PW_CHANGEME>
with the LDAP ROOT password!-
sudo bash -c 'cat > /etc/ldap/scratch/add_ou.ldif <<EOF dn: ou=people,dc=example,dc=org objectClass: organizationalUnit objectClass: top ou: people dn: ou=groups,dc=example,dc=org objectClass: organizationalUnit objectClass: top ou: groups dn: ou=system,dc=example,dc=org objectClass: organizationalUnit objectClass: top ou: system EOF'
-
Apply with:
sudo ldapadd -x -D 'cn=admin,dc=example,dc=org' -w '<LDAP-ROOT-PW_CHANGEME>' -H ldapi:/// -f /etc/ldap/scratch/add_ou.ldif
-
Verify with:
sudo ldapsearch -x -b 'dc=example,dc=org'
-
-
Create the
idpuser
needed to perform "Bind and Search" operations:Be carefull! Replace
dc=example,dc=org
with distinguish name (DN) of your domain name,<LDAP-ROOT-PW_CHANGEME>
with the LDAP ROOT password and<INSERT-HERE-IDPUSER-PW>
with password for theidpuser
user!-
sudo bash -c 'cat > /etc/ldap/scratch/add_idpuser.ldif <<EOF dn: cn=idpuser,ou=system,dc=example,dc=org objectClass: inetOrgPerson cn: idpuser sn: idpuser givenName: idpuser userPassword: <INSERT-HERE-IDPUSER-PW> EOF'
-
Apply with:
sudo ldapadd -x -D 'cn=admin,dc=example,dc=org' -w '<LDAP-ROOT-PW_CHANGEME>' -H ldapi:/// -f /etc/ldap/scratch/add_idpuser.ldif
-
-
Configure OpenLDAP ACL to allow
idpuser
to perform search operation on the directory:Be carefull! Replace
dc=example,dc=org
with distinguish name (DN) of your domain name!-
Check which configuration your directory has with:
sudo ldapsearch -Y EXTERNAL -H ldapi:/// -b cn=config 'olcDatabase={1}mdb'
-
Configure ACL for
idpuser
with:sudo bash -c 'cat > /etc/ldap/scratch/olcAcl.ldif <<EOF dn: olcDatabase={1}mdb,cn=config changeType: modify replace: olcAccess olcAccess: {0}to * by dn.exact=gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth manage by * break olcAccess: {1}to attrs=userPassword by self write by anonymous auth by dn="cn=admin,dc=example,dc=org" write by * none olcAccess: {2}to dn.base="" by anonymous auth by * read olcAccess: {3}to dn.base="cn=Subschema" by * read olcAccess: {4}to * by dn.exact="cn=idpuser,ou=system,dc=example,dc=org" read by anonymous auth by self read EOF'
-
Apply with:
sudo ldapadd -Y EXTERNAL -H ldapi:/// -f /etc/ldap/scratch/olcAcl.ldif
-
-
Check that
idpuser
can search other users (when users exist):Be carefull! Replace
dc=example,dc=org
with distinguish name (DN) of your domain name!sudo ldapsearch -x -D 'cn=idpuser,ou=system,dc=example,dc=org' -w '<INSERT-HERE-IDPUSER-PW>' -b 'ou=people,dc=example,dc=org'
-
Install needed schemas (eduPerson, SCHAC, Password Policy):
sudo wget https://raw.githubusercontent.com/REFEDS/eduperson/master/schema/openldap/eduperson.ldif -O /etc/ldap/schema/eduperson.ldif sudo wget https://raw.githubusercontent.com/REFEDS/SCHAC/main/schema/openldap.ldif -O /etc/ldap/schema/schac.ldif sudo ldapadd -Y EXTERNAL -H ldapi:/// -f /etc/ldap/schema/eduperson.ldif sudo ldapadd -Y EXTERNAL -H ldapi:/// -f /etc/ldap/schema/schac.ldif sudo ldapadd -Y EXTERNAL -H ldapi:/// -f /etc/ldap/schema/ppolicy.ldif (for Ubuntu 22.04 LTS and Debian 12 it does not exist! See below)
and verify presence of the new
schac
,eduPerson
andppolicy
schemas:sudo ldapsearch -Q -LLL -Y EXTERNAL -H ldapi:/// -b 'cn=schema,cn=config' dn
For Ubuntu >= 22.04 or Debian 12 follow Password Policies
-
Add MemberOf Configuration:
-
Create
add_memberof.ldif
:sudo bash -c 'cat > /etc/ldap/scratch/add_memberof.ldif <<EOF dn: cn=module,cn=config cn: module 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'
-
Add it to the Directory:
sudo ldapadd -Q -Y EXTERNAL -H ldapi:/// -f /etc/ldap/scratch/add_memberof.ldif
-
-
Improve performance:
-
Create
olcDbIndex.ldif
:sudo bash -c 'cat > /etc/ldap/scratch/olcDbIndex.ldif <<EOF dn: olcDatabase={1}mdb,cn=config changetype: modify replace: olcDbIndex olcDbIndex: objectClass eq olcDbIndex: member eq olcDbIndex: cn pres,eq,sub olcDbIndex: ou pres,eq,sub olcDbIndex: uid pres,eq olcDbIndex: entryUUID eq olcDbIndex: sn pres,eq,sub olcDbIndex: mail pres,eq,sub EOF'
-
Add it to the Directory:
sudo ldapmodify -Y EXTERNAL -H ldapi:/// -f /etc/ldap/scratch/olcDbIndex.ldif
-
-
Configure Logging:
sudo mkdir /var/log/slapd sudo chown syslog /var/log/slapd sudo bash -c 'cat > /etc/rsyslog.d/99-slapd.conf <<EOF local4.* /var/log/slapd/slapd.log EOF' sudo bash -c 'cat > /etc/ldap/scratch/olcLogLevelStats.ldif <<EOF dn: cn=config changeType: modify replace: olcLogLevel olcLogLevel: stats EOF' sudo ldapmodify -Y EXTERNAL -H ldapi:/// -f /etc/ldap/scratch/olcLogLevelStats.ldif sudo service rsyslog restart sudo service slapd restart
-
Configure openLDAP olcSizeLimit:
sudo bash -c 'cat > /etc/ldap/scratch/olcSizeLimit.ldif <<EOF dn: cn=config changetype: modify replace: olcSizeLimit olcSizeLimit: unlimited dn: olcDatabase={-1}frontend,cn=config changetype: modify replace: olcSizeLimit olcSizeLimit: unlimited EOF' sudo ldapmodify -Y EXTERNAL -H ldapi:/// -f /etc/ldap/scratch/olcSizeLimit.ldif
-
Add your first user:
Be carefull! Replace
dc=example,dc=org
with distinguish name (DN) of your domain name!- Configure
user1.ldif
:sudo bash -c 'cat > /etc/ldap/scratch/user1.ldif <<EOF # USERNAME: user1 , PASSWORD: ciaouser1 # Generate a new password with: sudo slappasswd -s <newPassword> dn: uid=user1,ou=people,dc=example,dc=org changetype: add objectClass: inetOrgPerson objectClass: eduPerson uid: user1 sn: User1 givenName: Test cn: Test User1 displayName: Test User1 preferredLanguage: it userPassword: {SSHA}u5tYgO6iVerMuuMJBsYnPHM+70ammhnj mail: [email protected] eduPersonAffiliation: student eduPersonAffiliation: staff eduPersonAffiliation: member eduPersonEntitlement: urn:mace:dir:entitlement:common-lib-terms eduPersonEntitlement: urn:mace:terena.org:tcs:personal-user EOF'
- Configure
- Apply with:
sudo ldapadd -Y EXTERNAL -H ldapi:/// -f /etc/ldap/scratch/user1.ldif
-
Check that
idpuser
can finduser1
:Be carefull! Replace
dc=example,dc=org
with distinguish name (DN) of your domain name!sudo ldapsearch -x -D 'cn=idpuser,ou=system,dc=example,dc=org' -w '<INSERT-HERE-IDPUSER-PW>' -b 'uid=user1,ou=people,dc=example,dc=org'
-
Check that LDAP has TLS ('anonymous' MUST BE returned):
sudo ldapwhoami -H ldap:// -x -ZZ
-
Make mail, eduPersonPrincipalName and schacPersonalUniqueID as unique:
-
Load
unique
module:sudo bash -c 'cat > /etc/ldap/scratch/loadUniqueModule.ldif <<EOF dn: cn=module{0},cn=config changetype: modify add: olcModuleLoad olcModuleload: unique EOF' sudo ldapmodify -Y EXTERNAL -H ldapi:/// -f /etc/ldap/scratch/loadUniqueModule.ldif
-
Configure mail, eduPersonPrincipalName and schacPersonalUniqueID as unique:
sudo bash -c 'cat > /etc/ldap/scratch/mail_ePPN_sPUI_unique.ldif <<EOF dn: olcOverlay=unique,olcDatabase={1}mdb,cn=config objectClass: olcOverlayConfig objectClass: olcUniqueConfig olcOverlay: unique olcUniqueAttribute: mail olcUniqueAttribute: schacPersonalUniqueID olcUniqueAttribute: eduPersonPrincipalName EOF' sudo ldapadd -Y EXTERNAL -H ldapi:/// -f /etc/ldap/scratch/mail_ePPN_sPUI_unique.ldif
-
-
Disable Anonymous bind
sudo bash -c 'cat > /etc/ldap/scratch/disableAnonymoysBind.ldif <<EOF dn: cn=config changetype: modify add: olcDisallows olcDisallows: bind_anon dn: olcDatabase={-1}frontend,cn=config changetype: modify add: olcRequires olcRequires: authc EOF' sudo ldapmodify -Y EXTERNAL -H ldapi:/// -f /etc/ldap/scratch/disableAnonymoysBind.ldif
-
Load Password Policy module:
sudo bash -c 'cat > /etc/ldap/scratch/load-ppolicy-mod.ldif <<EOF dn: cn=module{0},cn=config changetype: modify add: olcModuleLoad olcModuleLoad: ppolicy.la EOF' sudo ldapadd -Y EXTERNAL -H ldapi:/// -f load-ppolicy-mod.ldif
-
Create Password Policies OU Container:
Be carefull! Replace
dc=example,dc=org
with distinguish name (DN) of your domain name!sudo bash -c 'cat > /etc/ldap/scratch/policies-ou.ldif <<EOF dn: ou=policies,dc=example,dc=org objectClass: organizationalUnit objectClass: top ou: policies EOF'
-
Create OpenLDAP Password Policy Overlay DN:
Be carefull! Replace
dc=example,dc=org
with distinguish name (DN) of your domain name!sudo bash -c 'cat > /etc/ldap/scratch/ppolicy-overlay.ldif <<EOF dn: olcOverlay=ppolicy,olcDatabase={1}mdb,cn=config objectClass: olcOverlayConfig objectClass: olcPPolicyConfig olcOverlay: ppolicy olcPPolicyDefault: cn=default,ou=policies,dc=example,dc=org olcPPolicyHashCleartext: TRUE EOF'
-
Install requirements:
sudo apt install apache2-utils python3-passlib gettext php php-ldap php-xml
-
Download and extract PLA into the Apache2 DocumentRoot directory:
sudo su cd /var/www/html/ wget https://github.com/leenooks/phpLDAPadmin/archive/refs/tags/1.2.6.6.tar.gz -O phpldapadmin.tar.gz tar -xzf phpldapadmin.tar.gz mv phpLDAPadmin-1.2.6.6 pla
-
Create PLA configuration file:
cd /var/www/html/pla/config sudo cp config.php.example config.php
-
Enable LDAP Apache module:
sudo a2enmod ldap
-
Restart Apache2:
sudo systemctl restart apache2
-
Login on PLA:
- Navigate to
http://<YOUR-LDAP-FQDN>/pla
- Login with:
- Username:
cn=admin,dc=example,dc=org
- Password:
<LDAP-ROOT-PW_CHANGEME>
- Username:
- Navigate to
- Edit
/var/www/html/pla/config/config.php
to configure PhpLdapAdmin.