LDAP in a nutshell

You configure a database /?/ of users /that you add manually/ and tell other services, like peertube /or the linux login system even/, to look for the individuals in the ldap directories. This way an admin does not make an accound for 500 different users in 500 different servers. The user is made in ldap, and then some to-be-integrated server, like Mastodon for example, is told to get the users email, password, phone number etc from LDAP.

Why did we re-set-up our ldap.

Because our dear sysadmin /not telling names/ set it up on quick hand, and overlooked the transport layer security /TLS/ and plus our users didnt happen to have emails and phone numbers. So in order to not doubt our ldap when integrating new things with it - we decided to set up a new normies ldap.

The main points were: - ldap shall have TLS - info such as email, phone numbers, names, etc

We also wanted to use PostgreSQL as the database but turns out that’s not how LDAP works. So we use MDB /memory mapped database/ instead.

Components

  • Server: OpenLDAP 2.6 /slapd daemon/
  • Database: MDB
  • Directory base: abi.am or dc=abi,dc=am
  • Security: LDAPS /for tls/
  • Certificate: Self-signed tls
The structure / given by ldapsearch -x -b "dc=abi,dc=am" -LLL dn
 
  dc=abi,dc=am
   |-> cn=admin
   |-> ou=admins,dc=abi,dc=am
      |-> cn=antranigv,ou=admins,dc=abi,dc=am
   |-> ou=people,dc=abi,dc=am

Install OpenLDAP and enable on boot

pkg install openldap26-server openldap26-client
 
sysrc slapd_enable="YES"
sysrc slapd_flags="-f /usr/local/etc/openldap/slapd.conf -h ldap://0.0.0.0/"

Generate TLS certificates /the 1/3 of our todo list/

mkdir -p /usr/local/etc/openldap/tls
cd /usr/local/etc/openldap/tls
 
# generate the key 
openssl genrsa -out ldap-server.key 2048
 
# generate the csr /using that key/
# csr = certificate signing request
openssl req -new -key ldap-server.key -out ldap-server.csr \
  -subj "/C=AM/ST=Yerevan/L=Yerevan/O=abi.am/CN=ldap.abi.am"
 
# generate certificate /using that csr, and the key/
openssl x509 -req -days 365 -in ldap-server.csr \
  -signkey ldap-server.key -out ldap-server.crt
 
# permissions: ldap can read-write, others can read
chmod 600 ldap-server.key
chmod 644 ldap-server.crt
chown ldap:ldap ldap-server.crt

Create the database directory

mkdir -p /var/db/openldap-data # this is the file that you should not delete
chown -R ldap:ldap /var/db/openldap-data
chmod 700 /var/db/openldap-data

Configuring

We have 3 main config files we work with. - slapd.conf /usr/local/etc/openldap/slapd.conf for configuring the slapd daemon /server/. This file contains database settings, TLS config, schemas, monitoring, ACLs, admin password hash generated with slappasswd

  • base-setup.ldif /root/base-setup.ldif for initializing+configuring the base structure of an LDAP directory. This file contains Base DN, organizational units /people, admins, root password hash generated with slappasswd
  • ldap.conf /usr/local/etc/openldap/ldap.conf for client configuration /settings for client tools like ldapsearch, ldapadd, ldapmodify/. This file contains default server URI, base DN, TLS settings for clients

to see or modify them just run

vim /usr/local/etc/openldap/slapd.conf
vim /root/base-setup.ldif
vim /usr/local/etc/openldap/ldap.conf
# slapd.conf
    
    include     /usr/local/etc/openldap/schema/core.schema
    include     /usr/local/etc/openldap/schema/cosine.schema
    include     /usr/local/etc/openldap/schema/inetorgperson.schema
    
    pidfile     /var/run/openldap/slapd.pid
    argsfile    /var/run/openldap/slapd.args

    # Load dynamic backend modules:
    modulepath  /usr/local/libexec/openldap
    moduleload  back_mdb

    TLSCertificateFile  /usr/local/etc/openldap/tls/ldap-server.crt
    TLSCertificateKeyFile   /usr/local/etc/openldap/tls/ldap-server.key
    TLSCACertificateFile    /usr/local/etc/openldap/tls/ldap-server.crt

    # Database Configuration

    database    mdb
    suffix      "dc=abi,dc=am"
    rootdn      "cn=admin,dc=abi,dc=am"
    rootpw      {SSHA}WyDJGCVQmRbl57aiwOj4pSgSkkdAW64s

    directory   /var/db/openldap-data

    index   objectClass eq
    index   cn,sn,uid,mail eq,sub

    access to attrs=userPassword
        by self write
        by anonymous auth
        by * none

    access to *
        by self write
        by users read
        by * read

    database monitor
    access to *
        by dn.exact="cn=admin,dc=abi,dc=am"
        by * read
base-setup.ldif
    
    # Domain

    dn: dc=abi,dc=am
    objectClass: top
    objectClass: dcObject
    objectClass: organization
    o: abi.am
    dc: abi


    # Organizational unit ADMINS /and their interns/

    dn: ou=admins,dc=abi,dc=am
    objectClass: organizationalUnit
    ou: admins


    # Organizational unit PEOPLE

    dn: ou=people,dc=abi,dc=am
    objectClass: organizationalUnit
    ou: people


    # Antranig /the real admin/

    dn: cn=antranigv,ou=admins,dc=abi,dc=am
    objectClass: inetOrgPerson
    cn: Antranig
    sn: sysadmin
    mail: antranigv@abi.am
    userPassword: {SSHA}HGlAJt+rfJCK74xz9q+r/RdQh7cWmTel
    
  # import the base structure
  ldapadd -x -D "cn=admin,dc=abi,dc=am" -W -f /root/base-setup.ldif

  # to test, show all directory entries
  ldapsearch -x -b "dc=abi,dc=am" -LLL
  
  # or entries + hashed passwords
  ldapsearch -x -D "cn=admin,dc=abi,dc=am" -W -b "dc=abi,dc=am" -LLL
  
  # or authenticate
  ldapwhoami -x -D "cn=admin,dc=abi,dc=am" -W
  # TLS test: same auth but with encryption /-ZZ/
  ldapwhoami -x -D "cn=admin,dc=abi,dc=am" -W -ZZ

And finally start the ldap server.

service slapd start
 
# Check if its running
 
ps aux | grep slapd
sockstat -l | greo 389

Common actions

Adding a new user

make a file for the new user eg ani.ldif (preferrably in /root/ldap/users/)

Example of a user :

dn: uid=ani,ou=Users,dc=abi,dc=am
objectClass: account
objectClass: posixAccount
objectClass: ldapPublicKey
sn: Hakobyan
mail: ani.hakobyan@abi.am
uidNumber: 10037
gidNumber: 10037
homeDirectory: /mnt/home/ani
loginShell: /bin/bash
gecos: ani
description: User account
sshPublicKey: ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIMzmm9juul7a215P+2glagSKgU82TX3K8RtpcTM941Ad ani@DESKTOP-OG1R1UQ
userPassword:: e1NTSEF9SjN6cERNckttZTJwSS9jQXk1UDNpOTF0bG5QSlVPa20=
uid: ani
cn: Ani

and import the user like this

ldapadd -x -H ldaps://ldap.local.abi.am:636 -D "cn=admin,dc=abi,dc=am" -y /usr/local/etc/openldap/passwd -f /root/ldap-migrations/users/ani.ldif

modify user email

make a modify-email.ldif with the following content

dn: uid=ani,ou=Users,dc=abi,dc=am
changetype: modify
replace: mail
mail: ani@abi.am

apply changes with

ldapmodify -x -D "cn=admin,dc=abi,dc=am" -W -f modify-email.ldif

then you can search for the user by email

ldapsearch -x -b "ou=Users,dc=abi,dc=am" "(mail=newmail@abi.am)" cn mail

change password for someone, for example Antranig

ldappasswd -x -D "cn=admin,dc=abi,dc=am" -W -S "uid=antranigv,ou=admins,dc=abi,dc=am"

backup database

/usr/local/sbin/slapcat > /root/ldap-backup-$(date +%Y%m%d).ldif

Add many

for file in organizational_units/*.ldif; do
    echo "Adding OU: $file"
    ldapadd -y pass \
            -D "cn=admin,dc=abi,dc=am" \
            -f "$file"
done
 
for file in groups/*.ldif; do
    echo "Adding group: $file"
    ldapadd -y pass \
            -D "cn=admin,dc=abi,dc=am" \
            -f "$file"
done
 
for file in users/*.ldif; do
    echo "Adding user: $file"
    ldapadd -y pass \
            -D "cn=admin,dc=abi,dc=am" \
            -f "$file"
done

in /root/ldap/

we have
base.ldif
/projects
the projects have members and owners.
member comes from posixGroup,
ownser comes from… posixGroup again. not groupOfNames. We hardcoded “owner” into posixGroup in /usr/local/etc/openldap/schema/nis.schema /or core.schema, i dont rememember/
/users
users have objectclass sshPublicKey which comes from a custion schema sshPublicKey. Also the field “email” has been hardcoded into some objectclass that our users use so we can have email: testuhi@testmail.xyz
/organizationalUnits
/groups