--- myst: html_meta: description: Configure OpenLDAP with SASL passthrough authentication using Kerberos for simple bind authentication over TLS connections. --- (ldap-saslauthd-kerberos)= # How to configure OpenLDAP with passthrough SASL authentication using Kerberos ## Before you begin This guide makes several assumptions about the OpenLDAP setup: * Working OpenLDAP server: it is assumed you are starting with a working OpenLDAP server, with a hostname of `ldap-server.example.com`. If not, follow this guide {ref}`Install and configure OpenLDAP` to set it up. * Working Kerberos realm: 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 {ref}`How to install a Kerberos server `. * Working {term}`TLS` setup for OpenLDAP: since simple binds and clear text passwords are involved, the OpenLDAP server must have a working TLS setup, and connections to it must be using TLS. Refer to {ref}`ldap-and-tls` to set it up. * You should also know how to create service principals. See {ref}`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](https://www.openldap.org/doc/admin26/sasl.html#GSSAPI) (GSSAPI) to log into the LDAP server. Rather it is using [simple authentication](https://www.openldap.org/doc/admin26/security.html#%22simple%22%20method) with the OpenLDAP server so this should be over a [Transport Layer Security](https://datatracker.ietf.org/wg/tls/documents/) (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: ![openldap saslauthd detailed diagram](../images/openldap-saslauthd-diagram-detailed.png) The diagram shows the overall picture of how passthrough authentication can be used with OpenLDAP. It also highlights where the password is used in clear text format: * Between the application and OpenLDAP, since it's a simple bind, the connection must be protected via {term}`TLS` (see {ref}`ldap-and-tls`). * Between OpenLDAP and saslauthd, the credentials are passed via a UNIX local socket and protected via normal filesystem permissions. It's still clear text and localhost (the traffic doesn't go over the network), but only the root user, or the user under which saslauthd runs, can read that data. * Between saslauthd and the authentication mechanism that is chosen, it will depend on the mechanism. Here in this documentation, since we are using Kerberos, the traffic is not clear text, so there is nothing else to do. ## Package installation Install `saslauthd` on the OpenLDAP server (`ldap-server.example.com` in this document): ```text sudo apt install sasl2-bin ``` ## Check the hostname Get the hostname from the server: ```text hostname -f ``` Which should give you the hostname of: ```text 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`: ```text nslookup 10.10.17.91 ``` The reply should look like this: ```text 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](https://en.wikipedia.org/wiki/Fully_qualified_domain_name) (FQDN) can be entered in the `/etc/hosts` file. ```text sudo vi /etc/hosts ``` Add the FQDN before the short hostname. Using the same IP as in the previous example, we would have: ```text 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 {ref}`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`: ```text 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`: ```text Authenticating as principal ubuntu/admin with password. Password for ubuntu/admin@EXAMPLE.COM kadmin: addprinc -randkey host/ldap-server.example.com No policy specified for host/ldap-server.example.com@EXAMPLE.COM; defaulting to no policy Principal "host/ldap-server.example.com@EXAMPLE.COM" 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: ```text kadmin -p ubuntu/admin -q "addprinc -randkey host/ldap-server.example.com" ``` ```{note} `sudo` is not needed to remotely create a new principal. ``` And: ```text 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: ```text sudo klist -k ``` You should see the following: ```text Keytab name: FILE:/etc/krb5.keytab KVNO Principal ---- -------------------------------------------------------------------------- 2 host/ldap-server.example.com@EXAMPLE.COM 2 host/ldap-server.example.com@EXAMPLE.COM ``` ## 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`: ```text sudo vi /etc/default/saslauthd ``` Make the following change: ```text ... # 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 for `saslauthd` to start. ``` Save and exit the editor. ## Enable and start saslauthd Continue by enabling and starting the saslauthd service. ```text 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: ```text testsaslauthd -u ubuntu -p ubuntusecret 0: OK "Success." ``` And with the wrong Kerberos password: ```text 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 the `sasl` group, so the `testsaslauthd` commands above need to be run as root (via `sudo`) or as a user who is in the `sasl` 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: ```text 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: ```text 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: ```text userPassword: {SASL}ubuntu@EXAMPLE.COM ``` 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 the `userPassword` attribute contained, say, `{SASL}anotheruser@EXAMPLE.COM`, OpenLDAP would ask `saslauthd` to authenticate `anotheruser@EXAMPLE.COM`, and not the user from the bindDN! Therefore, it's important to use OpenLDAP ACLs to prevent users from changing the `userPassword` 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. Note the usage of `-ZZ`, which forces the connection to use StartTLS and thus encrypt the traffic, including the simple bind credentials: ```text ldapadd -x -D cn=admin,dc=example,dc=com -W -ZZ <