CentOS 8/9 – Setting up LDAP/Kerberos Authentication using Active Directory without Joining to the AD Domain

By El Virtual Jefe No comments

We all want to be able to use a centralized user database so we aren’t constantly having to make sure users and passwords match up between systems. This isn’t always the easiest to do, when using Linux with Microsoft AD DS.

I was asked to come up with a way to give Linux systems a “templated” and repeatable way to utilize AD Accounts to log into Linux systems, without having to deal with joining the Linux system to the domain.

Now, you may ask, “Why not just join it to the domain, and be done with it?!” The answer: They didn’t want to deal with managing the computer objects.

Fair enough… After a ton of research, trial & error and piecing some things together, I came up with the solution in this post. It turns out that the setup and configuration for this is super easy and quick to setup. I will do my best to try to explain all of the options/configurations that I chose to implement.

I am going to make some assumptions in this article:

  • You have a CentOS 8 or 9 system setup and configured with the basic tools
    • This guide should work with any RHEL 8 or 9 flavor of Linux, but I wrote this guide with CentOS
  • You have your DNS pointed to your AD Server(s)
  • You have an account setup for authenticating users to AD

So let’s get started…

We need to start by verifying that DNS Lookups are working properly for our AD Domain. We will do this, by utilizing the dig program:

dig -t SRV _ldap._tcp.ad.virtualjefe.com
dig -t SRV _ldap._tcp.dc._msdcs.ad.virtualjefe.com
dig -t SRV _KERBEROS._tcp.ad.virtualjefe.com
dig -t SRV _KERBEROS._tcp.dc._msdcs.ad.virtualjefe.com

* If you do not have dig on your machine, you can install bind-utils.

This lets us verify that DNS is working, and that we can identify the Domain Controllers, in our environment, that will accept LDAP queries.

Install needed packages:

dnf install sssd sssd-tools krb5-workstation oddjob-mkhomedir

These packages are needed for various different parts of the LDAP Authentication process.

sssd/sssd-tools – This is what does most of the heavy lifting, and brings in the LDAP authentication/identification.

krb5-workstation – This performs the actual authentication. You will see later, that we are using kerberos ticketing for the actual authentication.

oddjob-mkhomedir – This is used to automatically create the /home folder for a user when they log into the box for the first time.

Now that we have everything that we need, installed, lets setup our Kerberos ticketing… We will need to edit /etc/krb5.conf:

includedir /var/lib/sss/pubconf/krb5.include.d/

[libdefaults]
    dns_lookup_realm = true
    dns_lookup_kdc = true
    ticket_lifetime = 24h
    renew_lifetime = 7d
    forwardable = true
#    rdns = false
#    pkinit_anchors = FILE:/etc/pki/tls/certs/ca-bundle.crt
#    spake_preauth_groups = edwards25519
    default_realm = AD.VIRTUALJEFE.COM
#    default_ccache_name = KEYRING:persistent:%{uid}

In the above settings, we are setting up our box to allow DNS lookups of both the realm and the KDC server. This is why we checked to make sure we could resolve the SRV records, earlier.

We also want to set our ticket and renewal lifetimes. I picked these time lengths because it works for me. You can choose whatever timelines you want, and the defaults are 24 hours and 0 hours, respectively.

And finally, we set our default Realm. This just allows us to log into the host without having to fully qualify our usernames (i.e. VIRTUALJEFE\vjefe or [email protected]). I like having this configured, because I have users that refuse to fully qualify their usernames. So, as a compromise, I set a default realm.

Next we need to edit or create our configuration file for sssd (/etc/sssd/sssd.conf). This file does not exist, by default, when you first install sssd. However, you may have a previous sssd configuration, so your mileage may vary. In this file, we are going to setup how LDAP is going to identify users, and how Kerberos is going to authenticate them.

Here is what my configuration looks like:

[sssd]
domains = ad.virtualjefe.com
services = nss, pam, ssh, autofs, sudo
full_name_format = %1$s
config_file_version = 2
#debug_level = 9

[nss]
filter_users = nobody,root,mdaops,rabbitmq,postfix,apache,redis,nagios,tcpdump
filter_groups = nobody,root,mdaops,rabbitmq,postfix,apache,redis,nagios,tcpdump
#debug_level = 9

[pam]
#debug_level = 9

[ssh]
#debug_level = 9

[autofs]

[sudo]

[domain/ad.virtualjefe.com]
id_provider = ldap
auth_provider = krb5
chpass_provider = krb5
access_provider = ldap

ldap_access_order = filter, expire
ldap_account_expire_policy = ad

ldap_referrals = false
ldap_id_mapping = true
enumerate = false
case_sensitive = false

ldap_user_principal = userPrincipalNameDoesNotExist

ldap_search_base = DC=ad,DC=virtualjefe,DC=com
ldap_schema = ad
ldap_id_use_start_tls = false
ldap_tls_reqcert = never

ldap_default_bind_dn = CN=bind-account,OU=Service Accounts,OU=Users,DC=ad,DC=virtualjefe,DC=com
ldap_default_authtok_type = obfuscated_password
ldap_default_authtok = xxxxx

ldap_access_filter = memberOf=*

fallback_homedir = /home/%d/%u
default_shell = /bin/bash

krb5_realm = AD.VIRTUALJEFE.COM
krb5_user_enterprise_principal = true
krb5_canonicalize = false
krb5_validate = false
ldap_force_upper_case_realm = true

#debug_level = 9

sudo_provider = ldap
autofs_provider = ldap

In the [sssd] section, I am setting up the domain(s) that will be used for login, as well as the services that will utilize sssd and that the configured domain(s).

The following 5 sections (in my case) reflect a section for each of the services that we declared in the [sssd] section. Each service that you configure can have it’s own settings for how you want them to identify and authenticate the users, or whether you want to filter out any users/groups.

The last section [domain/*] is our domain configuration. This is where we tell sssd how to interact with our domain, and what ways we want to identify and authenticate our users. In my configuration, I am using LDAP as the identity provider, as well as access management. I am then telling the domain that I want to use Kerberos to authenticate the identity from LDAP, as well as facilitating password changes through Kerberos.

You will need to get the DN (Distinguished Name) of your user account that you will use for connecting to your LDAP source. This is configured as ldap_default_bind_dn. I will show you how to setup the password for the account later in this post.

One configuration I want to point out, in particular, is

ldap_user_principal = userPrincipalNameDoesNotExist

Setting this to an attribute that doesn’t exist in your environment allows you to be able to login with LDAP accounts that have a UPN that doesn’t match the <username>@<domain_name> format. I found this to be an issue when using Azure AD with email addresses set as the UPN.

Also, the ldap_access_filter uses standard LDAP query language. You can look that up, as it is pretty simple, and out of scope for this article.

Setup LDAP Obfuscated Password:

sss_obfuscate --domain ad.virtualjefe.com

This will encrypt your auth token password and place it in your sssd.conf file for you. So, there is no need to update it when building your initial config file.

Set Permissions on /etc/sssd/sssd.conf:

chmod 600 /etc/sssd/sssd.conf

Here, you want to make sure that only the root user can modify the sssd.conf file. You also don’t want other users to be able to see the file. This is something that I did, for security purposes, but is not necessarily required.

Enable sssd:

authselect select sssd with-mkhomedir --force

At this point, we want to tell the kernel to use sssd for authentication, and that we want the home directories created automatically. This is how we facilitate creating the directories structure we specified in our sssd.conf file.

(re)Start sssd and oddjobd service:

systemctl restart sssd
systemctl restart oddjobd

Enable sssd service at startup:

systemctl enable sssd
systemctl enable oddjobd

At this point, you should have a working configuration to allow users to login with AD Credentials, utilizing LDAP for identification and Kerberos for Authentication.

Somethings to note:

  • When using ldap_access_filter the memberOf field does not list the Primary Group in AD.  You may have to use primaryGroupID, instead.
  • Sudoers should be configured to properly allow access to the OS. I will post another article about this, as a follow up to this article.

Leave a Reply