Linux + Active Directory.. SSO bliss

As an IT consultant, sometime you run into situations that you need to compromise, Do I really need to buy another windows license to have a file server? I run linux, do I have to use windows in order to leverage Active Directory.The answer to these questions is no, we don't need to use windows in order to have a file server / software repository / any other service we can think of, and link to Active Directory. By using Kerberos and LDAP we can have a single sign on environment with Active directory through linux servers.

Warning

Before I get into the big details on how to do this, I just want to mention that this configuration has no guarauntee, and is given  AS IS. You SHOULD BACKUP FIRST before modifying anything on your systems. And I can't be held responsible if something happens to your system during the configuration.

My setup

This was done using CentOS 5.5 with a Windows server 2008 R2 Active Directory Schema

Making sure AD is ready

Before messing with linux, there is one prerequisite that needs to be installed with AD, and this requires a reboot. That is UNIX for active directory. This is an extension to the active directory attributes by adding such things as the UID, GID, shell location, and home folder. In Windows Server 2008R2, in Server Manager, simply right click on the role "Active Directory Domain Services" and select "Add Role Services".

adlinux1

adlinux1

Select Identity Management for UNIX and all its sub components.

adlinux2

adlinux2

Once the install is done, simply reboot the server

adlinux3

adlinux3

Once installation is finished, you should have a UNIX tab when going into a user or group's properties:

adlinux5

adlinux5

There is one more configuration that we are going to need to do to test Single Sign On (SSO) with Linux, We need to configure a user with the UNIX properties in Active Directory. The NIS server already has configured itself to use the NETBIOS name of your domain. In my example, I modified administrator with a UID 10000, set my environment varialbe to /bin/bash and specified a basic home folder in linux along with a group.

adlinux4

adlinux4

(Note: It is good to use a User ID that is 10,000 and bigger, this will remove conflicts with other user account in Linux)

Also before we go to linux, its good that we create a user that linux can use to browse AD

HERE COMES LINUX

So with AD ready to go, lets login to our Linux machine. Make sure that your DNS configuration is set on the linux server. Joining an AD server without DNS doesn't really work great. Modify /etc/resolv.conf to have this:

nameserver x.x.x.x

nameserver x.x.x.x

There are 4 Configuration Files that need to be modified, krb5.conf, nsswitch.conf. ldap.conf and system-auth. Best thing to do right now, is setup a second connection to the linux box ( either by SSH, or by pressing CTRL + ALT + F2).

The reason to have a second connection is that we are tinkering with how linux accepts authentication, and a mis-configuration in certain files (namely system-auth) can cause issues for even root to logon.

Also, lets backup the configurations before we modify them. I like to create a nice /backupconfig folder at the root and copy all the configs there

mkdir /backupconfig

cp /etc/krb5.conf /backupconfig

cp /etc/nsswitch.conf /backupconfig

cp /etc/ldap.conf /backupconfig

cp /etc.pam.d/system-auth /backupconfig

Got that? Great!

First lets modify krb5.conf. In the following configuration, I'm configuring these files with the domain test.local, that has a Domain Controller called DC.test.local. So now with either vi or, my personal favorite "nano"

nano /etc/krb5.conf

[logging]
default = FILE:/var/log/krb5libs.log
kdc = FILE:/var/log/krb5kdc.log
admin_server = FILE:/var/log/kadmind.log

[libdefaults]
default_realm = TEST.LOCAL
dns_lookup_realm = true
dns_lookup_kdc = true

[realms]
TEST.LOCAL = {
kdc = dc.test.local:88
admin_server = dc.test.local:749
default_domain = test.local
}

[domain_realm]
.test.local = TEST.LOCAL
test.local = TEST.LOCAL

[kdc]
profile = /var/kerberos/krb5kdc/kdc.conf

[appdefaults]
pam = {
debug = false
ticket_lifetime = 36000
renew_lifetime = 36000
forwardable = true
krb4_convert = false
}

It is very VERY important that we respect Captialization, otherwise things just dont work.

So as you can tell, this is the configuration for kerberos. We are telling linux that TEST.LOCAL is our default domain, and in order to talk to TEST.LOCAL, use dc.test.local. We also said that they can use DNS to look up dc.test.local.

Also, if anyone uses test.local for authentication, please use TEST.LOCAL instead.

In appdefaults, we tell pam (the authentication module in linux) to not debug, don't convert this information to Kerberos version 4, and you can forward the information. and the kerberos ticket is good for 36000 seconds (10 hours)

Once that is done, lets work our way to /etc/ldap.conf. What I would do is erase everything in ldap.conf, and rewrite a nice fresh clean config like so:

nano /etc/ldap.conf

base dc=test,dc=local
uri ldap://dc.test.local/
binddn unixjoin@test.local
bindpw password
scope sub
ssl no
nss_base_passwd dc=test,dc=local?sub
nss_base_shadow dc=test,dc=local?sub
nss_base_group dc=test,dc=local?sub?&(objectCategory=group)(gidnumber=*)
nss_map_objectclass posixAccount user
nss_map_objectclass shadowAccount user
nss_map_objectclass posixGroup group
nss_map_attribute gecos cn
nss_map_attribute homeDirectory unixHomeDirectory
nss_map_attribute uniqueMember member
tls_cacertdir /etc/openldap/cacerts
pam_password md5

What ldap.conf does is setting linux authentication parameters, like "passwd", "shadow", and "group" to a base within active directory using LDAP queries. Then it maps certain attributes from linux to Active directory, for example, the object "homeDirectory" in linux will be mapped to "unixHomeDirectory" in Active Directory.

Ok, half way done. Now we need to tell linux the methods that we are going to authenticate, much like the host.conf file says in which order hostname resolution will work.

nano /etc/nsswitch.conf

passwd: files ldap
shadow: files ldap group: files ldap

#hosts: db files nisplus nis dns hosts: files dns

# Example - obey only what nisplus tells us...
#services: nisplus [NOTFOUND=return] files
#networks: nisplus [NOTFOUND=return] files
#protocols: nisplus [NOTFOUND=return] files
#rpc: nisplus [NOTFOUND=return] files
#ethers: nisplus [NOTFOUND=return] files
#netmasks: nisplus [NOTFOUND=return] files

bootparams: nisplus [NOTFOUND=return] files

ethers: files netmasks: files networks: files protocols: files rpc: files services: files

netgroup: files ldap

publickey: nisplus

automount: files ldap

aliases:    files nisplus

As you can see, this tells linux, try local files first for authentication, then try LDAP.

The final portion of AD authentication in linux is to modify system-auth. This file is part of the pam module. We touched a bit on it before, its the authentication service of linux, so if there is misconfiguration in this part, then, don't say i didn't warn you..

nano /etc/pam.d/system-auth

#%PAM-1.0
# This file is auto-generated.
# User changes will be destroyed the next time authconfig is run.
auth required pam_env.so
auth sufficient pam_unix.so nullok try_first_pass
auth requisite pam_succeed_if.so uid >= 500 quiet
auth sufficient pam_krb5.so use_first_pass
auth sufficient pam_ldap.so use_first_pass
auth required pam_deny.so

account required pam_unix.so broken_shadow
account sufficient pam_succeed_if.so uid < 500 quiet
account [default=bad success=ok user_unknown=ignore] pam_ldap.so
account [default=bad success=ok user_unknown=ignore] pam_krb5.so
account required pam_permit.so

password requisite pam_cracklib.so retry=3
password sufficient pam_unix.so md5 shadow nullok try_first_pass use_authtok
password sufficient pam_krb5.so use_authtok
password sufficient pam_ldap.so use_authtok
password required pam_deny.so

session optional pam_keyinit.so revoke
session required pam_limits.so
session [success=1 default=ignore] pam_succeed_if.so service in crond quiet use_uid
session required pam_unix.so
session optional pam_krb5.so
session optional pam_ldap.so
session required pam_mkhomedir.so

These modifications will tell pam what module to use and if they are optional, or required to login and create a session on this box.

Now the moment of truth, its time to test Single Sign On for Linux. The first command is kinit

kinit administrator

replace "user" with the user that you added UNIX attributes to. if successful, you should be asked a password, and then sent back to your prompt without any other messages. run klist to list the kerberos ticket. kdestroy to destroy the ticket. One last test is "getent passwd". This command will query your local passed file, and then question AD for UNIX capable Users, for now, we should only see the user that you modified earlier.

The fastest way to test authentication is by establishing an SSH session from the same system:

ssh administrator@localhost

obviously use the same user as configured in active directory at the beginning. You should be able to logon without any hiccups, and.. it will create a home folder (if there wasn't one already).

Congrats! You got it! But wait, why isn't the Linux box listed in AD as a computer account. We can do this by continuing a bit more and adding the computer account from within linux.

To do this, make sure samba is installed.

yum install samba

Now, we need to modify some parameters in /etc/samba/smb.conf:

nano /etc/samba/smb.conf

workgroup = TEST

security = ads

passdb backend = tdbsam

realm = test.local

password server = dc.test.local

Now the last part is to run "net rpc join -U admin"

Replace admin with an administrator account in your active directory environment.

Voila! Done! Now you have Single Sign On with AD on your linux box.