Setting up OpenLDAP & SSSD w/Sudo on Ubuntu 22.04

The reason for creating this guide is I found so many different how-to's on the net that date back over a decade with varying methods of getting OpenLDAP installed, but none got me directly to my final goal of allowing sudo rights to LDAP users. I decided to gather up what I've learned and compile it into one guide for you and my aging brain.

Please keep in mind that even though this guide is one of my longest ever, it's just a primer to get you started and by no means the end all be all for OpenLDAP implementations.

Synopsis

Set Hostname

We'll first assign the Fully Qualified Domain Name (FQDN) as the hostname of the server

sudo hostnamectl set-hostname ldap.domain.com

Then we'll edit our hosts file to include the FQDN

sudo nano /etc/hosts

Add the server's FQDN to the localhost entry 127.0.1.1 entry. We're adding it to a localhost address instead of the server's assigned IP so we can restrict non-encrypted LDAP connections.

127.0.0.1 localhost
127.0.1.1 ldap ldap.domain.com

*NOTE: If you have a DNS server setup in your environment, add a record for this OpenLDAP server to its assigned static IP.

Install OpenLDAP

Installing OpenLDAP is pretty straightforward. The one thing to remember is that Slapd is the name of the OpenLDAP service.

sudo apt install slapd ldap-utils

While we need to create and confirm a new OpenLDAP Admin Password, don't sweat remembering it as we'll be replacing it immediately in the next step.

Create & Confirm LDAP Password
Create & Confirm LDAP Password

Configure OpenLDAP

Run the Slapd configurator which includes resetting the OpenLDAP password in the previous setp. Remember to substitute your environment values for the domain and organization names.

sudo dpkg-reconfigure slapd

Slapd Configuration

Omit OpenLDAP server configuration: No
DNS domain name: domain.com
Organization name: Org name
Administrator Password: New password (Can reuse same password from previous step)
Do you want the database to be removed when slapd is purged: No
Move old database: Yes

Next we'll edit the ldap.conf file

sudo nano /etc/ldap/ldap.conf

Add the following lines below the commented BASE & URI lines

#BASE   dc=example,dc=com
#URI    ldap://ldap.example.com ldap://ldap-provider.example.com:666
BASE    dc=domain,dc=com
URI     ldap://ldap.domain.com

*NOTE: For the rest of this guide, whenever you see dc=domain,dc=com make sure to change it match the domain name in your environment, i.e. tester.org would be dc=tester,dc=org

Now we'll test if OpenLDAP is working correctly

ldapsearch -x

You should see result: 0 Success if OpenLDAP is working. The 0 means there is no errors.

Setup LDAPS with SSL/TLS

Next we're going to secure OpenLDAP by implementing the LDAPS protocol which uses SSL/TLS to encrypt any traffic between the server and its clients. While technically this is not needed for OpenLDAP to work, it is highly encouraged.

*NOTE: You may find info on the net that shows a much quicker way to generate self-signed certs for OpenLDAP, but in my experience, SSSD, which we'll be installing later in this guide, will fail to start due to TLS verification errors. While this is a longer method, it comes with a lot less headaches.

Start by installing the following SSL packages

sudo apt install gnutls-bin ssl-cert

Then generate the OpenLDAP Certificate Authority (CA) key

sudo certtool --generate-privkey --bits 4096 --outfile /etc/ssl/private/ldap_ca_key.pem

Now we'll create a template for the OpenLDAP CA

sudo nano /etc/ssl/ldap_ca.info

Change the Org Name and set the expiration_days to how long you'd like the CA cert to be valid

cn = Org Name
ca
cert_signing_key
expiration_days = 3650

With the template created, we'll now generate the OpenLDAP CA self-signed cert

sudo certtool --generate-self-signed \
--load-privkey /etc/ssl/private/ldap_ca_key.pem \
--template /etc/ssl/ldap_ca.info \
--outfile /usr/local/share/ca-certificates/ldap_ca_cert.crt

The following command will add your cert to the server's Trusted CA as well as create a symlink to the cert in /etc/ssl/certs

sudo update-ca-certificates

We now need to generate a private key which will be used to decrypt communications with the OpenLDAP clients.

sudo certtool --generate-privkey --bits 2048 \
--outfile /etc/ldap/sasl2/ldap_slapd_key.pem

Like with the CA, we'll create a template for our OpenLDAP cert

sudo nano /etc/ssl/ldap.info

Change the Org Name and expiration_days. This should be less than or equal to the CA cert's expiration_days. In addition, you need to set the cn to the FQDN of the OpenLDAP server.

organization = Org Name
cn = ldap.domain.com
tls_www_server
encryption_key
signing_key
expiration_days = 3650

With the template created, we'll generate the OpenLDAP self-signed cert which will be copied to any device that authenticates to our OpenLDAP server.

sudo certtool --generate-certificate \
--load-privkey /etc/ldap/sasl2/ldap_slapd_key.pem \
--load-ca-certificate /etc/ssl/certs/ldap_ca_cert.pem \
--load-ca-privkey /etc/ssl/private/ldap_ca_key.pem \
--template /etc/ssl/ldap.info \
--outfile /etc/ldap/sasl2/ldap_slapd_cert.pem

Now change permissions on the newly generated OpenLDAP cert

sudo chown openldap. -R /etc/ldap/sasl2
sudo chmod 0640 /etc/ldap/sasl2/ldap_slapd_key.pem

Lastly, we'll verify our OpenLDAP cert against our CA cert

openssl verify -CAfile /etc/ssl/certs/ldap_ca_cert.pem /etc/ldap/sasl2/ldap_slapd_cert.pem

You should see /etc/ldap/sasl2/ldap_slapd_cert.pem: OK if everything is kosher.

Add Certs to OpenLDAP Config

With our certificates generated, we'll need to add them to our OpenLDAP schema. We need to first create an LDIF file with our intended changes.

sudo nano /etc/ldap/schema/cert.ldif

*NOTE: All OpenLDAP changes are made via .ldif text files. You need to create these files first and then apply them to your existing schema. While a bit of a hassle, it does make reusing the same functions easier.

dn: cn=config
add: olcTLSCACertificateFile
olcTLSCACertificateFile: /etc/ssl/certs/ldap_ca_cert.pem
-
add: olcTLSCertificateFile
olcTLSCertificateFile: /etc/ldap/sasl2/ldap_slapd_cert.pem
-
add: olcTLSCertificateKeyFile
olcTLSCertificateKeyFile: /etc/ldap/sasl2/ldap_slapd_key.pem

We'll now apply the ldif file to our schema. If the command works, you'll see modifying entry "cn=config" and no errors.

sudo ldapmodify -Y EXTERNAL -H ldapi:/// -f /etc/ldap/schema/cert.ldif

Now edit the Slapd default parameters

sudo nano /etc/default/slapd

Find the line that starts with SLAPD_SERVICES and replace it with the following. This will restrict unencrypted LDAP traffic to only localhost and also enable secured LDAPS connections.

SLAPD_SERVICES="ldap://127.0.1.1/ ldapi:/// ldaps:///"

We'll need to restart slapd, the OpenLDAP service, after making these changes

sudo systemctl restart slapd

Now verify LDAPS is working

ldapsearch -x -H ldaps://ldap.domain.com

Like before, if you see result: 0 Success, this means everything is working.

Create OpenLDAP Structure

With all of our OpenLDAP components in place, we'll be creating a basic structure of OU's for our LDAP schema.

sudo nano /etc/ldap/schema/rootOU.ldif

This ldif will create the Users & Groups OU's at the top of our schema and an administrators group which we'll be granting sudo rights later in the guide.

dn: ou=Users,dc=domain,dc=com
objectClass: organizationalUnit
ou: Users

dn: ou=Groups,dc=domain,dc=com
objectClass: organizationalUnit
ou: Groups

dn: cn=administrators,ou=Groups,dc=domain,dc=com
objectClass: posixGroup
cn: administrators
gidNumber: 5000

With the ldif created, we'll add these entries into our LDAP schema. When prompted, enter the OpenLDAP admin password set earlier in the guide.

ldapadd -x -D cn=admin,dc=domain,dc=com -W -f /etc/ldap/schema/rootOU.ldif

*TIP: So far, we've been managing OpenLDAP via the command-line with ldif files. While there are a lot of GUI-based LDAP managers, I've found most of them aren't free or haven't been updated in years. If you are deadset against managing OpenLDAP via the command-line, I would suggest the free version of LDAP Account Manager (LAM) which is a web-frontend for LDAP that can be installed directly on the OpenLDAP server.

Setup LDAP Sudo Access

Setting up LDAP enabled sudo access is not as straightforward as you may expect. The default sudo package Ubuntu uses doesn't include support for LDAP, so we need to replace it with the sudo-ldap version instead.

export SUDO_FORCE_REMOVE=yes
sudo -E bash -c 'apt install sudo-ldap'

*NOTE: This method of installing sudo-ldap is necessary because it replaces sudo, which is a dependency of ubuntu-server-minimal, a pre-installed package of Ubuntu server.

We'll now copy the sudo schema provided by the sudo-ldap package to our ldap schema directory

sudo cp /usr/share/doc/sudo-ldap/schema.olcSudo /etc/ldap/schema/

Then add it to our schema

sudo ldapadd -Y EXTERNAL -H ldapi:/// -f /etc/ldap/schema/schema.olcSudo

Next we'll create an ldif which defines the Sudoers OU and sets the default sudo options for it in our schema

sudo nano /etc/ldap/schema/sudoers.ldif

This ldif will also grant the LDAP group administrators we created earlier sudo rights.

dn: ou=Sudoers,dc=domain,dc=com
objectClass: organizationalUnit
objectClass: top
ou: Sudoers

dn: cn=defaults,ou=Sudoers,dc=domain,dc=com
objectClass: sudoRole
objectClass: top
cn: defaults
sudoOption: env_reset
sudoOption: mail_badpass
sudoOption: secure_path=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/snap/bin

dn: cn=%administrators,ou=Sudoers,dc=domain,dc=com
objectClass: top
objectClass: sudoRole
cn: %administrators
sudoUser: %administrators
sudoHost: ALL
sudoCommand: ALL

*NOTE: You may have noticed the % in front of administrators in our ldif. This indicates that we are specifying an LDAP group and not a user.

Finally add the sudoers.ldif to the schema and enter the OpenLDAP admin password when prompted

ldapadd -x -D cn=admin,dc=domain,dc=com -W -f /etc/ldap/schema/sudoers.ldif

Create OpenLDAP Test User

We'll now create an LDAP test user and grant it sudo rights by adding it to our administrators group.

sudo nano /etc/ldap/schema/addUser.ldif

*TIP: It's important that your schema Group ID's (gidNumber) & User ID's (uidNumber) don't conflict with local gid's and uid's. Most admins start gidNumber's at 5000 and uidNumber's at 10000 to prevent this.

dn: uid=jnobody,ou=Users,dc=domain,dc=com
objectClass: inetOrgPerson
objectClass: posixAccount
objectClass: shadowAccount
uid: john
sn: Nobody
givenName: John
cn: John Nobody
displayName: John Nobody
uidNumber: 10000
gidNumber: 5000
userPassword: {CRYPT}x
gecos: John Nobody
loginShell: /bin/bash
homeDirectory: /home/jnobody

*NOTE: To simplify this guide, I assigned the test user the gidNumber of the OpenLDAP administrators group which automatically makes it a member. It's normally better to assign a different default group to users and add their uid to the administrators group to more easily track group memberships.

Add the addUser.ldif to the schema and enter the OpenLDAP admin password

ldapadd -x -D cn=admin,dc=domain,dc=com -W -f /etc/ldap/schema/addUser.ldif

Next we'll set an LDAP password for our test user.

ldappasswd -x -D cn=admin,dc=domain,dc=com -W -S uid=jnobody,ou=Users,dc=domain,dc=com

Enter and confirm the test user password and then enter the OpenLDAP admin password

Install SSSD

Now we're going to setup SSSD which is a service that authenticates to OpenLDAP. It also has the added ability of caching credentials in the event an OpenLDAP server become unreachable.

*NOTE: If you'd prefer to leave your OpenLDAP server only accessible via local accounts, this section can be skipped. In the next and final section, I'll show you how to setup SSSD on a client PC to authenticate to our OpenLDAP server.

First install SSSD and the accompanying packages

sudo apt install sssd-ldap ldap-utils libsss-sudo

We'll now create the sssd.conf and change the permissions or else SSSD won't start

sudo install -m 600 /dev/null /etc/sssd/sssd.conf

Edit the sssd.conf and add the example config below

sudo nano /etc/sssd/sssd.conf

You'll want to change lines 3, 5, 8 & 10 to match the domain name used in your environment

[sssd]
config_file_version = 2
domains = domain.com

[domain/domain.com]
id_provider = ldap
auth_provider = ldap
ldap_uri = ldaps://ldap.domain.com
cache_credentials = True
ldap_search_base = dc=domain,dc=com

With our SSSD config setup, we'll we'll want to restart the SSSD service

sudo systemctl restart sssd

The following allows the automatic creation of a home directory for an LDAP user that logs into the OpenLDAP server

sudo pam-auth-update --enable mkhomedir

You can now switch to this LDAP user and test sudo rights

su jnobody
sudo ls -la

Connect Client PC to OpenLDAP Server

In this final section, we'll be setting up a client PC to connect to our OpenLDAP server. This allows any LDAP user to login and automatically have sudo rights if they are in the LDAP administrators group.

Setup Host Record for OpenLDAP Server

This section is only needed if you don't have a DNS server with an entry for your OpenLDAP server.

sudo nano /etc/hosts

Below the localhost entries, enter the OpenLDAP server's IP Address and FQDN

192.168.1.2 ldap.domain.com

Import the certificate created earlier on the OpenLDAP server

sudo sh -c "echo -n | openssl s_client -connect ldap.domain.com:636 | sed -ne '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p' > /usr/local/share/ca-certificates/ldap_ca_server.crt"

Now we'll add the cert to the client PC's Trusted CA

sudo update-ca-certificates

Install SSSD and the accompanying packages which will handle authentication to the OpenLDAP server

sudo apt install sssd-ldap ldap-utils libsss-sudo

Create the sssd.conf with proper permissions

sudo install -m 600 /dev/null /etc/sssd/sssd.conf

Edit the sssd.conf and add the example config below

sudo nano /etc/sssd/sssd.conf

Change lines 3, 5, 8 & 10 to match the domain name used in your environment

[sssd]
config_file_version = 2
domains = domain.com

[domain/domain.com]
id_provider = ldap
auth_provider = ldap
ldap_uri = ldaps://ldap.domain.com
cache_credentials = True
ldap_search_base = dc=domain,dc=com

With SSSD setup, restart the SSSD service

sudo systemctl restart sssd

Now test connectivity to the OpenLDAP server. Like the previous tests, seeing result: 0 Success means everything is working.

ldapsearch -x -H ldaps://ldap.domain.com -b "dc=domain,dc=com"

You can setup the automatic creation of home directories for LDAP users on the client PC

sudo pam-auth-update --enable mkhomedir

At long last, you can switch to the test user and verify sudo rights

su jnobody
sudo ls -la

Outro

If you made it to the end of this guide, kudos to you. I know it was a lot to take in, but its a lot easier than trying to weed through 10 different sites to get sudo working with your OpenLDAP environment. This is the service I provide to you for free so make sure to pay it forward and share this guide if you find it helpful.

Please Share Me, I'm Lonely

3 Responses to Setting up OpenLDAP & SSSD w/Sudo on Ubuntu 22.04

  1. Greetings, I’ve been struggling for a long time to setup an openLDAP and this guide made it a breeze to configure.

    One small issue I’ve encountered during the client setup was that it couldn’t find the LDAP server (-1), I managed to fix it by installing the libldap-common package that somehow wasn’t installed as a dependency with the other packages.

    On another note, can you point to me some directions on how to get PAM modules working with this setup? I’m trying to limit access with pam_time but it got me lost once again…

  2. Greetings, one of the best OpenLDAP deployment manuals out there.

    The only problem I’ve encountered is that on the client, after authorizing an OpenLDAP user, a home directory is created, but the user can’t get into it. The user gets a bash message: /home/jnobody/.bashrc: Permission denied. Authorization takes place, but the user remains in the current user’s directory.

    • Avatar Postmin (Admin)
      Postmin (Admin) says:

      It’s hard to say what might be causing that issue, but you should definitely be checking what user/group has ownership over the home directory. You should also try creating another test user and seeing if the ownership problem persists and if the permissions are the same.