Current Linux distributions can seamlessly work as members of Active Directory domains which gives them access to the AD authentication system. However it requires the Linux hosts to “join” the AD domain, for which one has to posses some special AD privileges. In many cases this is not viable and we may only want a simple user authentication without any write privileges to the Active Directory. Good old LDAP provides such an option.

SSSD for LDAP authentication

We’ll demo it on an Amazon Linux EC2 instance authenticating against AWS Simple AD Directory Service. However the instructions should also work for RedHat Enterprise Linux 6 or 7, CentOS or Oracle Linux. And also should work for against “real” Microsoft AD instead of AWS Simple AD which is in fact Samba 4 running on Linux.

We will use SSSD – System Security Services Daemon – instead of the legacy pam_ldap based suite. SSSD has been introduced in RHEL 6 and it’s actually quite a nice, modern, modular authentication system.

Pre-requisities – Install the required software

[root@ldap-demo ~]# yum install sssd sssd-tools sssd-ldap openldap-clients

Pre-requisities – Read-only LDAP user

For authentication and listing users and groups SSSD needs to bind to the LDAP directory. It’s enough to have a read-only user with just enough privileges to read the directory. How to create one is beyond the scope of this article. Let’s assume that your bind_dn is CN=ReadOnlyUser,CN=Users,DC=test,DC=aws,DC=nz and password is Read0nly. Get yours from your AD administrator 🙂

Test with ldapsearch:

[root@ldap-demo ~]# ldapsearch -H ldaps://test.aws.nz -x \
        -D CN=ReadOnlyUser,CN=Users,DC=ds,DC=e-it,DC=nz -w Read0nly \
        -b CN=Users,DC=ds,DC=e-it,DC=nz
# extended LDIF
#
# LDAPv3
# base  with scope subtree
# filter: (objectclass=*)
# requesting: ALL
#
[...]
# search result
search: 2
result: 0 Success
# numResponses: 30
# numEntries: 29

If the DN or Password is wrong you’ll get something like:

ldap_bind: Invalid credentials (49)
	additional info: Simple Bind Failed: NT_STATUS_LOGON_FAILURE

Also note that you must use SSL or StartTLS with SSSD. It will not send passwords over unencrypted channels!

Create sssd.conf

Create /etc/sssd/sssd.conf with a content like the following. Obviously update the ldap_uri, ldap_search_base and ldap_default_bind_dn to match your setup. Don’t worry about the password yet.

[sssd]
config_file_version = 2
domains = default
services = nss, pam
full_name_format = %1$s

[nss]

[pam]

[domain/default]
id_provider = ldap
cache_credentials = True
ldap_uri = ldaps://test.aws.nz
ldap_search_base = CN=Users,DC=test,DC=aws,DC=nz
ldap_schema = AD
ldap_default_bind_dn = CN=ReadOnlyUser,CN=Users,DC=test,DC=aws,DC=nz
ldap_default_authtok_type = obfuscated_password
ldap_default_authtok = Some_Place_Holder_For_Now

# Obtain the CA root certificate for your LDAPS connection.
ldap_tls_cacert = /etc/pki/tls/cacerts.pem

# AWS SimpleAD doesn't provide a way to download
# the CA root certificate at the moment.
# This setting disables cert verification.
#ldap_tls_reqcert = allow

# Only if the LDAP directory doesn't provide uidNumber and gidNumber attributes
ldap_id_mapping = True

# Consider setting enumerate=False for very large directories
enumerate = True

# Only needed if LDAP doesn't provide homeDirectory and loginShell attributes
fallback_homedir = /home/%u
default_shell = /bin/bash

Now lock down the permissions or sssd will refuse to start:

[root@ldap-demo ~]# chmod 600 /etc/sssd/sssd.conf

And finally create an obfuscated password for the Bind DN account:

[root@ldap-demo ~]# sss_obfuscate --domain default
Enter password: Read0nly
Re-enter password: Read0nly
[root@ldap-demo ~]# 

You will notice that the ldap_default_authtok has been updated with a long unreadable string.

Time to start sssd and test it. My test user account is obviously test.

[root@ldap-demo ~]# service sssd start
Starting sssd:                                             [  OK  ]

[root@ldap-demo ~]# getent passwd test
test:*:976201114:976200513:Test User:/home/test:/bin/bash

User ID mapping

You will have noticed the “strange” UID=976201114 and a similarly strange GID in the getent output above. That’s that result of ID mapping that allows to have consistent UIDs and GIDs even in situations where the LDAP directory doesn’t provide the uidNumber and gidNumber attributes. The keyword is consistent – the UID and GID values are derived from the user’s SID value (which is sort of a Windows UID) in a predictable, consistent way. That means that our user test will have UID 976201114 on all Linux hosts that authenticate against our AD using the the above config. See the section ID Mapping in man sssd-ldap for more details.

Enable use of SSS for authentication

Best to use the standard authconfig tool.

[root@ldap-demo ~]# authconfig --enablesssd --enablesssdauth --enablemkhomedir --updateall

At the same time we have enabled automatic creation of the users home directories with --enablemkhomedir.

It’s also a necessary to enable password authentication for SSH as it is by default disabled in Amazon Linux:

[root@ldap-demo ~]# grep PasswordAuthentication /etc/ssh/sshd_config
PasswordAuthentication yes

[root@ldap-demo ~]# service sshd restart
Stopping sshd:                                             [  OK  ]
Starting sshd:                                             [  OK  ]
[root@ldap-demo ~]# 

Test it!

Drumroll…. tadaaaa….

[root@ldap-demo ~]# ssh test@localhost
test@localhost's password: 
Creating directory '/home/test'.

       __|  __|_  )
       _|  (     /   Amazon Linux AMI
      ___|\___|___|

https://aws.amazon.com/amazon-linux-ami/2017.09-release-notes/

[test@ldap-demo ~]$ id
uid=976201114(test) gid=976200513(Domain Users) groups=976200513(Domain Users)

Great 🙂