How to configure OpenLDAP with passthrough SASL authentication using Kerberos¶
Before you begin¶
It is assumed you are starting with a working OpenLDAP server, with a hostname of ldap-server.example.com
. If not, follow this guide Install and configure OpenLDAP to set it up. It is also assumed that the EXAMPLE.COM
realm is set up, and the Kerberos client tools (krb5-user) are installed on the ldap server. You will need to create an ubuntu principal. See How to install a Kerberos server. You should also know how to create service principals. See How to configure Kerberos service principals.
All the following configuration will be on ldap-server.example.com
.
Note: This process is not the same as using Generic Security Services Application Programming Interface (GSSAPI) to log into the LDAP server. Rather it is using simple authentication with the OpenLDAP server so this should be over a Transport Layer Security (TLS) connection. The test user we will be using is
ubuntu@EXAMPLE.COM
which must exist in the Kerberos database
How the passthrough authentication will work¶
Here is a diagram showing how all the different pieces work together:
We will go over all these details next.
Package installation¶
Install saslauthd
on the OpenLDAP server (ldap-server.example.com
in this document):
sudo apt install sasl2-bin
Check the hostname¶
Get the hostname from the server
hostname -f
Which should give you the hostname of:
ldap-server.example.com
Also check the hostname and domain using a reverse lookup with your IP. For example, if the IP address is 10.10.17.91
:
nslookup 10.10.17.91
The reply should look like this:
91.17.10.10.in-addr.arpa name = ldap-server.example.com.
If the result is the same as your host’s canonical name them all is well. If the domain is missing, the Fully Qualified Domain Name (FQDN) can be entered in the /etc/hosts
file.
sudo vi /etc/hosts
Add the FQDN before the short hostname. Using the same IP as in the previous example, we would have:
10.10.17.91 ldap-server.example.com ldap-server
Create the saslauthd principal¶
The saslauthd
daemon needs a Kerberos service principal in order to authenticate itself to the Kerberos server. Such principals are created with a random password, and the resulting key is stored in /etc/krb5.keytab
. For more information about Kerberos service principals, please consult How to configure Kerberos service principals.
The simplest way to create this principal, and extract the key safely, is to run the kadmin
tool remotely, instead of on the Kerberos server. Since the key needs to be written to /etc/krb5.keytab
, the tool needs to be run with root privileges. Additionally, since creating a new service principal, as well as extracting its key, are privileged operations, we need an /admin
instance of a principal in order to be allowed these actions. In this example, we will use ubuntu/admin
:
sudo kadmin -p ubuntu/admin
An interactive session will look like below. Note the two commands we are issuing at the kadmin:
prompt: addprinc
and ktadd
:
Authenticating as principal ubuntu/admin with password.
Password for ubuntu/[email protected]
kadmin: addprinc -randkey host/ldap-server.example.com
No policy specified for host/[email protected]; defaulting to no policy
Principal "host/[email protected]" created.
kadmin: ktadd host/ldap-server.example.com
Entry for principal host/ldap-server.example.com with kvno 2, encryption type aes256-cts-hmac-sha1-96 added to keytab FILE:/etc/krb5.keytab.
Entry for principal host/ldap-server.example.com with kvno 2, encryption type aes128-cts-hmac-sha1-96 added to keytab FILE:/etc/krb5.keytab.
Alternatively, we can issue the commands directly:
kadmin -p ubuntu/admin -q "addprinc -randkey host/ldap-server.example.com"
NOTE
sudo
is not needed to remotely create a new principal.
And:
sudo kadmin -p ubuntu/admin -q "ktadd host/ldap-server.example.com"
To check that the service principal was added to /etc/krb5.keytab
, run this command:
sudo klist -k
You should see the following:
Keytab name: FILE:/etc/krb5.keytab
KVNO Principal
---- --------------------------------------------------------------------------
2 host/[email protected]
2 host/[email protected]
Configure saslauthd¶
We now need to configure saslauthd
such that it uses Kerberos authentication. This is an option that is selected at startup time, via command-line options. The configuration file for such options is /etc/default/saslauthd
. Only one change is needed in this file: update MECHANISMS
to kerberos5
:
sudo vi /etc/default/saslauthd
Make the following change:
...
# Which authentication mechanisms should saslauthd use? (default: pam)
#
# Available options in this Debian package:
# getpwent -- use the getpwent() library function
# kerberos5 -- use Kerberos 5
# pam -- use PAM
# rimap -- use a remote IMAP server
# shadow -- use the local shadow password file
# sasldb -- use the local sasldb database file
# ldap -- use LDAP (configuration is in /etc/saslauthd.conf)
#
# Only one option may be used at a time. See the saslauthd man page
# for more information.
#
# Example: MECHANISMS="pam"
MECHANISMS="kerberos5"
...
IMPORTANT:
For Ubuntu version 22.04 and earlier “
START=yes
” must also be added to the default config file forsaslauthd
to start.
Save and exit the editor.
Enable and start saslauthd¶
Continue by enabling and starting the saslauthd service.
sudo systemctl enable --now saslauthd
Test saslauthd configuration¶
The saslauthd
service can be tested with with the testsaslauthd
command. For example, with the correct Kerberos password for the ubuntu
principal:
testsaslauthd -u ubuntu -p ubuntusecret
0: OK "Success."
And with the wrong Kerberos password:
testsaslauthd -u ubuntu -p ubuntusecretwrong
0: NO "authentication failed"
NOTE:
In Ubuntu 22.04 LTS and earlier, the
/run/saslauthd
directory is restricted to members of thesasl
group, so thetestsaslauthd
commands above need to be run as root (viasudo
) or as a user who is in thesasl
group.
Configure OpenLDAP¶
In order for OpenLDAP to perform passthrough authentication using saslauthd
, we need to create the configuration file /etc/ldap/sasl2/slapd.conf
with the following content:
pwcheck_method: saslauthd
This will direct OpenLDAP to use saslauthd
as the password checking mechanism when performing passthrough authentication on behalf of a user.
In Ubuntu 22.04 LTS and earlier, the openldap
system user needs to be added to the sasl
group, or else it will not have permission to contact the saslauthd
unix socket in /run/saslauthd/
. To make this change, run:
sudo gpasswd -a openldap sasl
Finally, restart the OpenLDAP service:
sudo systemctl restart slapd.service
Change the userPassword
attribute¶
What triggers OpenLDAP to perform a passthrough authentication when processing a simple bind authentication request, is the special content of the userPassword
attribute. Normally, that attribute contains some form of password hash, which is used to authenticate the request. If, however, what it contains is in the format of {SASL}username@realm
, then OpenLDAP will delegate the authentication to the SASL library, whose configuration is in that file we just created above.
For example, let’s examine the directory entry below:
dn: uid=ubuntu,dc=example,dc=com
uid: ubuntu
objectClass: account
objectClass: simpleSecurityObject
userPassword: {SSHA}S+WlmGneLDFeCwErKnY4mJngnVJMZAM5
If a simple bind is performed using a binddn of uid=ubuntu,dc=example,dc=com
, the password will be checked against the hashed userPassword
value as normal. That is, no passthrough authentication will be done at all.
However, if the userPassword
attribute is in this format:
userPassword: {SASL}[email protected]
That will trigger the passthrough authentication, because the userPassword
attribute starts with the special prefix {SASL}
. This will direct OpenLDAP to use saslauthd
for the authentication, and use the name provided in the userPassword
attribute.
IMPORTANT
Note how the username present in the
userPassword
attribute is independent of the binddn used in the simple bind! If theuserPassword
attribute contained, say,{SASL}anotheruser@EXAMPLE.COM
, OpenLDAP would asksaslauthd
to authenticateanotheruser@EXAMPLE.COM
, and not the user from the binddn! Therefore, it’s important to use OpenLDAP ACLs to prevent users from changing theuserPassword
attribute when using passthrough authentication!
To continue with this how-to, let’s create the uid=ubuntu
entry in the directory, which will use passthrough authentication:
ldapadd -x -D cn=admin,dc=example,dc=com -W <<LDIF
dn: uid=ubuntu,dc=example,dc=com
uid: ubuntu
objectClass: account
objectClass: simpleSecurityObject
userPassword: {SASL}[email protected]
LDIF
NOTE
Note how we don’t need to add the posix attributes like user id, home directory, group, etc. All we really need is a directory entry that contains a
userPassword
attribute.
Test the authentication¶
To test that the simple bind is working, and using the Kerberos password for the ubuntu
user, let’s use ldapwhoami
:
ldapwhoami -D uid=ubuntu,dc=example,dc=com -W -x
Enter LDAP Password:
A successful bind will look like
dn:uid=ubuntu,dc=example,dc=com
A failed bind will look like
ldap_bind: Invalid credentials (49)
These LDAP bind DNs can now be used with external applications that only support “simple” username and password authentication, and they will be authenticated against Kerberos behind the scenes.
Troubleshooting¶
Saslauthd can be run in debug mode for more verbose messages to aid in troubleshooting
sudo systemctl stop saslauthd
sudo /usr/sbin/saslauthd -a kerberos5 -d -m /var/run/saslauthd -n 1
Also the /var/log/auth.log
file can be checked for saslauthd log entries
Advanced options¶
Saslauthd can be configured in the /etc/saslauthd.conf
file. The settings depend on the authorization mechanism configured in /etc/default/saslauthd
, which in this case is kerberos5
.
Some options are:
krb5_keytab
: Override the default keytab file location of/etc/krb5.keytab
.krb5_verify_principal
: Change the name of the Kerberos service principal used bysaslauthd
.
For example, with this content in /etc/saslauthd.conf
:
krb5_keytab: /etc/saslauthd.keytab
krb5_verify_principal: saslauthd
We have changed the keytab file to /etc/saslauthd.keytab
, and the service principal that saslauthd
will use to authenticate itself with the Kerberos server becomes saslauthd/ldap-server.example.com@EXAMPLE.COM
(following this how-to). Note how the domain and realm names remain the same in this service principal, and only the actual principal name is affected (changed from the default value of host
to saslauthd
).