Friday, November 13, 2009

Step by Step Apache Kerberos Authentication with LDAP Authorization on Red Hat Enterprise 5 (RHEL5) with Active Directory

Steps for enabling Active Directory hosted Kerberos authentication with LDAP authorization controls in Apache on Red Hat Enterprise 5


Active Directory Domain administrator creates Active Directory groups as appropriate for Apache authorization controls – get the DNs of these groups from her

Active Directory Domain administrator creates a service account which can be used to bind to LDAP for the purposes of doing group membership lookups on the groups to be used for authorization controls – get the service account name and password from her

Active Directory Domain administrator creates an HTTP service principal for the full hostname (including domain) of your web server by following these steps:
  • Create a new user account, i.e. service account in Active Directory with a non-expiring password to associate with the specific service principal for this host -- this must be done for EVERY kerberos service principal created for every host. If you REUSE a service account that was previously used to create a principal for a host, only the last host will work properly. If you get the error: ""failed to verify krb5 credentials: Decrypt integrity check failed" it's possible you're running into this issue
  • Domain administrator runs: ktpass -princ HTTP/host.your.domain@YOUR.DOMAIN -mapuser -crypto DES-CBC-MD5 -pass -out
  • Copy the keytab file to your Red Hat Enterprise 5 web server
  • Configure Red Hat Enterprise to use Kerberos for login authentication – the scope of this activity is not covered here, but it trivial to do with the RHEL5 administrative tools – your Domain Admin will have to supply the Domain Controller(s) IP addresses; don’t worry about the Kerberos Admin configuration unless you plan to use that service, it’s not required for Kerb authentication to work properly
To test Kerb on RHEL5, disable your account’s local linux password and verify that entering your active directory password instead gives you access to the server – use ssh –vvv to produce full debugging information if you’re connecting (hopefully) with ssh

Ensure your /etc/krb5.conf file looks something like this now – adjust accordinly, but only if you’ve taken the other steps outlined here and cannot get Apache Kerb to work properly

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

[libdefaults]
default_realm = YOUR.DOMAIN
dns_lookup_realm = false
dns_lookup_kdc = false
ticket_lifetime = 24h
forwardable = yes

[realms]
YOUR.DOMAIN = {
kdc = domain.controller.your.domain:88
kdc = domain.controller2.your.domain:88
admin_server = domain.controller.your.domain:749
default_domain = YOUR.DOMAIN
}

[domain_realm]
your.domain = YOUR.DOMAIN
.your.domain = YOUR.DOMAIN

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

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

Uninstall mod_auth_kerb provided by RHEL5 if it is installed and the version is less than 5.4 That version or later is required to get access to a feature that strips the realm off of user credentials. If the realm is left on, you will not be able to properly lookup the user name in LDAP against Active Directory unless you change the LDAP filter to use userPrincipalName, but unfortunately, userPrincipalName is not automatically populated for all users – I’m not sure why, but it’s not. So, best to use the KrbLocalUserMapping option

Ensure the following entries existing somewhere in your Apache configuration – The details of Apache configuration are not covered here – there are plenty of places to look elsewhere for that.

# you can probably safely place your compiled mod_auth_kerb into /etc/httpd/modules and so long as you don’t later install the RHEL5 supplied version, you’ll probably be ok… I like to keep my customizations separate, but that’s just me

LoadModule auth_kerb_module /path/to/your/compiled/mod_auth_kerb/mod_auth_kerb.so


AuthType Kerberos
Krb5Keytab /path/to/your/new/keytab/file
# if your web browser is not “kerberized” properly, e.g. setting firefox’s about:config property called network.negotiate-auth.trusted-uris to .YOUR.DOMAIN, it will not be sending the Kerberos ticket for the HTTP service to your web server
# in that case, we want to fall back to basic authentication to get the user’s credentials – please do not do this without SSL in place
KrbMethodNegotiate on

# strip the realm from the name of the authenticated user, e.g. o-simpson@YOUR.DOMAIN => o-simpson; this is necessary for LDAP lookups later on
KrbLocalUserMapping on

AuthName "Active Directory Credential"

# Kerberos just has to validate a match between a credential and a password
require valid-user



OK, now restart your web server and give it a shot. Check /var/log/httpd/ssl_error_log for problems and enable debugging if you have to. On windows, you can use the klist command from the Windows Resource Kit to ensure that your client is getting a ticket for HTTP/YOUR.HOST.YOUR.DOMAIN; Also, you can use wireshark and live httpd headers to see what’s going on the wire; but hopefully this will work

If you’re being prompted for a username and password and you’re sure you’ve kerberized your browser properly, check the ssl_error_log – either your client machine is not able to fetch a ticket for the service at your web server host, or the browser is not forwarding the ticket to the web server for some reason, or the web server is not able to decrypt the ticket, or the web server is not able to communicate with the KDC (although that’s unlikely since you have enabled Kerberos login for the Red Hat host already). I recommend getting this transparent SSO to work before proceeding… although it’s not absolutely required in order to proceed… but the configuration is about to get a little more complicated before we’re finished.

Congrats, you have SSO working. Let’s now apply a layer of authorization using LDAP groups – I think the notion of Kerberos groups also exists, but when I briefly looked into it, it seemed pretty complicated. I think managing LDAP groups is a lot easier so I’m sticking with that. Add the following lines to your httpd configuration inside the directive

# tell Kerberos that it doesn’t have the final say over allowing the request to proceed; we have another step in the process… the authorization step
KrbAuthoritative off

# add the second layer for authorization
AuthBasicProvider ldap

# LDAP shall have the final say over whether the request proceeds or not… mind you, if you don’t authenticate against Kerberos, the LDAP lookup for group membership won’t work either…
AuthzLDAPAuthoritative on

# the DN of the service account you are going to use to BIND to your LDAP server
AuthLDAPBindDN "cn=LDAPQuery,ou=Service,ou=UserAccounts,dc=YOUR,dc=DOMAIN"
AuthLDAPBindPassword secretSaucers

# this is the URL to your ldap server combined with the LDAP filter that limits the set of accounts to match – auth_ldap combines your filter with an attribute search matching the authenticated username: (&(filter)(attribute=username))
AuthLDAPURL ldap://your-ldap-server.your.domain:389/dc=your,dc=domain?sAMAccountName?sub?(objectCategory=person)(objectClass=User)

# now, your ldap groups… the authenticated user must not only be found in active directory, they must also be a member of at least one of the following AD groups…
Require ldap-group CN=GROUPA,OU=Groups,dc=your,dc=domain
Require ldap-group CN=GROUPB,OU=Groups,dc=your,dc=domain







No comments:

Post a Comment