Fixing Active Directory domain joins on Ubuntu 18.04 after KB4586830

     

We use Noobuntu for enrolling Linux clients in our AD environment. This week we applied the following updates on our DCs:

  • KB4586830
  • KB890830
  • KB4576750

The latter 2 don’t have any kind of changelog, but the KB4586830 article says:

Known issues in this update
After installing this update on domain controllers (DCs) and read-only domain controllers (RODCs) in your environment, you might encounter Kerberos authentication and ticket renewal issues.
Kerberos service tickets and ticket-granting tickets (TGT) might not renew for non-Windows Kerberos clients when PerformTicketSignature is set to 1 (the default).

Well that’s exactly what we faced afterwards. We’d either get this:

$ sudo realm join [email protected] dc1.ad.foobar.com -v
 * Resolving: _ldap._tcp.dc1.ad.foobar.com
 * Resolving: dc1.ad.foobar.com
 * Performing LDAP DSE lookup on: 10.1.3.1
 * Successfully discovered: ad.foobar.com
Password for [email protected]: 
 * Unconditionally checking packages
 * Resolving required packages
 * LANG=C /usr/sbin/adcli join --verbose --domain ad.foobar.com --domain-realm AD.FOOBAR.COM --domain-controller 10.1.3.1 --os-name Ubuntu Workstation --os-version 18.04 --login-type user --login-user [email protected] --stdin-password --user-principal
 * Using domain name: ad.foobar.com
 * Calculated computer account name from fqdn: FOO439LINUX
 * Using domain realm: ad.foobar.com
 * Sending NetLogon ping to domain controller: 10.1.3.1
 * Received NetLogon info from: dc1.ad.foobar.com
 * Wrote out krb5.conf snippet to /var/cache/realmd/adcli-krb5-sormvM/krb5.d/adcli-krb5-conf-oFA8AO
 * Authenticated as user: [email protected]
 * Using GSS-SPNEGO for SASL bind
 ! Couldn't lookup domain short name: Can't contact LDAP server
 ! Couldn't lookup domain SID: Can't contact LDAP server
 * Using fully qualified name: foo439linux.ad.foobar.com
 * Using domain name: ad.foobar.com
 * Using computer account name: FOO439LINUX
 * Using domain realm: ad.foobar.com
 * Calculated computer account name from fqdn: FOO439LINUX
 * With user principal: host/[email protected]
 * Generated 120 character computer password
 * Using keytab: FILE:/etc/krb5.keytab
 ! Couldn't lookup computer account: FOO439LINUX$: Can't contact LDAP server
adcli: joining domain ad.foobar.com failed: Couldn't lookup computer account: FOO439LINUX$: Can't contact LDAP server
 ! Failed to join the domain

Or this:

$ sudo realm join --user stewie.griffin ad.foobar.com -v
 * Resolving: _ldap._tcp.ad.foobar.com
 * Performing LDAP DSE lookup on: 10.1.3.1
 * Performing LDAP DSE lookup on: 10.1.0.118
 * Successfully discovered: ad.foobar.com
Password for stewie.griffin:
 * Unconditionally checking packages
 * Resolving required packages
 * LANG=C /usr/sbin/adcli join --verbose --domain ad.foobar.com --domain-realm AD.FOOBAR.COM --domain-controller 10.1.3.1 --os-name Ubuntu Workstation --os-version 18.04 --login-type user --login-user stewie.griffin --stdin-password --user-principal
 * Using domain name: ad.foobar.com
 * Calculated computer account name from fqdn: FOO439LINUX
 * Using domain realm: ad.foobar.com
 * Sending NetLogon ping to domain controller: 10.1.3.1
 * Received NetLogon info from: dc1.ad.foobar.com
 * Wrote out krb5.conf snippet to /var/cache/realmd/adcli-krb5-xHwb94/krb5.d/adcli-krb5-conf-pWj3Ps
 * Authenticated as user: [email protected]
 * Using GSS-SPNEGO for SASL bind

And then realm would get stuck here forever. Oddly enough, this only happened on 18.04, Ubuntu 20.04, Fedora Workstation, and CentOS/RHEL clients worked just fine. So the idea was to try updating some of the relevant packages from the 20.04 repo. At the end of the day, the libsasl2-modules-gssapi-mit package turned out to be the culprit. So how do you rebuild the 20.04 packages for 18.04? Let’s head over to the Cyrus SASL source packages for 20.04 and save the URLs for those 3 files on the bottom. Then fire up 18.04 in Docker:

cd
mkdir -p cyrus-sasl
docker run -it --network=host --rm --mount type=bind,source="$(pwd)"/cyrus-sasl,target=/pkg ubuntu:18.04

And now in the container, build the packages against 18.04 (update the file URLs accordingly from the page linked above, they’ll change over time):

sed -i 's/^# deb-src/deb-src/g' /etc/apt/sources.list
apt update
apt -y install wget dpkg-dev libpod-pom-view-restructured-perl python3-sphinx
apt -y build-dep cyrus-sasl2

cd /pkg
wget http://archive.ubuntu.com/ubuntu/pool/main/c/cyrus-sasl2/cyrus-sasl2_2.1.27+dfsg-2.dsc \
http://archive.ubuntu.com/ubuntu/pool/main/c/cyrus-sasl2/cyrus-sasl2_2.1.27+dfsg.orig.tar.xz \
http://archive.ubuntu.com/ubuntu/pool/main/c/cyrus-sasl2/cyrus-sasl2_2.1.27+dfsg-2.debian.tar.xz

dpkg-source -x cyrus-sasl2_2.1.27+dfsg-2.dsc
cd cyrus-sasl2-2.1.27+dfsg
dpkg-buildpackage -b -d

Once finished, you can exit the container, the resulting .deb packages will be in ~/cyrus-sasl. You only need to replace 2 packages:

  • libsasl2-modules
  • libsasl2-modules-gssapi-mit

But wait, you said the culprit is just libsasl2-modules-gssapi-mit, then why libsasl2-modules too? Because libsasl2-modules-gssapi-mit depends on the corresponding version of libsasl2-modules, so you need to update both at the same time. So in our example, at the time of writing:

dpkg -i libsasl2-modules_2.1.27+dfsg-2_amd64.deb libsasl2-modules-gssapi-mit_2.1.27+dfsg-2_amd64.deb

Or preferably, if your company has an internal .deb repo (which it most definitely should), you can upload it there, and then your clients will receive it automatically as an update.

And that’s about it, now domain joins work as they should, the day is saved. Cheers 🙂