Recently I undertook the very daunting task of integrating a Red Hat Enterprise Linux 5 server in a Windows Server 2003 RC2 Active Directory environment.
As enterprise networks go, single sign-on between operating systems from all walks of life is sort-of a holy grail of achievement, and with good reason, it was by no means obvious or easy to make it happen! But with some determination, lots of Google searching, trial and error, and a desk to bang your head against, it is ultimately possible.
In Linux-land, those nifty GUI tools for doing this sort of thing are completely worthless. On the Windows side Microsoft isn't exactly the biggest help either. The web and various man pages are your only friends. I spent the better part of two weeks searching the web, reading documentation, ant attempting to follow in the footsteps of those that came before me.
You see, I wanted to make AD login happen on a Linux server, but I did not want to become an expert in Kerberos, LDAP, Windows Active Directory, or networking in general. Unfortunately, you're much better off if you are an expert. Linux does not forgive the weak or the naive. And AD login on Linux doesn't look like it will ever be as easy as integrating a Windows client on a Windows domain. That is to say, set your domain, enter the Administrator password, and you're good to go. No, no, no, that's far too easy. OK, enough whining, let's get on with it.
Here are the goals I set out with:
That's the synopsis, currently my integration of Linux in a Windows AD environment fulfills all of those requirements but the last, and with some further research and experimentation, I believe I can fulfill all of those requirements. Now a word of warning.
DISCLAIMER: I am not an Active Directory expert. Neither am I an expert on the various technologies that Linux uses to perform authentication. There may be flaws in my configurations. I MAY NOT BE ABLE TO ASSIST YOU WITH YOUR PARTICULAR CONFIGURATION. I CANNOT GUARANTEE SECURITY. PROCEED AT YOUR OWN RISK.
The following configuration is specific to my company's particular implementation of a Windows Server 2003 (RC2) domain running Active Directory. Your results may vary, God help you in your quest.
So, without further delay, here are the configuration instructions.
In order to configure Linux for AD authentication, you must configure PAM (Pluggable Authentication Modules), nsswitch (Name Service Switch), LDAP, Kerberos, Samba, and Winbind. I present two different methods of AD authentication simultaneously, that is to say authentication via LDAP, and authentication via Winbind. These instructions are based on personal experience with the help of the following online resources/blogs.
Again, my configuration is specific to Red Hat Enterprise Linux 5, certain bits may need to be tweaked for your particular distribution of Linux.
First up is LDAP. Make the following configuration changes to /etc/ldap.conf
In the LDAP configuration, the configuration is set for a domain called example.com. The domain controller has the host name dc.example.com. The domain controller is located at the IP address 192.168.1.10.
If your domain is called something.example.com, and your domain controller is called dc.something.example.com you'd change the configuration like so where only the domain is referenced: dc=something,dc=example,dc=com
Active Directory also does not allow anonymous queries. Each query made must be associated with a valid domain user. Therefore, you must create a new user in Active Directory for this purpose. In the example configuration, this user is adquery@EXAMPLE.COM, and the user's password is adquerypassword. This user should have no privileges, in fact you should make this user a member of Domain Guests.
The remainder of the file has to do with mapping Microsoft's Services for Unix (SFU) snapin to Linux user attributes. My configuration ultimately does not utilize SFU at all, though it could with some experimentation.
The configurations I present allow two different ways of authenticating a domain user, via LDAP and Kerberos, or via Winbind. The former configuration does not allow Linux SMB shares to mount on Windows clients, while the latter does, at least in this particular Windows AD domain.
In the preceding block you see the standard nsswitch.conf file that's shipping with Red Hat (and presumably Fedora and CentOS). This is the only important modification to make:
You're telling Linux to look at winbind as a source of authentication information, in addition to the Linux files /etc/passwd and /etc/group.
I could use the following configuration for LDAP, instead of Winbind. If only AD authentication is required (but no file shares), that would be the way to go. If going that method, you'll need that Microsoft Services for Unix snapin to be installed, and you'll have to configure the UID, GID, Home Directory, and Login Shell attributes for each domain user logging into Linux.
PAM is configured to use winbind for authentication in this example, if going the LDAP route, remove the "auth" and "account" blocks, and uncomment the corresponding "auth" and "account" lines containing references to krb5.
In the hosts configuration, you're doing two things. One, you're setting the Fully-Qualified Domain Name (FQDN) of the server or workstation, and two, you're hard-coding a DNS entry for the location of the domain controller. For good measure.
WARNING: The case of the domain names in krb5.conf is important. You will fail if this is not configured correctly.
At this point, you should be able to do a kerberos authentication. At the command line, cross your fingers and type the following:
# kinit user@EXAMPLE.COM
The above command obtains a new kerberos ticket. You do not have to be joined to the domain to obtain a kerberos ticket. Joining to the domain is necessary for mutual authentication, and is required for Linux SMB shares. Again, the case is important. The domain must be typed in all uppercase, or this command will fail. See if you have obtained a kerberos ticket by running the following command:
# klist
You should see a valid kerberos ticket.
Don't forget that the clock of the Linux client must be within the range allowed by the Windows server. Typically this is a skew of plus or minus five minutes. The best way to handle this is to set your clock to automatically synchronize to an NTP server, such as time.redhat.com.
If they are running, stop the smb and winbind services.
Now, configure /etc/samba/smb.conf.
Although I haven't tested it yet, I believe it is possible to use both winbind and Windows Services for Unix to generate Unix account attributes, UID, GID, login shell, and home directory. man smb.conf leads me to believe this is possible, but more tinkering is required. Additionally, smb.conf can be configured to store the winbind-generated attributes in an LDAP container, which is useful for synchronizing these attributes among multiple Linux clients.
Test the samba configuration.
# testparm /etc/samba/smb.conf
With regards to share definitions, group membership can be tested as criteria
valid users = @EXAMPLEweb
The above says that anyone in the group EXAMPLEweb is allowed access to the share.
Spaces in group names must be accounted for specially, just enclose the name in quotes.
valid users = @"EXAMPLEgroup name"
Now make sure that winbind and samba are set to start at boot, and that samba starts before winbind. Do this from the webmin console or the services console.
Now, start Winbind and Samba services, samba sbould be started first.
Obtain a kerberos ticket for the domain Administrator
# kinit Administrator@EXAMPLE.COM
Verify that you have a ticket.
# klist
Join the workstation to the domain.
# net ads join
Alternatively, you can also join using the following command, which supercedes the need to pull a kerberos ticket for the domain Administrator.
# net ads join -U Administrator
As I explained previously in the configuration for LDAP, Windows Server 2003 does not allow anonymous queries, so you'll have to assign winbind a domain user, again this domain user does not need any privileges, in fact it's better if it is a member of domain guests.
# wbinfo --set-auth-user adquery%adquerypassword
The modulus separates the username and password, for a more complex password that may have characters that have special meaning in the BASH terminal, enclose the password in single (or double) quotes.
# wbinfo --set-auth-user adquery%'adquerypassword'
In Active Directory, the user lookup should be a member of Domain Guests. Verify that you have set the user with the following
# wbinfo --get-auth-user
The above should print the username and password.
Verify that you are joined by testing the join
Now, test that you have domain users and groups available.
# wbinfo -u
The above should print every domain user as EXAMPLEuser.
# wbinfo -g
The above should print every domain group as EXAMPLEgroup.
Test that you have merged domain users and local users with the following.
# getent passwd
The same for groups
# getent group
Domain users should be appended to the results of each of those commands.
Test a login with a domain user account.
# ssh -l EXAMPLE\user localhost
If the above is successful, you should see "Directory created for user", and have a login by SSH.
Operations like chown and chgrp should now work with domain users. At the command line, and in most other operations, any user or group name containing spaces must be enclosed in quotations. Additionally, the backslash character must be escaped like you see above in the SSH login.
If you are not able to login via a domain user, or if getent passwd / getent group does not return domain users, it may be necessary to clear the winbind cache.
Delete the winbind cache.
For debugging, change the log level in smb.conf to 10, and look for the log for the client you are attempting to connect with in /var/log/samba. Logs are kept by netbios name and IP address.
Before attempting to connect to a Linux SMB share from a Window client, it may be necessary to logout and login on the client. It may also be necessary to wait a little time for propagation.
You may also find that the testparm /etc/samba/smb.conf command complains about the winbind separator. It's supposed to be a backslash by default. If this is a problem for you, you may want to change the separator to a plus sign instead. That change might look like this:
# net ads changetrustpw
The above changes the machine's kerberos password, and updates the samba-maintained Kerberos keytab. This hangs when I do it, so CTRL + C to cancel out of it.
Once done, you have logout and login to any machines you're using to test.
Test the join.
# net ads testjoin
Leave the domain.
# net ads leave
Print out the workgroup of the kerberos realm.
# net ads workgroup
Print out the workgroup of the kerberos realm.
Cleanup, before logging off the server run the following command:
# kdestroy
This will remove any active kerberos tickets, including any obtained for the domain Administrator.
The domain Administrator can be given root access to the Linux server by editing the /etc/sudoers file.
# visudo -f /etc/sudoers
Make the following modification around the "root" line.
I have not yet tested granting the domain administrator root privileges via sudo, so I'm not certain if that works.