SSSD and OpenLDAP
Learn how to seamlessly integrate the System Security Services Daemon (SSSD) with OpenLDAP to enhance authentication and access control processes within your network environment.
Table of Contents
Updated by S. McNelis Date: 06-12-2024
This guide describes how to set up SSSD (System Security Services Daemon) and an OpenLDAP server to manage user authentication on various machines when user data is stored on a remote OpenLDAP server. SSSD builds on various services like PAM, NSS, and SSH to provide a centralized authentication solution.
Installation Overview
- Install SSSD if it's not already present
- Configure SSSD
- Configure the LDAP server
SSSD
SSSD is a system daemon that "provides access to identity and authentication remote resources through a common framework that can provide caching and offline support to the system." It offers the following features:
- Offline authentication: Allows login even when the machine can't connect to the remote LDAP server.
- Server load reduction: Opens a single connection to the LDAP server.
- Multiple domain support: Supports more than one remote source of identity.
SSSD acts as a single point of configuration, simplifying the management of authentication systems.
How It Works
SSSD manages access to remote data and caches it locally. Existing services that applications use will send their requests to SSSD instead of querying the remote database directly.
Installation
CentOS/Fedora
sudo yum install sssd
For more recent RHEL-based systems:
sudo dnf install sssd
Debian/Ubuntu
sudo apt-get install sssd libpam-sss libnss-sss
Basic Commands
Daemon Management
Managing the SSSD service involves restarting it after configuration changes. Commands for different distributions:
Fedora/RHEL/CentOS:
sudo service sssd [stop|start|restart|status|reload|force-reload|condrestart|try-restart]
Debian/Ubuntu
sudo /etc/init.d/sssd [stop|start|restart|status|reload|force-reload|condrestart|try-restart]
Configuration Testing and Backup
Testing Configuration
sudo authconfig --test
Example output:
caching is disabled
nss_files is always enabled
nss_compat is disabled
...
Creating a Configuration Backup
sudo authconfig --savebackup /tmp/sssd.save
Restoring a Backup
sudo authconfig --restorebackup /tmp/sssd.save
To revert the last change:
sudo authconfig --restorelastbackup
Applying Configuration Changes
sudo authconfig --update
Configuring SSSD
ldap.conf
This file has to be configured separately, as we are using the one we have installed. It is located in /opt/symas/etc/openldap/.
Here is typical content, where we are listing two LDAP servers (if one is not reachable, the other one will be used).
# LDAP Defaults
#
# See ldap.conf(5) for details
# This file should be world readable but not world writable.
#SIZELIMIT 12
#TIMELIMIT 15
#DEREF never
# The CA certificate that was used to sign the server certificates
TLS_CACERT /opt/symas/ssl/cacert.pem
# The URI of the two LDAP servers we will connect to. Note that there is
# no LDAPS URI, startTLS is mandatory.
URI ldap://brie.rb.symas.net/, ldap://cantal.rb.symas.net/
# The base root for the users and groups entries.
BASE dc=symas,dc=com
The data we are interested in are stored in the dc=symas,dc=com branch (typically, groups are stored in ou=groups,dc=symas,dc=com and users in ou=people,dc=symas,dc=com)
The remote server CA certificate is also stored in the /opt/symas directory.
sssd.conf
This is the main configuration file. It's located in /etc/sssd/. It covers all the services that needed to be configured separately before SSSD was created: NSS, PAM, SSH, SUDO in our case.
Its structure is quite simple:
[sssd]
<parameters>
[<service>]*
<service parameters>
[<domain type>/<domain name>]*
<domain parameters>
We may have many services and many domains.
We will now cover all the sections one by one.
[sssd] Section
This contains global parameters for SSSD. This is where you list the services and domains that will be used.
Here is an example:
#---------------------------------------------
# The SSSD configuration
#---------------------------------------------
[sssd]
config_file_version = 2
# Trace Fatal(0x0010), Critical(0x0020), Serious(0x0040), Minor(0x0080), Config(0x0100) and Operation(0x0400) messages
# Can also be a number between 0 and 9
# check /var/log/sssd/sssd.log
debug_level=0x17F0
# the supported services
services = nss, pam, sudo,ssh
# The associated domains (only one here)
domains = rb.symas.net
Here, we have defined one single domain, which name is rb.symas.net, and 4 services. We will then have 5 more sections present in the configuration file.
The debug level can either be a number between 1 and 9, or a combinaison of flags (each flag represents a single bit in a 2 bytes integer, they are combined by OR-ing them). Here are the different possible values:
- 0x0001: Unused
- 0x0002: Unused
- 0x0004: Unused
- 0x0008: Unused
- 0x0010 / 0: Fatal failures. Anything that would prevent SSSD from starting up or causes it to cease running.
- 0x0020 / 1: Critical failures. An error that doesn't kill the SSSD, but one that indicates that at least one major feature is not going to work properly.
- 0x0040 / 2: Serious failures. An error announcing that a particular request or operation has failed.
- 0x0080 / 3: Minor failures. These are the errors that would percolate down to cause the operation failure of 2.
- 0x0100 / 4: Configuration settings.
- 0x0200 / 5: Function data.
- 0x0400 / 6: Trace messages for operation functions.
- 0x0800: Unused
- 0x1000 / 7: Trace messages for internal control functions.
- 0x2000 / 8: Contents of function-internal variables that may be interesting.
- 0x4000 / 9: Extremely low-level tracing information.
- 0x8000: Unused
In this list, the (deprecated) integer number from 0 to 9 is cumulative, i.e., 7 is equivalent to 0x0010 + 0x0020 + 0x0040 + 0x0080 + 0x0100 + 0x0200 + 0x0400 + 0x1000, which is 0x17F0.
[nss] Section
This is the part where you configure the Name Service Switch service. This service basically provides sources for configuration and name resolution mechanisms. It lists how a database should fetch what it needs from a given source or mechanism, like:
passwd: files ldap
that tells the password system to find the requested data from either a file or LDAP. The configuration is stored in the /etc/nsswitch.conf file. With SSSD, you won't have to modify this file, it will be handled automatically.
Here is the suggested configuration for this section:
#---------------------------------------------
# NSS service configuration
#
# Don't lookup for root on the LDAP server
#---------------------------------------------
[nss]
# Trace Fatal(0x0010), Critical(0x0020), Serious(0x0040), Minor(0x0080), Config(0x0100) and Operation(0x0400) messages
# check /var/log/sssd/sssd_nss.log
debug_level=0x17F0
# Try three times when the remote LDAP server is not reachable
reconnection_retries = 3
# Don't get the root group from LDAP
filter_groups = root
# Don't get the root user from LDAP
filter_users = root
# The default Home dir
homedir_substring = /home
# The home dir to use if there is none configured in LDAP
fallback_homedir = /home/%u
# The default shell to use if none is configured in LDAP or does not exist
shell_fallback = /bin/bash
Here, we have configured a few things, beside the log level. The most important part is to exclude the root user from any LDAP request (as we should always be able to log as root on the machine even if we can't connect to the remote LDAP server).
Otherwise, we tell the system to set the home directory of new users to be stored in /home with their user ID as the name of the directory fallback_homedir = /home/%u
and defined its default shell (note that those definitions are not strictly necessary, they are provided for clarity).
There are a few more parameters that are can be used, but the default values already fit most of the use cases.
[pam] Section
The Pluggable Authentication Module configuration is done here. PAM is meant to decouple authentication from the application, by delegating it to third party modules. An application will just have to use the PAM API, and the PAM configuration will route the request to the best authentication service.
Here is what we set:
#---------------------------------------------
# PAM service configuration
#---------------------------------------------
[pam]
# Trace Fatal(0x0010), Critical(0x0020), Serious(0x0040), Minor(0x0080), Config(0x0100) and Operation(0x0400) messages
# check /var/log/sssd/sssd_pam.log
debug_level=0x17F0
# Try three times when the remote LDAP server is not reachable
reconnection_retries = 3
# The verbosity level (the higher, the more messages will be printed on the user console)
# 0: none
# (1): important messages
# 2: informational messages
# 3: all messages and debug informations
pam_verbosity = 1
Nothing special here. It's important to understand that most of the configuration takes place in the [domain] section.
[sudo] and [ssh] Sections
We have grouped those two sections, as their configuration are the same:
#---------------------------------------------
# SUDO service configuration
#---------------------------------------------
[sudo]
# Trace Fatal(0x0010), Critical(0x0020), Serious(0x0040), Minor(0x0080), Config(0x0100) and Operation(0x0400) messages
# check /var/log/sssd/sssd_sudo.log
debug_level=0x17F0
# Try three times when the remote LDAP server is not reachable
reconnection_retries = 3
Note that the SSH section will be named [ssh], but will contain the same parameters with the same values.
[domain/xxx] Section
This is the most important section in the sssd.conf file. It's where we tell teh SSSD daemon how informations are retrieved from the remote LDAP server. Actually, all the other sections depend on this section, which makes it way simpler to configure, as we don't have to duplicate the informations in many configuration files ( nsswitch.conf, system-auth-ac, password-auth-ac, ...).
The first important thing to remember is that the domain section has a name, which is the one we have put in the [sssd] section. In our example, this is rb.symas.net. Here is the proposed configuration:
#---------------------------------------------
# The SYMAS domain
#---------------------------------------------
[domain/rb.symas.net]
# Trace Fatal(0x0010), Critical(0x0020), Serious(0x0040), Minor(0x0080), Config(0x0100) and Operation(0x0400) messages
# check /var/log/sssd/sssd_<domain name>.log
debug_level=0x17F0
# Try three times when the remote LDAP server is not reachable reconnection_retries = 3
# Allow the system to cache credentials so that a user can always login on the machine even if not being
# able to contact the remote LDAP server
cache_credentials = True
# Define the range of UID we are going to fetch from the LDAP server
min_id = 500
max_id =100000
# Provider mapped to ldap
id_provider = ldap
access_provider = ldap
auth_provider = ldap
chpass_provider = ldap
autofs_provider = ldap
sudo_provider = ldap
# LDAP informations
ldap_uri = ldap://brie.rb.symas.net, ldap://cantal.rb.symas.net
ldap_search_base = dc=symas,dc=com
ldap_access_filter = (objectClass=posixAccount)
ldap_user_search_base = ou=People,dc=symas,dc=com?subtree?(objectclass=posixaccount)
ldap_group_search_base = ou=Groups,dc=symas,dc=com?subtree?(objectclass=posixGroup)
ldap_sudo_search_base = ou=People,dc=symas,dc=com
# Expect the schema used in the LDAP server to be RFC2307Bis
ldap_schema = rfc2307bis
# LDAP attributeType mapping
ldap_user_uid_number = uidNumber
ldap_user_gid_number = gidnumber
ldap_user_gecos = sn
ldap_user_home_directory = homeDirectory
ldap_user_shell = loginShell
ldap_user_ssh_public_key = sshPublicKey
ldap_user_fullname = cn
ldap_user_member_of = memberUid
ldap_group_object_class = posixGroup
ldap_group_name = cn
ldap_group_gid_number = gidNumber
ldap_group_member = member
# TLS configuration
ldap_tls_reqcert = demand
ldap_tls_cacert = /opt/symas/ssl/cacert.pem
ldap_id_use_start_tls = True
Lots of things here... Let's describe all the parameters
- cache_credentials: Tells the system to keep a tack of the (hashed) credentials, so that a user can login even if the remote LDAP is not reachable. The cache can be configured in the [pam] section, if needed (especially the expiration date)
- min_id, max_id: Defines the range for UID and GID that are allowed
- id_provider, xxx_provider: Defines the provider in charge of managing identification and other operations. Here, it's clearly LDAP
- ldap_uri: The URI for all the LDAP servers in charge of providing the requested operations. We may have many, to cover teh case of an unreachable server
- ldap_xxx_search_base: The position in the LDAP server DIT where SSSD will look for informations. Here we look for two places, with a SUBTREE search and we filter the returned entries using a specific OvjectClass (respectively posixAccount and posixGroup)
- ldap_schema: Defines the schema to use on the LDAP schema for LDAP attribute we will get back
- ldap_user_xxx/ldap_group_yyy: The definition of attribute mapping. It associates a SSSD attribute with the equivalent LDAP attribute. Here, we just explicitely listed many of them, assuming most are already defaulting to the same value, this was done for clarity purposes
- ldap_access_filter: This parameter is mandatory as we have set the access_provider to use LDAP. Basically we set it to only accept entries that have the posixAccount ObjectClass (there are other possible options)
- ldap_id_use_start_tls: Inform SSSD to use startTLS to communicate in a secured fashion with the LDAP server
- ldap_tls_cacer: The file that contains the remote LDAP server CA certificate
- ldap_tls_reqcert: Requires the server certificate to be asked and checked
That's pretty much it. This is a working configuration for the servers that we have set, so for any other setup, some of those parameters might have to be modified (this is expected for the remote LDAP servers URIs for instance)
Home Directory Automatic Creation
One more thing is necessary if you want the home directory for unkown users to be created when they login on the client machine the very first time. Sadly, this is a change you have to make in the PAM configuration. Here is the command that change the configuration accordingly to this requirement:
mkhomedir
# sudo authconfig --enablemkhomedir --update
That will change the required configuration file and restart the oddjobd daemon automatically.
Configuring the Remote LDAP Server
Now that we have described the client configuration, we have to configure the remote LDAP server and the entries that will be injected in it.
LDAP Server Configuration
There is not so much things we need to change on the server. As we have made the SSH service depending on the LDAP content, we need to extend the server so that it allows entries to store the public key. There is no default Attribute or ObjectClass that cover this aspect (the nisKeyObject ObjectClass is certainly not the right one to use: it forces you to store both the public and private key for each user. A typical security breach !)
We will define an auxiliary ObjectClass and an AttributeType for this purpose, and store them into the /opt/symas/etc/openldap/schema/openssh.schema file.
Openssh schema
#
# LDAP Public Key Patch schema for use with openssh-ldappubkey
# Author: Eric AUGE <eau@phear.org>
#
# Based on the proposal of: Mark Ruijter
#
# octetString SYNTAX
attributetype ( 1.3.6.1.4.1.24552.500.1.1.1.13 NAME 'sshPublicKey'
DESC 'MANDATORY: OpenSSH Public key'
EQUALITY octetStringMatch
SYNTAX 1.3.6.1.4.1.1466.115.121.1.40 )
# printableString SYNTAX yes|no
objectclass ( 1.3.6.1.4.1.24552.500.1.1.2.0 NAME 'ldapPublicKey' SUP top AUXILIARY
DESC 'MANDATORY: OpenSSH LPK objectclass'
MUST ( sshPublicKey $ uid )
)
Now, we must tell the server to use this schema. This is done by adding a reference to this schema in the slapd.conf file.
schema list
#-----------------------------------------------------------------------
# SCHEMA INCLUDES
# Use only those you need and leave the rest commented out.
include /opt/symas/etc/openldap/schema/core.schema
include /opt/symas/etc/openldap/schema/ppolicy.schema
include /opt/symas/etc/openldap/schema/cosine.schema
include /opt/symas/etc/openldap/schema/inetorgperson.schema
include /opt/symas/etc/openldap/schema/krb5-kdc.schema
include /opt/symas/etc/openldap/schema/rfc2307bis.schema
include /opt/symas/etc/openldap/schema/openssh.schema
See the last line.
The server need to be restarted after this change.
Modifying the Entries
Now we need to inject the user's public key in each user's entry in the server. Each entry has to be modified so that the ldapPublicKey ObjectClass is added and the sshPublicKey attribute is added. Here is an example:
dn: uid=elecharny,ou=People,dc=symas,dc=com
objectClass: ldapPublicKey
objectClass: inetOrgPerson
objectClass: posixAccount
objectClass: top
objectClass: shadowAccount
cn: Emmanuel Lecharny
gidNumber: 2023
homeDirectory: /home/elecharny
sn: TMOpY2hhcm55
sshPublicKey: c3NoLWRzcyBBQUFBQjNOemFDMWtjM01BQUFDQkFNVWlRVTBvM1ZsUWRkTDArd kxpS0ZVMFI1V3ZaVEc3OExyYk9pZytMbGt6RjBHS0ZHTTZsczE1eE51NkZxQzBvNHBERklwWk1Q K3VXRjA0WTMycXZmS2hCMWdFT0hPV3I3VE9yazZGbVJPOEoyb2NqaFQrMDdwcFRKSWVLS3N6Nkt QS0xwWlVZMkdnTDF4U2hha2w4ZXdzVlNRZmh1TDUrWG1HM0RuVmc2Rm5BQUFBRlFEWDduN2o1Qj JndGg3QVh0QTI3a3NvRUs4K05RQUFBSUVBdWpDVS9oREZ2RmpYNW13MnJ2K0owcHJuMDFOS3pyV StrZVYvWFZES1pPL3pyRWUwExamplemWFN0d21aTFNZcFV5R3h4cVNSd1VlUnAvRWE5STYxNHdr SjFEUnJ5ZlBmZWg3czkxUlAwMFN3a2JaOS92NE8xLzBGUVpIZ29XY1hGa1V5RDFCOE1xSENVVEh yYUwybWkyQkhHRTExSStTU2JQc2gwYm9sdTNzQUFBQ0FjRzN1VWdkNVg2bWZqdCtId1hPaFF3Qj dmSGVRR2p5VWlrM09ZcU1GS1Avc25COVpIWlFrcktEQ2k5WjVUTDFtekRhTjc4c2Q4U3FvdGFjW lgrWVJzdDE5ZzRkd3hLL3NMSitjMDc1YTA5YmNSeU1RVm52Yk5raXRxaXlSUGVlOXNOci9XNnFz dDVSREVlZ2o3ZmZFdWpBWjRpdHVYTWJ5Qy81SW4yNjBmeWM9IGVsZWNoYXJueUBlbGVjaGFybnk tbGFwdG9wCg==
uid: elecharny
uidNumber: 2023
givenName: Emmanuel
loginShell: /bin/bash
mail: elecharny@symas.com
ou: Symas
userPassword: xxxxxxx
publicKey
The sshPublicKey contain the text form of the public key. Above, it's shown in Base64 format, but actually, the stored value is:
ssh-dss AAAAB3NzaC1kc3MAAACBAMUiQU0o3VlQddL0+vLiKFU0R5WvZTG78LrbOig+LlkzF0GKFGM6ls15xNu6FqC0o4pDFIpZMP+uWF04Y32qvfKhB1gEOHOWr7TOrk6FmRO8J2ocjhT+07ppTJIeKKsz6KPKLpZUY2GgL1xShakl8ewsVSQfhuL5+XmG3DnVg6FnAAAAFQDX7n7j5B2gth7AXtA27ksoEK8+NQAAAIEAujCU/hDFvFjX5mw2rv+J0prn01NKzrU+keV/XVDKZO/zrEe0DPYHFfXStwmZLSYpUyGxxqSRwUeRp/Ea9I614wkJ1DRryfPfeh7s91RP00SwkbZ9/v4O1/0FQZHgoWcXFkUyExampleCUTHraL2mi2BHGE11I+SSbPsh0bolu3sAAACAcG3uUgd5X6mfjt+HwXOhQwB7fHeQGjyUik3OYqMFKP/snB9ZHZQkrKDCi9Z5TL1mzDaN78sd8SqotacZX+YRst19g4dwxK/sLJ+c075a09bcRyMQVnvbNkitqiyRPee9sNr/W6qst5RDEegj7ffEujAZ4ituXMbyC/5In260fyc= elecharny@elecharny-laptop