SSSD and Active Directory

SSSD and Active Directory

This section describes the use of sssd to authenticate user logins against an Active Directory via using sssd’s “ad” provider. At the end, Active Directory users will be able to login on the host using their AD credentials. Group membership will also be maintained.

Prerequisites, Assumptions, and Requirements

  • This guide does not explain Active Directory, how it works, how to set one up, or how to maintain it.

  • This guide assumes that a working Active Directory domain is already configured and you have access to the credentials to join a machine to that domain.

  • The domain controller is acting as an authoritative DNS server for the domain.

  • The domain controller is the primary DNS resolver (check with systemd-resolve --status)

  • System time is correct and in sync, maintained via a service like chrony or ntp

  • The domain used in this example is ad1.example.com .

Software Installation

Install the following packages:

sudo apt install sssd-ad sssd-tools realmd adcli

Join the domain

We will use the realm command, from the realmd package, to join the domain and create the sssd configuration.

Let’s verify the domain is discoverable via DNS:

$ sudo realm -v discover ad1.example.com
 * Resolving: _ldap._tcp.ad1.example.com
 * Performing LDAP DSE lookup on: 10.51.0.5
 * Successfully discovered: ad1.example.com
ad1.example.com
  type: kerberos
  realm-name: AD1.EXAMPLE.COM
  domain-name: ad1.example.com
  configured: no
  server-software: active-directory
  client-software: sssd
  required-package: sssd-tools
  required-package: sssd
  required-package: libnss-sss
  required-package: libpam-sss
  required-package: adcli
  required-package: samba-common-bin

This performs several checks and determines the best software stack to use with sssd. sssd can install the missing packages via packagekit, but we installed them already previously.

Now let’s join the domain:

$ sudo realm join ad1.example.com
Password for Administrator: 

That was quite uneventful. If you want to see what it was doing, pass the -v option:

$ sudo realm join -v ad1.example.com
 * Resolving: _ldap._tcp.ad1.example.com
 * Performing LDAP DSE lookup on: 10.51.0.5
 * Successfully discovered: ad1.example.com
Password for Administrator: 
 * Unconditionally checking packages
 * Resolving required packages
 * LANG=C /usr/sbin/adcli join --verbose --domain ad1.example.com --domain-realm AD1.EXAMPLE.COM --domain-controller 10.51.0.5 --login-type user --login-user Administrator --stdin-password
 * Using domain name: ad1.example.com
 * Calculated computer account name from fqdn: AD-CLIENT
 * Using domain realm: ad1.example.com
 * Sending NetLogon ping to domain controller: 10.51.0.5
 * Received NetLogon info from: SERVER1.ad1.example.com
 * Wrote out krb5.conf snippet to /var/cache/realmd/adcli-krb5-hUfTUg/krb5.d/adcli-krb5-conf-hv2kzi
 * Authenticated as user: Administrator@AD1.EXAMPLE.COM
 * Looked up short domain name: AD1
 * Looked up domain SID: S-1-5-21-2660147319-831819607-3409034899
 * Using fully qualified name: ad-client.ad1.example.com
 * Using domain name: ad1.example.com
 * Using computer account name: AD-CLIENT
 * Using domain realm: ad1.example.com
 * Calculated computer account name from fqdn: AD-CLIENT
 * Generated 120 character computer password
 * Using keytab: FILE:/etc/krb5.keytab
 * Found computer account for AD-CLIENT$ at: CN=AD-CLIENT,CN=Computers,DC=ad1,DC=example,DC=com
 * Sending NetLogon ping to domain controller: 10.51.0.5
 * Received NetLogon info from: SERVER1.ad1.example.com
 * Set computer password
 * Retrieved kvno '3' for computer account in directory: CN=AD-CLIENT,CN=Computers,DC=ad1,DC=example,DC=com
 * Checking RestrictedKrbHost/ad-client.ad1.example.com
 *    Added RestrictedKrbHost/ad-client.ad1.example.com
 * Checking RestrictedKrbHost/AD-CLIENT
 *    Added RestrictedKrbHost/AD-CLIENT
 * Checking host/ad-client.ad1.example.com
 *    Added host/ad-client.ad1.example.com
 * Checking host/AD-CLIENT
 *    Added host/AD-CLIENT
 * Discovered which keytab salt to use
 * Added the entries to the keytab: AD-CLIENT$@AD1.EXAMPLE.COM: FILE:/etc/krb5.keytab
 * Added the entries to the keytab: host/AD-CLIENT@AD1.EXAMPLE.COM: FILE:/etc/krb5.keytab
 * Added the entries to the keytab: host/ad-client.ad1.example.com@AD1.EXAMPLE.COM: FILE:/etc/krb5.keytab
 * Added the entries to the keytab: RestrictedKrbHost/AD-CLIENT@AD1.EXAMPLE.COM: FILE:/etc/krb5.keytab
 * Added the entries to the keytab: RestrictedKrbHost/ad-client.ad1.example.com@AD1.EXAMPLE.COM: FILE:/etc/krb5.keytab
 * /usr/sbin/update-rc.d sssd enable
 * /usr/sbin/service sssd restart
 * Successfully enrolled machine in realm

By default, realm will use the Administrator account of the domain to request the join. If you need to use another account, pass it to the tool with the -U option.

Another popular way of joining a domain is using an OTP, or One Time Password, token. For that, use the --one-time-password option.

SSSD Configuration

The realm tool already took care of creating an sssd configuration, adding the pam and nss modules, and starting the necessary services.

Let’s take a look at /etc/sssd/sssd.conf:

[sssd]
domains = ad1.example.com
config_file_version = 2
services = nss, pam

[domain/ad1.example.com]
default_shell = /bin/bash
krb5_store_password_if_offline = True
cache_credentials = True
krb5_realm = AD1.EXAMPLE.COM
realmd_tags = manages-system joined-with-adcli 
id_provider = ad
fallback_homedir = /home/%u@%d
ad_domain = ad1.example.com
use_fully_qualified_names = True
ldap_id_mapping = True
access_provider = ad

Note

Something very important to remember is that this file must have permissions 0600 and ownership root:root, or else sssd won’t start!

Let’s highlight a few things from this config:

  • cache_credentials: this allows logins when the AD server is unreachable
  • home directory: it’s by default /home/<user>@<domain>. For example, the AD user john will have a home directory of /home/john@ad1.example.com
  • use_fully_qualified_names: users will be of the form user@domain, not just user. This should only be changed if you are certain no other domains will ever join the AD forest, via one of the several possible trust relationships

Automatic home directory creation

What the realm tool didn’t do for us is setup pam_mkhomedir, so that network users can get a home directory when they login. This remaining step can be done by running the following command:

sudo pam-auth-update --enable mkhomedir

Checks

You should now be able to fetch information about AD users. In this example, John Smith is an AD user:

$ getent passwd john@ad1.example.com
john@ad1.example.com:*:1725801106:1725800513:John Smith:/home/john@ad1.example.com:/bin/bash

Let’s see his groups:

$ groups john@ad1.example.com
john@ad1.example.com : domain users@ad1.example.com engineering@ad1.example.com

Note

If you just changed the group membership of a user, it may be a while before sssd notices due to caching.

Finally, how about we try a login:

$ sudo login
ad-client login: john@ad1.example.com
Password: 
Welcome to Ubuntu 20.04 LTS (GNU/Linux 5.4.0-24-generic x86_64)
...
Creating directory '/home/john@ad1.example.com'.
john@ad1.example.com@ad-client:~$ 

Notice how the home directory was automatically created.

You can also use ssh, but note that the command will look a bit funny because of the multiple @ signs:

$ ssh john@ad1.example.com@10.51.0.11
Welcome to Ubuntu 20.04 LTS (GNU/Linux 5.4.0-24-generic x86_64)
(...)
Last login: Thu Apr 16 21:22:55 2020
john@ad1.example.com@ad-client:~$ 

Note

In the ssh example, public key authentication was used, so no password was required. Remember that ssh password authentication is by default disabled in /etc/ssh/sshd_config.

Kerberos Tickets

If you install krb5-user, your AD users will also get a kerberos ticket upon logging in:

john@ad1.example.com@ad-client:~$ klist
Ticket cache: FILE:/tmp/krb5cc_1725801106_9UxVIz
Default principal: john@AD1.EXAMPLE.COM

Valid starting     Expires            Service principal
04/16/20 21:32:12  04/17/20 07:32:12  krbtgt/AD1.EXAMPLE.COM@AD1.EXAMPLE.COM
	renew until 04/17/20 21:32:12

Note

realm also configured /etc/krb5.conf for you, so there should be no further configuration prompts when installing krb5-user

Let’s test with smbclient using kerberos authentication to list he shares of the domain controller:

john@ad1.example.com@ad-client:~$ smbclient -k -L server1.ad1.example.com

	Sharename       Type      Comment
	---------       ----      -------
	ADMIN$          Disk      Remote Admin
	C$              Disk      Default share
	IPC$            IPC       Remote IPC
	NETLOGON        Disk      Logon server share 
	SYSVOL          Disk      Logon server share 
SMB1 disabled -- no workgroup available

Notice how we now have a ticket for the cifs service, which was used for the share list above:

john@ad1.example.com@ad-client:~$ klist
Ticket cache: FILE:/tmp/krb5cc_1725801106_9UxVIz
Default principal: john@AD1.EXAMPLE.COM

Valid starting     Expires            Service principal
04/16/20 21:32:12  04/17/20 07:32:12  krbtgt/AD1.EXAMPLE.COM@AD1.EXAMPLE.COM
	renew until 04/17/20 21:32:12
04/16/20 21:32:21  04/17/20 07:32:12  cifs/server1.ad1.example.com@AD1.EXAMPLE.COM

Desktop Ubuntu Authentication

The desktop login only shows local users in the list to pick from, and that’s on purpose.

To login with an Active Directory user for the first time, follow these steps:

  • click on the “Not listed?” option:

  • type in the login name followed by the password:

  • the next time you login, the AD user will be listed as if it was a local user:

Known Issues

When logging in on a system joined with an Active Directory domain, sssd (the package responsible for this integration) will try to apply Group Policies by default. There are cases where if a specific policy is missing, the login will be denied.
This is being tracked in bug #1934997. Until the fix becomes available, please see comment #5 in that bug report for existing workarounds.

Resources

1 Like

Thank you for this document. I followed this guide on a clean 22.04 minimal server install. I was able to login locally like the guide shows but the ssh attempts just fail with a disconnect. Is there additional configuration required besides allowing PasswordAuthentication in the sshd config (although though the default account work via ssh without making this change)?

Have you used the full username, with the realm part, like ssh user@DOMAIN@server?. But it’s best to check /var/log/auth.log as to why the login via ssh was denied.

1 Like

It appears that is a potential sssd bug related to the GPO code. The auth.log provided just a generic permission denied error, however from the bug notes adding ad_gpo_access_control = permissive to the sssd domain config allows the domain user to login.

Have you tried creating the empty policy file on the samba server like outlined in this bug comment?

1 Like

sssd 2.7.x has the fix, but it’s not in any ubuntu release yet. I guess we can update this section with the two workarounds for now (the permissive setting (less ideal), and creating the empty policy file if the AD is samba4).

1 Like

I have a 2016 level MS AD domain with only 3 policies that I was testing with so the samba directory wouldn’t apply however that tpl file only appears to show up if you make changes to the security settings in a GPO. The 2 default domain polices this exists but not in my third policy. Its very likely there is another issue and making the sssd setting to permissive allows it to ignore the error. I know this site is not for technical support so I will keep it high level. I just know that I did minimal installs on 20.04 Deskto and both 22.04 Desktop / Server testing both the ubiquity installed AD join and the post install instructions above and they all had this problem were AD users weren’t able to ssh with the most standard OOB configuration.

I did some additional debugging. The default value for ad_gpo_access_control for sssd 2.2.3 in ubuntu on 20.04 is “enforcing” and this applies the ad_gpo_map. What I found was I needed to create a GPO in AD that set the “Allow log on through Remote Desktop Services” and add the AD users trying to SSH. Once this was in place, sssd pulled the computer’s GPO and referenced that policy to allow the domain user to login. This is a direct policy lookup each login via the SYSVOL. I was able to login with a user. Remove them from the gpo setting at the policy level and it immediately blocked the login, so not traditional MS AD gpudate provisioning delays. So I think if you make a reference in the documentation that if a domain user is unable to login remotely via ssh, the domain admins may need to configure the Allow log on through Remote Desktop Services policy under Computer Configuration -> Policies -> Windows Settings -> Security Settings -> Local Policies -> User Rights Assignment and configure that item, then link the GPO. There are 2 notes I found. 1) There are limits to the “security filtering” that sssd handles on the GPO and folks should reference man sssd-ad for those specifics and 2) it doesn’t appear that AD groups can be used at this time as that didn’t work in my initial testing.

At least in Ubuntu Studio 22.04.1 (with KDE Plasma 5.24.6) krb5-user does not appear to be necessary, as the command "smbclient -k -L " runs successfully without it. However the command results in the warning “The option -k|–kerberos is deprecated!”. Running it without -k requests the logged in user’s password, so it looks as though the kerberos ticket is not being used without the “-k” option. This is more a problem with smbclient: I was not able to find a man page which mentioned -k.
After following these instructions (as quoted in the whitepaper “Integration of Ubuntu Desktop with Microsoft Active Directory”), login as a domain user works, but both login and logout are accompanied by “Invalid user” messages, apparently caused by failures of authentication by pam_unix, which are immediately followed by successful authentications by pam_sss.
P.S. I have meanwhile found man pages which mention “-k”, but not in the usual places:
manpagez & Oracle

Apparently the pam_unix error message is normal behavior for a domain login, because pam tries to authenticate first as a local user. A more detailed explanation can be found here.
BTW, I would suggest testing domain login via “su” rather than “login”.

Indeed, pam_sss takes care of obtaining the kerberos ticket. Having krb5-user installed, and its tooling (kinit, klist, kdestroy and others) does help, though, specially klist, as it will tell you where the ticket is, what kind of encryption was used, flags, etc.

1 Like

It got dropped recently from samba as part of their command-line overhaul. The equivalent option should be --use-kerberos=desired|required|off.

1 Like

Do you get these messages in the terminal/GUI, or in the logs? In the logs the failure to authenticate should be correct, as pam_unix comes first in the stack, before the AD authentication is tried. But I wouldn’t want to see such errors “in my face” (terminal or GUI).

1 Like

The message “Invalid user name” appears in terminal but not in GUI. It appears after the login or logout has succeeded, regardless of whether “login” or “su” is used. I prefer “su” to “login”, because “login” requires sudo privileges. If this guide continues to recommend “login”, then “sudo” should be prepended to the illustrated command. Without it, a rather opaque error message, “Cannot possibly work without effective root” is displayed. Regardless of whether the guide recommends “login” or “su”, it would be nice to mention that the message “Invalid user name” is to be expected.
Many thanks for your work on this otherwise excellent guide!

You mean the message appears only during this login test from the guide? Not in day-to-day usage, when people login via a terminal on this system?

1 Like

Exactly, but I prefer to use “su”, because login prompts for both the admin password of the already logged in user, as well as the password of the domain user being tested, which can be confusing. I guess you already added “sudo” to the login test. I don’t remember seeing it before.
Also, the KDE login screen in Ubuntu Studio does not show previously logged in domain users as stated here: “the next time you login, the AD user will be listed as if it was a local user”. It only shows a local user. OTOH, it is pretty clear that your guide is referring to the gnome GUI.

It might be a setting in the KDE login manager. If you find out where to tweak it, post a comment here and I can update the guide.

Correct, I didn’t try any of the other Ubuntu flavors.

1 Like