Kerberos authenticated queries to Active Directory
There are many guides out there to help you configure your Linux system as an LDAP and Kerberos client to an Active Directory server. Most of these guides solve the problem of authentication by embedding a username and password into a configuration file somewhere on your system. While this works, it presents some problems:
- If you use a common account for authentication from all of your Linux systems, a compromise on one system means updating the configuration of all of your systems.
- If you don’t want to use a common account, you need to provision a new account for each computer…
- …which is silly, because if you join the system to Active Directory there is already a computer object associated with the system that can be used for authentication.
This document describes how to configure a Linux system such that queries generated by nss_ldap will use either the current user’s Kerberos credentials, or, for the root user, credentials stored in a Kerberos credentials cache.
Your Linux system must have a valid
keytab
file.A
keytab
is a file containing pairs of Kerberos principals and encrypted keys.Joining Active Directory using Samba’s
net ads join
will create the necessary keytab. It is also possible to create the keytab on your Windows domain controller and install it on your Linux systems. Instructions for doing this are beyond the scope of this document.Host objects in Active Directory must have a
userPrincipalName
attribute.For example:
$ ldapsearch cn=dottiness userPrincipalName dn: CN=DOTTINESS,CN=Computers,dc=example,dc=com userPrincipalName: host/dottiness.example.com@EXAMPLE.COM
Active Directory does not automatically create a
userPrincipalName
when a new host object is provisioned. You will either need to provide this value manually or develop an automated process that will populate this field when provisioning new host objects.
Kerberos credentials have a maximum usable lifetime. The cached credentials
used for root queries by nss_ldap
must be refreshed periodically in order to
function.
You will need to install a crontab (e.g., in /etc/cron.d
) that looks something
like this:
PATH=/bin:/usr/bin:/usr/kerberos/bin
@reboot root kinit -k -c /var/run/ldap_cc > /dev/null 2>&1
@hourly root kinit -k -c /var/run/ldap_cc > /dev/null 2>&1
This periodically reauthenticates to your domain controller used the cached
principal in the system keytab (/etc/krb5.keytab
) and caches the credentials in
/var/run/ldap_cc
.
You will need something similar to the following in /etc/ldap.conf
:
# This is your domain controller.
uri ldap://dc1.example.com
base dc=example,dc=com
scope one
referrals no
timelimit 120
bind_timelimit 120
idle_timelimit 3600
ldap_version 3
# Authenticate using SASL for user and root queries.
use_sasl on
rootuse_sasl on
# Use SASL's gssapi (Kerberos) mechanism.
sasl_mech gssapi
# Use these cached credentials for root.
krb5_ccname /var/run/ldap_cc
nss_base_group ou=groups,dc=example,dc=com
nss_base_passwd ou=people,dc=example,dc=com
nss_initgroups_ignoreusers root,ldap,named,avahi,haldaemon,dbus,radvd,tomcat,radiusd,news,mailman,nscd,gdm,polkituser
# These are common mappings for working with Active Directory.
nss_map_attribute uid sAMAccountName
nss_map_attribute uniqueMember member
nss_map_objectclass posixAccount user
nss_map_objectclass posixGroup group
nss_map_objectclass shadowAccount user
pam_login_attribute sAMAccountName
pam_member_attribute member
pam_password ad
pam_password_prohibit_message Please visit http://password.example.com to change your password.
pam_filter objectclass=User
The use_sasl on
directive configures nss_ldap
to use the Kerberos credentials
for the current user when looking up user/group/etc information. The
rootuse_sasl on
attribute does the same thing for processes running as root
.
Note that this configuration sets scope one
, which means that nss_ldap
will
not recurse down a directory tree. This is a performance optimization, not a
requirement.
As an unprivileged user⌗
Before acquiring Kerberos credentials:
$ getent passwd lars
(times out)
Authenticate to Kerberos:
$ kinit
Password for lars@EXAMPLE.COM:
With valid credentials:
$ getent passwd lars
lars:*:500:500:lars:\\emc00.example.com\staff\l\lars\windows:
As root⌗
Before acquiring Kerberos credentials:
# getent passwd lars
(times out)
Update credentials cache from system keytab:
# kinit -k
With valid credentials:
# getent passwd lars
lars:*:500:500:lars:\\emc00.example.com\staff\l\lars\windows:
This configuration makes the operation of nss_ldap
dependent on valid Kerberos
credentials. If a user remains logged in after her Kerberos credentials have
expired, she will experience degraded behavior, since many name lookup
operations will timeout. Similarly, local system accounts that do not have
valid Kerberos credentials will experience similar behavior (and will thus only
be able to see local users and groups).