Authentication against Active Directory
Unix servers use the PAM protocol for authentication. This can be configured for local user accounts and passwords or for accessing networked directories like Microsoft Active Directory or LDAP.
LDAP provides a single store for all user information in Microsoft Active Directory (AD) and avoids the replication of such details, and in particular passwords, in more than one place. The Kerberos protocol is used for password management. Using LDAP and Kerberos for authentication against AD is strongly recommended on sites with multiple KCML application servers.
Most PAM based LDAP authenticators will require the use of the standard RFC2307 schema when used to authenticate against an LDAP server such as AD. The default AD schema lacks crucial attributes needed by PAM but Microsoft provide the Windows Services for Unix (SFU) product to extend the schema to bridge this gap. SFU ships with Windows 2003R2 (though it is still an option that needs to be explicitly installed) and is available as a free download for earlier versions of AD. This article assumes you are using Windows 2003R2 with the RFC2307 schema enabled or have installed SFU3.5 on an earlier version of Windows but if you cannot do so then there is still a way to use pure LDAP, with some restrictions, documented here.
Network considerations
Kerberos uses ports tcp/88, tcp/749 and udp/464. LDAP uses tcp/389 and tcp/636.
On the Active Directory server
On at least one DC install the "Server for NIS" option to add the "Unix Attributes" tab to the Users and Groups properties.
Using the AD Management tool make sure there is an Organisational Unit called Groups at the same level as Users under the domain, creating it if necessary. Add a group representing the KCML users and allocate it a GID in the Unix Attributes tab. The tool will autoallocate GIDs in the 10000+ range.
When you add or modify the KCML users you can set UID, GID, default shell and home directory attributes with the new tab. AD should autoallocate unique UIDs starting at 10000. They must not be less than 500. Put the KCML users into the group created earlier so they share a common GID and a home directory which you should create in advance and chgrp to the common GID. The choice of shell is immaterial. All other AD users should not have Unix attributes set thus denying them access to the Unix systems.
Again using the AD Management tool create a special proxy user adbrowse in the Users object container with read-only access for use by PAM to access Users and Groups. On Win2003R2 the Unix attributes are visible by default but if using Windows 2000 AD and SFU 3.5 then the extra Unix attributes will not be readable by the user by default and must be made so with AD management console thus:
For each Unix server create a user account (not a computer account) for use by the Kerberos service accessing that computer. At the command prompt type:
ktpass -princ host/fqdn@REALM -mapuser account -crypto DES-CBC-MD5 +DesOnly -pass password -ptype KRB5_NT_PRINCIPAL -out filename.keytab
where fqdn is the name of the Unix server with its fully qualified domain name, e.g. apps1.adpdsi.com, REALM is the uppercase Kerberos realm for the AD server, e.g. ADPDSI.COM, password is the password set for the new computer account and filename.keytab is the filename of the keytab that will be generated. Then securely copy the keytab file to the Unix server and rename it /etc/krb5.keytab. It should be publicly readable but writeable only by root. You can check that it installed properly by using klist -k as root
With a Windows 2003R2 AD you can avoid the ktpass step and join the computer to the domain automatically using Samba. See Scott Lowe's article.
On the application servers
On each application server
+-------------¦ Authentication Configuration +-------------+ ¦ ¦ ¦ User Information Authentication ¦ ¦ [*] Cache Information [*] Use MD5 Passwords ¦ ¦ [ ] Use Hesiod [*] Use Shadow Passwords ¦ ¦ [*] Use LDAP [ ] Use LDAP Authentication ¦ ¦ [ ] Use NIS [*] Use Kerberos ¦ ¦ [ ] Use Winbind [ ] Use SMB Authentication ¦ ¦ [ ] Use Winbind Authentication ¦ ¦ ¦ ¦ +--------+ +------+ ¦ ¦ ¦ Cancel ¦ ¦ Next ¦ ¦ ¦ +--------+ +------+ ¦ ¦ ¦ ¦ ¦ +----------------------------------------------------------+
On clicking Next it will ask for details of the LDAP server. Enter the IP address of the AD server and fill in the base DN for accessing Users, usually just the domain DN, e.g.
+-----------------¦ LDAP Settings +-----------------+ ¦ ¦ ¦ [ ] Use TLS ¦ ¦ Server: 10.10.10.10_____________________________ ¦ ¦ Base DN: dc=adpdsi,dc=local______________________ ¦ ¦ ¦ ¦ +------+ +------+ ¦ ¦ ¦ Back ¦ ¦ Next ¦ ¦ ¦ +------+ +------+ ¦ ¦ ¦ ¦ ¦ +---------------------------------------------------+
It will then prompt for Kerberos settings. The KDC and Admin server should be set to the host names of the AD server.
+-----------------¦ Kerberos Settings +------------------+ ¦ ¦ ¦ Realm: ADPDSI.COM______________________________ ¦ ¦ KDC: kerberos.adpdsi.com:88__________________ ¦ ¦ Admin Server: kerberos.adpdsi.com:749_________________ ¦ ¦ [ ] Use DNS to resolve hosts to realms ¦ ¦ [ ] Use DNS to locate KDCs for realms ¦ ¦ ¦ ¦ +------+ +----+ ¦ ¦ ¦ Back ¦ ¦ Ok ¦ ¦ ¦ +------+ +----+ ¦ ¦ ¦ ¦ ¦ +--------------------------------------------------------+
The Redhat authconfig tool will write many of the configuration files for you. However check they are consistent with these
Ensure the Unix Kerberos configuration file /etc/krb5.conf looks something like this (shown for a REALM of ADPDSI.COM and a dns domain of adpdsi.com. The AD KDC is host.adpdsi.com. This must be resolvable from the Unix servers.
[logging] default = FILE:/var/log/krb5libs.log kdc = FILE:/var/log/krb5kdc.log admin_server = FILE:/var/log/kadmind.log [libdefaults] default_realm = ADPDSI.COM dns_lookup_realm = false dns_lookup_kdc = false [realms] ADPDSI.COM = { kdc = host.adpdsi.com:88 admin_server = host.adpdsi.com:749 default_domain = adpdsi.com } [domain_realm] .adpdsi.com = ADPDSI.COM adpdsi.com = ADPDSI.COM [kdc] profile = /var/kerberos/krb5kdc/kdc.conf [appdefaults] pam = { debug = false ticket_lifetime = 36000 renew_lifetime = 36000 forwardable = true krb4_convert = false }
Ensure the LDAP configuration file /etc/ldap.conf looks something like this. Replace the IP 10.10.10.10 with the IP address of the AD server and set the binddn and bindpw attributes to the user and password we set up for read-only access to the directory.
host 10.10.10.10 base dc=adpdsi,dc=com # browse user/password binddn cn=adbrowse,cn=Users,dc=adpdsi,dc=com bindpw secret #use this to limit access to members of a particular group #pam_groupdn cn=k8users,ou=Groups,dc=adpdsi,dc=com scope sub ssl no pam_password md5 # map directory attributes to NIS names nss_map_objectclass posixAccount user nss_map_objectclass shadowAccount user nss_map_objectclass posixGroup group # use these mappings for Win2000/Win2003R1 and SFU 3.5 nss_base_passwd dc=adpdsi,dc=com nss_base_shadow dc=adpdsi,dc=com nss_base_group dc=adpdsi,dc=com nss_map_attribute uid sAMAccountName nss_map_attribute uidNumber msSFU30UidNumber nss_map_attribute gidNumber msSFU30GidNumber nss_map_attribute loginShell msSFU30LoginShell nss_map_attribute gecos name nss_map_attribute userPassword msSFU30Password nss_map_attribute homeDirectory msSFU30HomeDirectory nss_map_attribute uniqueMember msSFU30PosixMember nss_map_attribute cn cn # use these RFC2307 mappings for Win2003R2 #nss_base_passwd dc=adpdsi,dc=com?sub #nss_base_shadow dc=adpdsi,dc=com?sub #nss_base_group dc=adpdsi,dc=com?sub?&(objectCategory=group)(gidnumber=*) #nss_map_attribute gecos cn #nss_map_attribute homeDirectory unixHomeDirectory #nss_map_attribute uniqueMember member
In the /etc/nsswitch.conf file ensure that these three attributes have these values so that lookups on users will first check the local files then use LDAP.
passwd: files ldap shadow: files ldap group: files ldap
In Redhat Linux a common PAM configuration file, /etc/pam.d/system-auth, is written by the authconfig tool and referenced by most PAM configurations, in particular the one used by the KCML connection manager (either kcc or kcml, connection manager gets the name of the PAM configuration file from the service name used to start it in xinetd). The system-auth file should look something like this:
auth required /lib/security/$ISA/pam_env.so auth sufficient /lib/security/$ISA/pam_unix.so likeauth nullok debug auth sufficient /lib/security/$ISA/pam_krb5.so use_first_pass debug auth required /lib/security/$ISA/pam_deny.so account required /lib/security/$ISA/pam_unix.so broken_shadow debug account sufficient /lib/security/$ISA/pam_succeed_if.so uid < 100 quiet account [default=bad success=ok user_unknown=ignore] /lib/security/$ISA/pam_krb5.so debug account required /lib/security/$ISA/pam_permit.so password requisite /lib/security/$ISA/pam_cracklib.so retry=3 password sufficient /lib/security/$ISA/pam_unix.so nullok use_authtok md5 shadow password sufficient /lib/security/$ISA/pam_krb5.so use_authtok password required /lib/security/$ISA/pam_deny.so session required /lib/security/$ISA/pam_limits.so session required /lib/security/$ISA/pam_unix.so session optional /lib/security/$ISA/pam_krb5.so
To verify this setup use kinit to get a Kerberos ticket for a user in the AD e.g.
$ kinit TestUser Password for [email protected]: $ klist Ticket cache: FILE:/tmp/krb5cc_0 Default principal: [email protected] Valid starting Expires Service principal 04/03/08 16:32:38 04/04/08 02:32:49 krbtgt/[email protected] renew until 04/04/08 16:32:38 Kerberos 4 ticket cache: /tmp/tkt0 klist: You have no tickets cached $ kdestroy $
Check the user is visible over LDAP
$ getent passwd TestUser TestUser:ABCD!efgh12345$67890:10001:500:TestUser:/home/TestUser:/bin/sh $
Some versions of getent may not support (and ignore) filtering by user in which case just use getent passwd for them all. As a final check that NSS is working create a temporary file, have it owned by the uid and gid of a network user, and make sure that ls can resolve that user and group e.g.
$ >/tmp/a $ chown 10001 /tmp/a $ chgrp 5000 /tmp/a $ ls -l /tmp/a -rw-rw-rw- 1 TestUser kccUser 0 Mar 20 12:06 /tmp/a $
Now you should be able to use connection manager to connect to KCML. Check /var/log/messages and /var/log/secure in case of problems.
Single sign on with Active Directory
Using PAM still requires the user to enter a userid and password in the client. It is possible, if the client Windows PC is logged into the AD domain, to have the client use the Windows logon credentials to authenticate and thus avoid the need for a password prompt. This mechanism does not support the LDAP lookup of the users details so the user must exist in the Unix server /etc/password or NIS database in order to be identified on the server.
Configuration for SSO requires that the server be configured for Kerberos v5 as above. You can use the same computer account in AD. Ideally there should be a keytab entry for a HTTP service rather than a host service but reusing an existing host service created for PAM will work too.
ktpass -princ HTTP/fqdn@REALM -mapuser account -crypto DES-CBC-MD5 +DesOnly -pass password -ptype KRB5_NT_PRINCIPAL -out filename.keytab
Install this keytab on the server and verify that it is visible to kerberos using klist -k while running as root.
Connection manager on the server will need to be configured for SSO by adding the -g switch to its command line. This switch is followed by the principal name exactly as entered for the -princ argument to ktpass. e.g. in /etc/inetd.conf
kcml stream tcp nowait root /usr/local/kcml/kwebserv /usr/local/kcml/kwebserv -g HTTP/[email protected]
Remember to restart inetd. When running this way the connection manager will accept only Kerberos or NTLM SSO connections. To avoid fallback to the insecure NTLM protocol use -G rather than -g to force the use of Kerberos.
See Also:
Authentication in the Connection Manager
LDAP authentication
Configuring PAM
Scott Lowe's excellent How-To article for Win2003R2
Scott Lowe's other How-To article for Win2000 and Win2003R1
Scott Lowe's article on SSO over HTTP