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 # basewith 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 🙂
Hi, this is cool article, i tried to create new user CN=bob,CN=Users,DC=ldap,DC=test,DC=io, and i set the attribute user.password. But it always ldap_bind: Invalid credentials (49) and cannot authenticate. Any idea how is the workflow to this case ? Thanks
Hi Michael
Nice article !
one thing about the step #Obtain the CA root certificate for your LDAPS connection.
Do we need a certificate chain ( root + intermediate) or just the trusted root CA certificate .
We tried that but cannot pass through the ldapsearch with ldaps.
it says Can’t contact LDAP server (-1)
Peer’s Certificate issuer is not recognized.
Followed the steps all the way till end but couldn’t ssh.
thanks
The Root CA should be enough, provided the LDAP server sends the full certificate chain in TLS handshake. If it only sends the server cert and the intermediate certs are missing then the client won’t have a trusted path to verify it.
Thanks for this article!
I followed and still I miss sth, why do you have a user called test? I mean when you run:
“getent passwd test”
Is it created when service sssd is restarted? Did you created previously the whole setup?
Thanks in advance!
That
test
user is from the AD. Test it with any user that exists in your Active Directory.Worked like a charm with one caveat. After login I get:
id: cannot find name for group ID 1034010512
Is there something special I need to do to get the group mapping to something nice?
Follow up to my earlier question. If there is a specific primary group I would like the users to fall into (that is a real group on the box) and secondary groups I’d like to add them to dynamically from LDAP attributes. Is that possible?
Thanks
It worked well for me in my Amazon Linux
It seems that SimpleAD may no longer support LDAPS, so there is some work to effort required to connect sssd to it…
https://aws.amazon.com/blogs/security/how-to-configure-an-ldaps-endpoint-for-simple-ad/
One question, you are using a read only DN to bind to openldap in order to perform the search and the authentication of the user. If I login into the system with a normal user, Can you use a password command in order to change its passwords (if you have in the branch self.write privilege), It’s not a problem using a readonly user in sssd.com?
Thanks in advance
Helps me a lot
many thansk
we hate to join ADS with the linux boxes
Thomas
Thanks. Nonetheless, I can’t make my CentOS 7 authenticate against our company AD. The AD server doesn’t provide LDAPS and works on port 389 only. I know some other services (like Gerrit Code Revew) are able to authenticate against it, but sssd with the above config fails to authenticate without any obvious reason. It just returns ‘[7] Authentication failure’ although I’m definitely using the correct password.
I checked the output of ldapsearch and it doesn’t seem to contain the password attribute in any form. Can that be the problem? Any ideas how to solve that?
More details. When I use `sssctl user-checks -a auth ldapusername`, I never get asked for a password and get that ‘[7] Authentication failure’ in the logs. If I however change ‘use_first_pass’ to ‘prompt_always’ in pam config for pam_sss, I then get asked for the password by `sssctl` and authentication succeeds there, but sshd still fails, although now with ‘[6] Permission denied’.