Monday, August 10, 2009

Complete Linux-AD Authentication Details

Introduction

There are several articles posted here that discuss, in general terms, how to authenticate Linux against Active Directory.

With the introduction of Windows Server 2003 R2 and Windows Server 2008 Microsoft did a big step towards the Linux community - why? Active Directory LDAP schema is now much more RFC2307 friendly and so can directly contain Unix attributes (UID, GIDs,...) of users and groups. To apply for this benefit, system administrator is only required to install so-called Identity Management for Unix extension. Unix attributes of users and groups can be then directly edited in the Active Directory Users and Computers snap-in.

In this article we will use Samba to help us with Linux-AD authentication tasks.

Suggestions to use Samba in Linux-AD integration scenarios appeared in the comments for the following articles:

Linux, Active Directory, and Windows Server 2003 R2 Revisited
Kerberos-Based SSO with Apache

Samba could be used to help automate the process of creating the appropriate service principals in Active Directory (many similar articles use ktpass.exe and separate user accounts for each service principal - i.e., HOST/ or host/, HTTP/, etc. - this is quite tedious work which can be simplified greatly using Samba). Here’s what I found and the process that I used to successfully integrate the new Linux server into AD with the Samba tools:

1. Time synchronization

In this article we are going to use Windows-native authentication methods like Kerberos. Kerberos is well known to be picky about client-server synchronization so make sure you have your time in sync between Windows server and Linux client!

2. Samba configuration

  1. Next, Samba must be properly configured. I used the following settings in /etc/samba/smb.conf:
    workgroup = PRAGUE
    security = ads
    realm = PRAGUE.AD.S3GROUP.COM
    use kerberos keytab = true
    idmap domains = PRAGUE
    idmap config PRAGUE:schema_mode = rfc2307
    idmap config PRAGUE:backend = ad
    idmap config PRAGUE:readonly = yes
    winbind nss info = rfc2307
    winbind use default domain = yes

  2. If the DNS domain of your Linux server will be different than the DNS domain of the AD domain (for example, perhaps your Linux server will be web1.linux.corp.com whereas Active Directory uses ad.corp.com), then create a computer account in Active Directory. If the Linux server’s DNS domain will be the same as the DNS domain for AD, then we can have Samba create it for us. (I ran into problems here since the Linux server does use a different DNS domain than Active Directory, and pre-creating the computer account was the only way to make it work.)
  3. Run net ads join to join the Linux server to Active Directory. As part of this process, it will add various SPNs to the computer account in Active Directory automatically and create the appropriate entries in the local Kerberos keytab (/etc/krb5.keytab, by default)

3. Configure Name Services Switch

Contrary to many other articles we will not use the nss_ldap client but will use winbindd (part of the Samba package) instead. Why? ldap_client is a library, not a daemon so it runs in the user context. That is why we can not use the Kerberos machine credentials (which Samba kindly provided) to contact AD - we would have to define some proxy user instead. Winbind is a daemon running as root so it has access to the machine credentials -> the whole configuration is a lot easier (see the 1 extra configuration line above).

Note that winbind can only take care of these two databases - everything else must be handled by nss_ldap.so NSS library (ok automounter is an exception here, we will cover autofs later...) - but these two are the most important anyway...:
[root@dorado_v1 ondrejv]# cat /etc/nsswitch.conf
passwd: files winbind
shadow: files winbind
group: files winbind

#hosts: db files nisplus nis dns
hosts: files dns
automount: files ldap
When winbindd is correctly configured, you should be able to do a wbinfo -u and wbinfo -i get back a list of user properties for that username. You might also use the wbinfo tool to debug winbind errors. Unfortunately winbind is quite hard to debug as it employs caching (which survive daemon restarts and even machine reboots - and there is no simple way to force cache flush - are you listening, Samba developers? :-) ). To flush winbind cache you might try deleting files in /var/cache/samba/winbind* - but in many cases you just need to wait for the cache to refresh.

Note:

Usual debugging commands like gentent passwd and getent group do not work by default with winbind as enumeration those needs to be enabled explicitely

4. Configure PAM for Kerberos authentication

Use the system-config-authentication tool (available in RHEL and CentOs) to and configure PAM for Kerberos - the result should look like this:

[root@dorado_v1 ondrejv]# cat /etc/pam.d/system-auth
#%PAM-1.0
# This file is auto-generated.
# User changes will be destroyed the next time authconfig is run.
auth required pam_env.so
auth sufficient pam_unix.so nullok try_first_pass
auth requisite pam_succeed_if.so uid >= 500 quiet
auth sufficient pam_krb5.so use_first_pass
auth required pam_deny.so

account required pam_unix.so broken_shadow
account sufficient pam_succeed_if.so uid < 500 quiet
account [default=bad success=ok user_unknown=ignore] pam_krb5.so
account required pam_permit.so

password requisite pam_cracklib.so try_first_pass retry=3
password sufficient pam_unix.so md5 shadow nis nullok try_first_pass use_authtok
password sufficient pam_krb5.so use_authtok
password required pam_deny.so

session optional pam_keyinit.so revoke
session required pam_limits.so
session [success=1 default=ignore] pam_succeed_if.so service in crond quiet use_uid
session required pam_unix.so
session optional pam_krb5.so

Use the same tool to configure the Kerberos library (/etc/krb5.conf) - Samba can not do this for us, unfortunately. Here is my minimal configuration:
[libdefaults]
default_realm = PRAGUE.AD.S3GROUP.COM
default_tgs_enctypes = arcfour-hmac-md5 des-cbc-md5 des-cbc-crc
default_tkt_enctypes = arcfour-hmac-md5 des-cbc-md5 des-cbc-crc
permitted_enctypes = arcfour-hmac-md5 des-cbc-md5 des-cbc-crc arcfour-hmac-exp
dns_lookup_realm = true
dns_lookup_kdc = true
passwd_check_s_address = false
use_tcp_only = true
ccache_type = 3
forwardable = true
[domain_realm]
.prague.ad.s3group.com = PRAGUE.AD.S3GROUP.COM
.prague.s3group.com = PRAGUE.AD.S3GROUP.COM
prague.ad.s3group.com = PRAGUE.AD.S3GROUP.COM
prague.s3group.com = PRAGUE.AD.S3GROUP.COM
[realms]

It is important, that this configuration is consistent across your LAN computers otherwise you might experience some strange Kerberos errors. As you can see, there is no configuration in the [realms] section - it is not needed as the Kerberos library will use DNS SRV records to locate KDC (AD domain controllers). Also note the forwardable = true flag - it instructs pam_krb5 module to create forwardable TGT tickets (important for SSH single sign on)

Note:


This setup works, but unfortunately still not everything works just perfectly - for example if your password expired, you are asked to change it - and if you attempt to change it to something which does not fulfill enforced AD policies (like attempt to re-use old password or not complex enough password), you are kicked out without a word of explanation....

I used this process to integrate a new CentOS 5.3 server into Active Directory (Windows 2008 server based) without any problems whatsoever.

2 comments:

  1. Hi Ondrej.

    I followed your article and it worked wonderfully. However one tweak was necessary to make this work flawlessly.

    winbind use default domain = yes inside smb.conf

    Without that winbind was not working for some reason. Added that, and it's working perfectly.

    Thanks for the writeup!

    -Terry

    ReplyDelete
  2. Hi Bezerker,

    Yes I know about that option - it would work without it too, but you would have to add your domain name when logging in (i.e. something like PRAGUE\ondrejv instead of just ondrejv). But thanks for this note!
    Ondrej

    ReplyDelete