AzureAD and Linux

Authenticating Linux using Microsoft Azure AD pam, sssd, and kerberos

For anyone that works in a mixed Linux and Windows environment, your situation might be different. Hell, it might be wildly different. For me, any time I have had to work in a mixed environment, it was always “Windows in this corner, Linux in that corner”. This made it difficult when things had to work together. Except for Samba (ugh) I have been lucky enough to mostly just have to deal with user accounts of a very small group. Which means local accounts on the servers.

This isn’t really a problem. In my current situation, most of the servers have less than 10 users on it. One half of them have only 3 or 4 which is the unix team (heh, team, its just me) and some network or other admin types. The web servers get a few additional users. Right now I have only two servers that have more than 10 users, and both are used by students and faculty to log in and manage some personal websites and teaching materials.

While I don’t mind dealing with local accounts, I HATE dealing with local passwords. Not a problem for myself and the other admins, just use SSH keys and all is good with the world. Anyone that has tried to teach SSH keys to a classroom full of freshman who don’t have local passwords on their laptops and every website they use password saved in their brower can tell you, showing someone that is 100% uninterested in using SSH keys how to use SSH keys is a recipie for disaster. And I will include a few faculty in that statement. “but I can log in with my face!”

The solution I have come up with is to use kerberos. AD will allow you to use kereros even if your device isn’t in the domain as a computer object, as long as you can get to it. The end result is I can control access via local users and local groups, but users can have a single password for AD and Linux. Not quite SSO/SingleSignOn, but at least “common password” without the mess of password replication.

There are two parts to this. 1) configure kerberos on the server, and 2) configure sssd to use kerberos for authenitcation. It even works very nicely with Microsofts new Azure AD Directory Services (here after called ‘aadds’ in this document), assuming you offer it as a service and can get to it via the network.

The first step is to edit /etc/krb5.conf

# To opt out of the system crypto-policies configuration of krb5, remove the
# symlink at /etc/krb5.conf.d/crypto-policies which will not be recreated.
includedir /etc/krb5.conf.d/

[logging]
    default = FILE:/var/log/krb5libs.log
    kdc = FILE:/var/log/krb5kdc.log
    admin_server = FILE:/var/log/kadmind.log

[libdefaults]
    dns_lookup_realm = false
    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 = AADDS.EXAMPLE.EDU
    default_ccache_name = KEYRING:persistent:%{uid}

[realms]
AADDS.EXAMPLE.EDU = {
     kdc = aadds.example.edu
     admin_server = aadds.example.edu
}

[domain_realm]
 aadds.example.edu = aadds.example.edu
 .aadds.example.edu = aadds.example.edu

Once that is done, you should be able to do a realm discover. The great thing about this method is you don’t actually have to join the domain.

[root@centos8-test ~]# realm discover aadds.example.edu
aadds.example.edu
  type: kerberos
  realm-name: AADDS.EXAMPLE.EDU
  domain-name: aadds.example.edu
  configured: no
  server-software: active-directory
  client-software: sssd
  required-package: oddjob
  required-package: oddjob-mkhomedir
  required-package: sssd
  required-package: adcli
  required-package: samba-common-tools
[root@centos8-test ~]#

Now that krb5 is done, you have to edit /etc/sssd/sssd.conf.

[sssd]
        services = nss, pam
        domains = AADDS.EXAMPLE.EDU

[domain/AADDS.EXAMPLE.EDU]
        id_provider = files
        auth_provider = krb5
        krb5_realm = AADDS.EXAMPLE.EDU
        krb5_server = aadds.example.edu

Once that is completed, stop and restart sssd. Make sure the sssd.conf file is 0600. I usually get a crazy sssd error when doing it quickly, so I stop sssd, wait a few minutes then restart it. (Usual process is stop it, start it, get error, be confused, check config with vi, try again and it works.) You can also launch sssd in debug with “sssd -d4 -i” and watch the screen as stuff happens. What should happen is when you try to connect to your box with a local account that you never set a password for, it goes to check kerberos for the password. Then you see messages where it connects to your AD service and then authenitcates you.

If you want to look at your tokens, you can use kinit and klist. This is after I logged in as me with ssh.

[nickdanger@centos8-test ~]$ klist
Ticket cache: KCM:1000:16630
Default principal: nickdanger@AADDS.EXAMPLE.EDU

Valid starting       Expires              Service principal
01/05/2022 18:36:55  01/06/2022 04:36:55  krbtgt/AADDS.EXAMPLE.EDU@AADDS.EXAMPLE.EDU
        renew until 01/12/2022 18:36:55
[nickdanger@centos8-test ~]$

I attempted to sanitize the data, I dont really work for example.edu, but this was all output from my system. Also note that the DNS entry of the kdc and admin_server must actually resolve, and the user must be exist on the system locally. This is only for password authentication, not authorization and it does not create/build users that don’t exist.

** Addendum **

I started using packer (post on that later). I used packer to make a new template in VMware for deploying machines. This was working great (so I thought). Most servers I build have myself, and maybe one other log in. And we use ssh keys. For servers (like web) that have other developer type people logging in, I set up sssd against Azure AD. Then they have a common username / pw combo to log in. This works great!

The last few machines I had built were for myself/other ssh key users only. I rebuilt the web server, spent quite a load of time getting Oracle, MySQL and Sybase connectivity and PHP working, then handed it over to the web developers. And none of them could log in.

Weird. kinit works, but sshd would not allow a user to log in using their AD password. I start poking around, getting nowhere, and finally ask on Mastodon. I got a few suggestions. I build a new VM using the old template, Azure AD auth works fine. New template? Nope.

This morning I asked my boss who started rambling about Google Auth 2FA and ssh, and reminded me to check in /etc/security. Ahhhh… thats the problem. For whatever reason, the old template I build did an authselect select sssd, but the new one did not. I did “authselect select sssd” on the web server that wasn’t working and voila. All is well.

I redid my packer config and built new templates that work.