h1

CentOS 6: Authenticate (AND sudo!) Active Directory users!

2013-06-05

Alright, my attempts over the previous years have all been dismal failures: Connect a Linux box to Active Directory.

In the grand scheme of things, the process itself is simple, and there are several ways to do it. In my case, I had specific requirements. Let me set the stage – a sprawling infrastructure of CentOS production servers with more being added regularly. A fast growing IT staff. Zero tolerance for inaccessibility due to domain controller availability, and therefore, one root login. If someone wipes a disk, we would never know who was at fault. In the end, these are the requirements:

  1. Single-sign on via Active Directory.
  2. Permit SSH & Local logon based on Active Directory group memberships.
  3. Authorize or deny ‘Sudo’ use via Active Directory group memberships.
  4. Allow both of the above to occur using cached credentials.

I fought with this for ages. The combination of my arguable Linux naivete and flagrant lack of LDAP knowledge played no small part. Here are the methods I tried, and the reasons I abandoned them:

  • AD Server for NIS: The prerequisite SSOD agent provided my Microsoft is poorly documented and impossible to get running on CentOS 6, and therefore is useless.
  • LDAP + Identity Services for Unix: This provided authentication well enough (and quite easily once you know what a BindDN is), but I gave up on the LDAP+SUDO portion due to horrible documentation when it came to AD. I discovered on my own that it involves manually creating AD objects through ADSI edit. I’m comfortable there, and I still couldn’t get it to work. In the end, no sudo = no go.
  • Centrify DirectManage Express: A free third-party offering. I was actually quite impressed with it’s analysis / auto-fix functions, and it’s simple method of integrating Linux hosts into AD, but again, no way of creating a SUDOer (at least that I could find), and it was really unwieldy in a non-segregated demo environment (where the domain SRV records aren’t available through DHCP-provided DNS servers).

The holy grail? Good ol’ WINBIND. That’s right, the one solution that I passed on from the get-go, was the best solution overall.

Here is the entirety of what I needed in order to link CentOS 6 boxes to, authenticate, AND authorize users against, Active Directory.

Active Directory:

  1. Create a user to bind against. I created a “_service.winbind” user in AD. I gave it a very strong password, member of Domain Admins (I also disallowed interactive logon to any computer, but that is not necessary).
  2. (Optional): Create a security group to contain users permitted to log into the Linux boxes (I used “Domain Admins“).
  3. (Optional): Create a security group to contain users permitted to SUDO on the Linux boxes (Can be the same as above. Again, I used “Domain Admins“).

The windows side is done. Seriously. No need to extend schema, Identity Services for Unix isn’t needed, no Kerberos keytabs to create. That was it.

CentOS 6:

  1. Ensure the server is able to communicate with the Domain Controller via its FQDN. If DHCP-provided DNS is insufficient, create an entry in /etc/hosts file. If you can ping the FQDN, you’re golden.
  2. Run the following command as root:
authconfig --update --kickstart --enablewinbind --enablewinbindauth --smbsecurity=ads --smbworkgroup=<DOMAIN NETBIOS> \
--smbrealm=<DOMAIN.SUFFIX> --smbservers=<DC FQDN> --winbindjoin=<BIND User> --winbindtemplatehomedir=/home/%U --winbindtemplateshell=/bin/bash \
--enablewinbindusedefaultdomain --enablelocauthorize
  1. Enter the password you configured for the BIND user when prompted. DNS related errors are OK, as long as it says that it successfully ‘Joined %HOSTNAME to domain’
  2. Check that the connection worked by running ‘wbinfo -u‘. A list of domain users should appear. A new computer account will also appear in the ‘Computers’ OU within Active Directory Users and Computers.
  3. Next, is to enable cached logon & set things up for sudo. Change the following lines in /etc/samba/smb.conf:
winbind offline logon = yes

# Then add the following beneath it:
idmap uid = 10000-20000
idmap gid = 10000-20000
winbind enum users = yes
winbind enum groups = yes
winbind separator = +
  1. Then, make the following changes in /etc/security/pam_winbind.conf – this wraps up the enablement of cached logons, authorizes access based on group access, and enables home directories.
cached_login = yes
require_membership_of = "logon group in all lowercase"
mkhomedir = yes
  1. Then edit the sudoers file via ‘visudo‘.  The line to add will look like this: (Replace ‘domain admins’ with your sudoer group. Don’t forget to escape spaces in the group name with a backslash! ‘\’)
%domain\ admins   ALL=(ALL)      ALL
  1. Finally, add the following as the LAST SESSION LINE in /etc/pam.d/sshd – this ensures that user home directories are created when they first log in.
session    required      /lib/security/pam_mkhomedir.so skel=/etc/skel umask=0022
  1. Restart the winbind service with ‘service winbind restart‘. That’s it, you’ve won!

To test that it works, try to SSH into the server using a domain-only username (‘ssh user.name@centosbox‘) and the associated password. If it let’s you in, try to sudo something (‘sudo ls‘). It probably won’t print anything since the current directory is the brand new user’s homedir, but if it completes without error, it succeeded!

PROBLEMS I RAN INTO:

Winbind likes to forget user groups on me. While logged in as a domain user, run the command ‘groups‘. If everything is in the clear, a list of all your Domain Group memberships will be displayed. If you’re like me, you may get an error after the first couple groups stating ‘Group XXXXXXXX could not be found’. In my case, that was Domain Admins. I haven’t found a solid solution yet, but restarting winbind (‘service winbind restart‘) and running random winbind commands (‘wbinfo -m‘; ‘wbinfo –own-domain‘; ‘wbinfo –online-status‘) usually fixes it. Because this caused problems with Sudo in my case (since my SUDOer specific group couldn’t be enumerated), I put the group id (as reported in the error) into the sudoers file in place of the group name (‘%\#16777217    ALL=(ALL)      ALL‘). The login group doesn’t seem to be affected by this problem.

Permission denied when you try to SSH? Watch the /var/log/secure and /var/log/messages log files for hints.

‘Not in the SUDOer file’? Run ‘visudo‘ and check the line you added. Did you escape your whitespace? Is the group name all lowercase (it should be!)? If you resorted to group ID, is it preceded by ‘\#’ (it should be!)?

A WORD TO THE WISE:

PLEASE, seriously, TEST cached credentials immediately, and test them on ALL SERVERS. Log in and sudo something while the DC is available, and then make sure it works when the DC can’t be contacted (unplug the cable on your CentOS box or something). It may take a while to log in since the winbind service has to time out first, BUT IT SHOULD STILL LET YOU IN. You DO NOT want to discover after a catastrophic network failure that you can’t log into your CentOS servers because they can’t find your DC. Also make sure that winbind is set to start automatically on boot. You could be in for a bad day otherwise.

9 comments

  1. Very good post. Very useful


  2. Hello, in your ad steps, these steps are the same, is this normal ?

    (Optional): Create a security group to contain users permitted to log into the Linux boxes (I used “Domain Admins“).
    (Optional): Create a security group to contain users permitted to log into the Linux boxes (Can be the same as above. Again, I used “Domain Admins“).


    • Thanks for the heads up. The second was supposed to say ‘permitted to SUDO on the Linux boxes’. I’ve corrected this and a few other typos I found.


  3. Have you discovered a permanent fix for the “Group XXXXXXXX could not be found” problem? I don’t mind adding a group id my sudoers file as you suggest but i’d much rather it work correctly and get the group name. In my case, the only group that doesn’t show up is the one i need. Seems a bit odd. Great post though. Very helpful.


    • Mattrk, if memory serves me correctly the issue was specific to the group that you require_membership_of. In other words, the group you require_membership_of will fail to enumerate the name. If you only plan to use a single group, you’ll need to use the group ID in SUDOers. If you use two seperate groups for ‘require_membership_of’ and SUDOers, you can use the name in the sudoers file.


      • Just an FYI, you were correct about the require_membership_of causing the issue. As a work around i created two groups. One for login and one for sudo. This resolved my problems.

        Also of interest, i just updated to CentOS 6.5 and this bug seems to have been resolved. I no longer receive the “Group xxxx could not be found” error. I have now reverted back to using the same group for login access and sudo access and everything works great. (Knock on wood)


  4. Great article! It is the only article thus far that has helped me! I’m now trying to use this on a CentOS 6.5 Minimal install, with only “Base” group installed. Commands like wbinfo don’t work for me. Could you please list the required packages? Appreciate it 🙂


    • Please correct me if I’m wrong, I think I figured out the appropriate packages, krb5-workstation and samba-common. I am hoping, however, you might be able to help: I am trying to join CentOS 6.5 to a Windows 2012 R2 RODC. I created the account in AD and let replication occur (I also made sure the computer account and the username I used to join the system was cached on the RODC). No matter what I do I get “Failed to set account flags for machine account: (NT_STATUS_NOT_SUPPORTED)”. However, “net ads testjoin -U rodcjoin” returns “Join was OK”. I’m not sure what else to do. Any advice?


      • Howdy, the simple response is that winbind likely requires a writable domain controller in order to properly join the machine. The ‘failed to set account flags’ being a strong indication. I would suggest trying it against a writable DC, and going from there.



Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: