Thursday, 23 February 2012

Join CentOS 6.2 server to a Windows 2008 Active Directory domain

Following on from my previous post detailing how to join a RHEL6 box to a Windows 2003 AD domain, in this post I discuss how to join to Windows 2008 AD domain (2008 Mode). This time rather than using RHEL 6, I've decided to use Centos 6.2 instead. I have used the standard installation rather than the minimal installation that used in the previous post, so here are the steps needed. 

Before I start though, I'd like to note that I installed the Identity Management for UNIX role in the Windows domain controller, so if you are following these instructions, make sure that you have that role installed in your domain controller. You will also need a binding account that has its Unix attributes set.

Without further ado, here are the instructions:
  1. Ensure that name resolution is working. At the very least you should be able to ping your domain controller, in my case If you can't, have a look at your /etc/resolv.conf file. Sample file:
  2. Depending on your installation type, you might have to install several of the packages below (It looks like I went for a base install only):
    yum install pam_krb5 pam_ldap nss-pam-ldapd samba policycoreutils-python -y
  3. Run authconfig-tui. Make sure that Kerberos realm is in capitals:

  4. Ensure that Name Service Switch is configured for ldap authentication. In essence, check that /etc/nsswitch.conf has the following values:
  5. passwd:     files ldap
    shadow:     files ldap
    group:      files ldap
  6. Edit the local LDAP name service daemon configuration (/etc/nslcd.conf). A bind account to the Active Directory is needed, so create that account now (I have created binding in the Users OU). The mappings (for Active Directory) need to be modified. Below is a list of changes to /etc/nslcd.conf. In essence uncomment the relevant parts:
  7. binddn cn=binding, cn=Users,dc=dev,dc=org
    bindpw mypass 
    #The Default search scope
    scope sub 
    #Customize certain database lookups
    base   group  dc=dev,dc=org
    base   passwd dc=dev,dc=org
    base   shadow dc=dev,dc=org
    # Mappings for Active Directory
    pagesize 1000
    referrals off
    filter passwd (&(objectClass=user)(!(objectClass=computer))(uidNumber=*)(unixHomeDirectory=*))
    map    passwd uid              sAMAccountName
    map    passwd homeDirectory    unixHomeDirectory
    map    passwd gecos            displayName
    filter shadow (&(objectClass=user)(!(objectClass=computer))(uidNumber=*)(unixHomeDirectory=*))
    map    shadow uid              sAMAccountName
    map    shadow shadowLastChange pwdLastSet
    map    shadow userPassword     unixUserPassword
    filter group  (objectClass=group)
    map    group  uniqueMember     member
  8. Change permissions on /etc/nslcd.conf file so that it is only readable by root:
    chmod 600 /etc/nslcd.conf
  9. Restart the local LDAP name service daemon:
    service nslcd restart
  10. Ensure that the local LDAP name service daemon (nslcd) is set to start with the server:
    chkconfig nslcd on
  11. Edit /etc/samba/smb.conf. Make sure that there is only a security directive active. Comment out all others.
  12. Network Related Options
    workgroup =dev
    Domain members options
    security = ads
    realm = DEV.COM
    use kerberos keytab = true  #not really sure about this one
    password server =
  13. Ensure that iptables lets traffic through on port 389:
  14. iptables –I INPUT –p tcp --dport ldap –j ACCEPT; service iptables save
  15. Run the following command to join the domain:
  16. net ads join –U domainadmin
  17. A DNS record was not created for this server in my DNS server, not sure why, which meant that I had to add the record myself manually. Thus ensure that you do this before moving on if the DNS record is not added automatically, otherwise you might be unable to login.
  18. At this point you have successfully joined to the AD domain, you can test this by getting a list of users or group. You should get back the users and/or groups that have linux attributes, at least the binding account.
    getent passwd
    getent group
  19. In order to create a user's home directory on first login add this directive to /etc/pam.d/sshd. I only log on using ssh. If you are logging in at the box, rather than remotely, you need to modify /etc/pam.d/logon too, I believe. Note that this will not work if SELinux is on.
    session required skel=/etc/skel umask=0022
  20. Allow polyinstatiation in SELinux settings:
     setsebool -P allow_polyinstantiation 1
  21. Temporarily set SELinux to permissive:
  22. setenforce 0
  23. If you login with a domain user (ssh binding@domainadtest, where domainadtest is the server that has just joined the domain), the directory will be created, but you will also have a record of what would've gone wrong on /var/log/audit/audit.conf had SElinux been on, which in my case is this:
  24. type=AVC msg=audit(1329063091.971:160): avc:  denied  { create } for  pid=5510 comm="mkhomedir_helpe" name="binding" scontext=unconfined_u:system_r:sshd_t:s0-s0:c0.c1023 tcontext=unconfined_u:object_r:home_root_t:s0 tclass=dir type=AVC msg=audit(1329063091.973:161): avc:  denied  { create } for  pid=5510 comm="mkhomedir_helpe" name=".bashrc" scontext=unconfined_u:system_r:sshd_t:s0-s0:c0.c1023 tcontext=unconfined_u:object_r:home_root_t:s0 tclass=file type=AVC msg=audit(1329063091.973:161): avc:  denied  { write open } for  pid=5510 comm="mkhomedir_helpe" name=".bashrc" dev=dm-0 ino=263825 scontext=unconfined_u:system_r:sshd_t:s0-s0:c0.c1023 tcontext=unconfined_u:object_r:home_root_t:s0 tclass=file type=AVC msg=audit(1329063091.973:162): avc:  denied  { setattr } for  pid=5510 comm="mkhomedir_helpe" name=".bashrc" dev=dm-0 ino=263825 scontext=unconfined_u:system_r:sshd_t:s0-s0:c0.c1023 tcontext=unconfined_u:object_r:home_root_t:s0 tclass=file type=AVC msg=audit(1329063092.015:163): avc:  denied  { setattr } for  pid=5510 comm="mkhomedir_helpe" name="binding" dev=dm-0 ino=263284 scontext=unconfined_u:system_r:sshd_t:s0-s0:c0.c1023 tcontext=unconfined_u:object_r:home_root_t:s0 tclass=dir
  25. Create a SELinux policy module to allow the creation of home directories when the user first logs in:
    less /var/log/audit/audit.log  | grep denied > mkdir.log 
    audit2why < mkdir.log 
    audit2allow -M mkdir -i mkdir.log 
    semodule -i mkdir.pp
  26. Renable SELinux:
    setenforce 1
That is it.

See this post to configure openSSH single sign on.


  1. I have followed all your steps and do seem to be able to join it but I have problems with retrieving users and groups, any ideas?

    1. There are number of things that could be the issue, but chances are that there is a typo on the /etc/nslcd.conf file. I've had that issue myself a couple of times.

      Check the secure log (/var/log/secure) to see if there are any clues there

  2. You need the following lines in /etc/samba/smb.conf

    kerberos method = dedicated keytab
    dedicated keytab file = /etc/krb5.keytab
    on RHEL6 or Centos6 systems. The newer version of samba used on those system versions changed some of the keywords.
    Once you are joined to the domain you can use the
    net ads keytab
    command to manipulate your system's kerberos tickets.

  3. Great write up!:) I finally managed to join my Centos server to the domain, however I'm not able to login as standard user, I'm getting Access Denied. When I do user look up with getnet passwd or group lookup getent group I don't get full list of domain users and groups. I can see i.e only Linux built-in groups and 4 other groups from my domain controller however I can't see groups listed in different OU i.e. OU=Groups,OU=MyCompany,OU=Company Subsidiaries,DC=domainname,DC=corp.