Authenticating Linux users by Windows AD has become popular in many organizations for the convenience of centralized account management. It makes sense, if you need existing Windows account to login to Linux servers, but it doesn’t make sense to install a new Windows AD for the sole purpose of authenticating Linux users, just because Windows has a nice GUI. Redhat Directory Server/Centos Directory Server/389 Directory Server all are capable of doing such task beautifully by ldap+StartTLS or ldap+Kerberos.
At least, there are 4 ways to authenticate Linux users by Windows AD:
1. Linux Clients use Linux LDAP server synchronized with Windows AD.
Replicate a subtree of Windows AD accounts to Linux Ldap Server (Redhat Directory Server/Centos Directory Server/389 Directory Server), Linux users authenticate against the Linux LDAP Server either by Ldap+StartTLS or Ldap+Kerberos
A more complex approach, it is for those who don’t like a Windows AD sitting in datacenter.
2. Linux Client use LDAP or LDAP+SSL(ldaps) or LDAP+StartTLS
User information store: LDAP
Authentication: LDAP or LDAP+SSL(ldaps) or LDAP+StartTLS
Limitation: Client can login but can’t change its password
3. Linux Client use ldap+Kerberos
User information store: LDAP
Authentication: Kerberos
The most popular approach, work out of the box, no need to install additional software. User can change its password.
A vbscript to add unix user to windows AD.
http://honglus.blogspot.com/2009/04/add-unix-user-to-windows-ad-by-vbscript.html
4. Linux Client use samba Winbind
User information store: Winbind local file or winbind ldap
Authentication: Winbind
Cons to solution #3 ldap+Kerberos approach:
- /etc/init.d/windbind dameon need to be running
- The Linux client has to be joined to the domain, it is showed in computers container.
- The UID/GID is derived from Windows SID(ID = RID - BASE_RID + LOW RANGE ID, "man 8 idmap_rid"), you don’t seem to have a choice to set to a specific number.
Pros to solution #3 ldap+Kerberos approach:
- No need to insall Service for Unix in Windows
This post demonstrate method #3 ldap+kerberos and #4 Winbind.
Linux OS: Centos 5.5
Windows OS: Window 2003
FQDN: server1.ad.example.com
Domainname/Realm: ad.example.com
Linux Clients use ldap+Kerberos
Setup Windows Server
- Install “Windows Services for UNIX Version 3.5” for Windows 2003
Windows 2003 R2 or Windows 2008 has built-in component “Server for NIS Service”
- Create a generic user account for Linux nss-ldap client to run ldap query with the credentials.
e.g username=Linux-bind-user password=Redhat123
- Create a test group, go to “Unix Attribute tab” to set GID etc
- Create a test user, go to “Unix Attribute tab”, to set uid/homedir/shell/gid etc
- Modify default domain security group policy to allow users change password immediately, by default it is 1 day, change it to 0 day.
Set up Linux client
#make sure the following pkgs are installed
krb5-workstation
openldap-clients
nss_ldap
pam_krb5
#Edit configuration files: /etc/nsswitch.conf; /etc/ldap.conf; /etc/krb5.conf; /etc/pam.d/system-auth
#The easiest way is to run authconfig-tui.
#Before run the command, empty config files for easy reading
$cat /dev/null >/etc/ldap.conf ; cat /dev/null > /etc/krb5.conf
$authconfig-tui #select use ldap for “User information” and “use md5 passwords, use shadow passwords, use Kerberos,local authorization is sufficient” for authentication.
$cat /etc/ldap.conf
uri ldap://server1.ad.example.com/
base cn=Users,dc=ad,dc=example,dc=com
ssl no
binddn cn=linux-bind-user,cn=users,dc=ad,dc=example,dc=com
bindpw Redhat123
##Map Unix account attributes to Winnows SFU 3.5 attributes
##NOTE: Windows 2003 R2/Windows 2008 use different name
##In either scheme, the attribute can be retrieved by ldapsearch command
#$ldapsearch –x –W –b ”cn=Users,dc=ad,dc=example,dc=com” –D “cn=linux-bind-user,cn=users,dc=ad,dc=example,dc=com”
#....
#msSFU30Name: jsmith
#msSFU30UidNumber: 10001
#...
nss_map_objectclass posixAccount User
nss_map_objectclass shadowAccount User
nss_map_objectclass posixGroup Group
nss_map_attribute uid sAMAccountName
nss_map_attribute uidNumber msSFU30uidNumber
nss_map_attribute gidNumber msSFU30gidNumber
nss_map_attribute gecos name
nss_map_attribute homeDirectory msSFU30HomeDirectory
nss_map_attribute loginShell msSFU30loginShell
pam_login_attribute sAMAccountName
pam_filter objectclass=User
nss_base_password cn=Users,dc=ad,dc=example,dc=com
nss_base_shadow cn=Users,dc=ad,dc=example,dc=com
nss_base_group cn=Users,dc=ad,dc=example,dc=com
pam_password ad
#Optional, "referrals yes" try to connect both ldap://server1.ad.example.com and ldap://ad.example.com
referrals no
$cat /etc/krb5.conf
##[logging] section is not needed, I think, it is for KDC daemon running locally only
[libdefaults]
default_realm = AD.EXAMPLE.COM #realm name MUST be in capitals
dns_lookup_realm = false
dns_lookup_kdc = false
[realms]
AD.EXAMPLE.COM = {
kdc = server1.ad.example.com
admin_server = server1.ad.example.com
}
##domain to realm mapping is also optional for user login, it is for the host added to KDC as principal to provide service
[domain_realm]
.example.com = AD.EXAMPLE.COM
example.com = AD.EXAMPLE.COM
#nsswitch.conf system-auth don’t need to be further customization after “authconfig-tui” is run, just post them for reference
$cat /etc/nsswitch.conf
passwd: files ldap
shadow: files ldap
group: files ldap
$grep krb5 /etc/pam.d/system-auth
auth sufficient pam_krb5.so use_first_pass
account [default=bad success=ok user_unknown=ignore] pam_krb5.so
password sufficient pam_krb5.so use_authtok
session optional pam_krb5.so
Test LDAP+Kerberos
#Query LDAP user information or run getent password|shadow|group to list all
$id jsmith
uid=10001(jsmith) gid=10000(unix-test-group) groups=10000(unix-test-group)
Troubleshooting
Error:
pam_krb5[5330]: password change failed for jsmith@AD.EXAMPLE.COM: Password change rejected, Password change rejected
Solution:
test changing password in Windows GUI, Make sure the password meet password complexity policy and minimum change day is 0
Error:
Authentication failure (Cannot find KDC for requested realm)
$ kinit
kinit(v5): Cannot find KDC for requested realm while getting initial credentials
Solution:
check the relam spelling is correct and all in UPPER case, e.g AD.EXAMPLE.COM
ERROR:
Authentication failure (Clock skew too great)
Solution:
synchronize datetime with AD and enable ntpd
$ntpdate -s server1.ad.example.com
Enable DEBUG:
$cat /etc/ldap.conf
debug 7
Linux Clients use samba Winbind
#Windows required software
Windows Services for UNIX is not needed
#Linux required software
samba-client
samba-common
krb5-workstation
#Clear /etc/ldap.conf and /etc/krb5.conf in last test
$cat /dev/null >/etc/ldap.conf; $cat /dev/null >/etc/krb5.conf;
$authconfig-tui
#select use winbind for “User information” and “use md5 passwords, use shadow passwords, use winbind,local authorization is sufficient” for authentication.
#supply following information and type in "domain admin"'s username password to join domain
$cat /etc/samba/smb.conf
[global]
#--authconfig--start-line--
workgroup = AD
password server = server1.ad.example.com
realm = AD.EXAMPLE.COM
security = ads
idmap uid = 16777216-33554431
idmap gid = 16777216-33554431
template shell = /bin/bash
winbind offline logon = false
##above lines are generated by authconfig-tui
##following 3 parameters need mannual customization
winbind use default domain = true
winbind enum users = yes
winbind enum groups = yes
#--authconfig--end-line--
##Other files don't need further customization, just paste here for reference
$cat /etc/krb5.conf
[libdefaults]
default_realm = AD.EXAMPLE.COM
dns_lookup_realm = false
dns_lookup_kdc = false
[realms]
AD.EXAMPLE.COM = {
kdc = server1.ad.example.com
}
$grep winbind /etc/pam.d/system-auth
auth sufficient pam_winbind.so use_first_pass
account [default=bad success=ok user_unknown=ignore] pam_winbind.so
password sufficient pam_winbind.so use_authtok
$grep winbind /etc/nsswitch.conf
passwd: files winbind
shadow: files winbind
group: files winbind
Test winbind
$wbinfo -u
jsmith
$gettent passwd
jsmith:*:16777216:16777216:John smith:/home/AD/jsmith:/bin/bash
##Group membership is added by opening the group, then click add member button in Windows GUI
$id jsmith
uid=16777216(jsmith) gid=16777216(domain users) groups=16777216(domain users),16777225(unix-test-group)