Kerberos SSO configuration
Problem: A new web application uses regular Apache httpd authorizations to directories entries and you want to authenticate the users using their Active Directory (AD) credentials.
Solution: Through the implementation of an Active Directory service principal, httpd can authenticate users either coming from an already existing AD connection, which is seamless and provides Single Sign-On (SSO) or, if not coming from their Windows/AD connections, authenticate to AD with a password.
Single Sign-On (SSO) using GSS API:
In order to implement httpd SSO using GSS API, the following steps are required:
Setup /etc/krb5.conf on target server
Create a service principal in Active Directory and a keytab for apache authentication
Setup the Apache web server on target server
Configure the apache directives
Configure the user browser for automatic logon
Setup the web server kerberos configuration and related utilities and libraries
Any machine communicating with AD or even just containing services that provide GSS API authentication needs a properly configured /etc/krb5.conf, specifying the kerberos realm and other parameters. This file should be writable only by root but readable by all users. Here is an example:
# /etc/krb5.conf
[libdefaults]
default_realm = SPROCKETS.LOCAL
dns_lookup_realm = true
dns_lookup_kdc = true
ticket_lifetime = 10h
renew_lifetime = 7d
forwardable = true
kdc_timesync = true
ccache_type = 4
proxiable = true
fcc-mit-ticketflags = true
default_keytab_name = FILE:/etc/krb5.keytab
verify_ap_req_nofail = true
[realms]
SPROCKETS.LOCAL = {
kdc = sprockets.local
admin_server = dom01.sprockets.local
}
[domain_realm]
sprockets.local = SPROCKETS.LOCAL
.sprockets.local = SPROCKETS.LOCAL
.nyc.sprockets.local = SPROCKETS.LOCAL
.tex.sprockets.local = SPROCKETS.LOCAL
.smd.sprockets.local = SPROCKETS.LOCAL
[domain realm]
Notice the domain realm section in the /etc/krb5.conf. This section provides a mapping between the host name and the Kerberos realm.
In Active Directory, independently where the host is installed in the directory services (LDAP) structure, i.e. the Organizational Units (OU), all of them are mapped to a flat Kerberos realm. The mapping above means that a host named host1.sprockets.local, created in AD as CN=host1, OU=New York, OU=Linux, DC=SPROCKETS, DC=local, is mapped as host1.SPROCKETS.LOCAL in the Kerberos database.
Install the krb5 utils and libraries:
$ sudo yum install krb5-libs krb5-workstation
Create a service principal in Active Directory and a keytab for apache authentication
Once the /etc/krb5.conf file is in place, access to and manipulating objects in Active Directory is possible.
Where this step can be executed
This step can either be executed in the target host (if it is able to communicate with Active Directory) or at any other Linux host, including your personal VM. If you choose the later, simply create the /etc/krb5.conf file and install the krb5 RPMs as instructed in the previous step.
pre-requisites
The tool used to create the AD service principals in a Linux host is msktutil, This tool fetches and manages kerberos keytabs, creates accounts and services principals in an Active Directory environment. This is needed only in the Linux host where the keytab is created so, if you are not doing this step in the Apache httpd server itself, do not install it there.
$ sudo yum install msktutil
Authenticate (initialize your kerberos ticket) with an Active Directory domain administrator account:
$ kinit '$homer.simpson@SPROCKETS.LOCAL' (make sure case matches to whats in krb5.conf)
$ klist
Ticket cache: FILE:/tmp/krb5cc_2501
Default principal: myadministratoraccount@SPROCKETS.LOCAL
Valid starting Expires Service principal
08/31/16 14:41:32 09/01/16 00:41:32 krbtgt/SPROCKETS.LOCAL@SPROCKETS.LOCAL
renew until 09/01/16 00:41:32
Create the httpd service principal keytab. The following command uses "nycweb01.sprockets.local" as an example:
short and fqdn references
Attention to the distinction among the service, account-name and hostname options references to the host name. The HTTP service principal and the hostname use the fqdn, but the account name is a short host identification.
$ msktutil --create \
--use-service-account \
--user-creds-only \
--service HTTP -s HTTP/nycweb01.sprockets.local \
--keytab ./httpd.keytab \
--account-name nycweb01.httpd \
--hostname nycweb01.sprockets.local \
--base 'OU=Utility Accounts,OU=Sprocket-Users' \
--no-pac \
--dont-expire-password \
--verbose
Confirm the keytab is properly created
$ klist -t -k httpd.keytab
Keytab name: FILE:httpd.keytab
KVNO Timestamp Principal
---- ----------------- --------------------------------------------------------
15 08/13/16 16:58:35 web01.httpd@SPROCKETS.LOCAL
15 08/13/16 16:58:35 web01.httpd@SPROCKETS.LOCAL
15 08/13/16 16:58:35 web01.httpd@SPROCKETS.LOCAL
15 08/13/16 16:58:35 HTTP/web01@SPROCKETS.LOCAL
15 08/13/16 16:58:35 HTTP/web01@SPROCKETS.LOCAL
15 08/13/16 16:58:35 HTTP/web01@SPROCKETS.LOCAL
confirm Authentication
kinit -Vkt httpd.keytab web01.httpd
Using default cache: /tmp/krb5cc_0
Using principal: web01.httpd@COMPANY.LOCAL
Using keytab: httpd.keytab
Authenticated to Kerberos v5
Destroy your administrator accounts kerberos tickets:
$ kdestroy
$ klist
klist: No credentials cache found (ticket cache FILE:/tmp/krb5cc_2501)
Copy the keytab to the target web server. In the following paragraphs, it assumes the location is /etc/httpd/httpd.keytab
$ rsync -vpP httpd.keytab web01:/etc/httpd/httpd.keytab
In the target web server, set the proper ownership and permissions for the keytab:
$ sudo chown daemon:daemon /etc/httpd/httpd.keytab
$ sudo chmod 600 /etc/httpd/httpd.keytab
Configure the apache directives
Any Apache <Directory> stanza can now authorize based on Kerberos (AD) SSO through GSS-API.
Here is an example through the Nagios configuration, notice the 'Krb' entries, where references to the AD realm and the keytab you created in the previous steps:
<Directory "/usr/share/nagios/">
AuthzSendForbiddenOnFailure On
Options None
AllowOverride None
Order allow,deny
Allow from all
AuthName "Nagios Access"
AuthType Kerberos
KrbAuthRealms SPROCKETS.LOCAL
KrbServiceName HTTP/nycweb01.sprockets.local
Krb5KeyTab /etc/httpd/httpd.keytab
KrbMethodK5Passwd off
KrbLocalUserMapping on
KrbSaveCredentials on
SSLRequireSSL
AuthGroupFile /etc/httpd/conf/httpd-access-groups
Require group nagios-users
</Directory>
Additional Apache modules
Apache needs mod_auth_kerb installed and loaded, in order to provide GSS-API authentication with Active Directory
Install the RPM:$ sudo yum install mod_auth_kerb
In your Apache configuration, load the module:LoadModule auth_kerb_module /usr/lib64/httpd/modules/mod_auth_kerb.so
the full Apache config file including 80 and 443,
# Apache configuration for BGSE logs access
LoadModule auth_kerb_module /usr/lib64/httpd/modules/mod_auth_kerb.so
<VirtualHost *:80>
ServerName sprockets
ServerAlias sprockets.company.local
ServerAdmin admin@company.com
ErrorLog /var/log/httpd/sprockets-error_log
CustomLog /var/log/httpd/sprockets-access_log common
DocumentRoot //usr/share/nagios
RewriteEngine On
RewriteCond %{HTTPS} off
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI}
</VirtualHost>
<VirtualHost *:443>
ServerName sprockets
ServerAlias sprockets.company.local
ServerAdmin admin@company.com.com
ErrorLog /var/log/httpd/sprockets-error_log
CustomLog /var/log/httpd/sprockets-access_log common
DocumentRoot /usr/share/nagios
SSLEngine on
SSLCertificateKeyFile "/etc/httpd/conf.d/sprockets.company.local.key"
SSLCertificateFile "/etc/httpd/conf.d/sprockets.company.local.pem"
<Directory "/usr/share/nagios/">
AuthzSendForbiddenOnFailure On
Options None
AllowOverride None
Order allow,deny
Allow from all
AuthName "Nagios Access"
AuthType Kerberos
KrbAuthRealms SPROCKETS.LOCAL
KrbServiceName HTTP/nycweb01.sprockets.local
Krb5KeyTab /etc/httpd/httpd.keytab
KrbMethodK5Passwd off
KrbLocalUserMapping on
KrbSaveCredentials on
SSLRequireSSL
Require valid-user
</Directory>
</VirtualHost>
Restart Apache or reload its configuration
$ sudo /sbin/service httpd reload
Configure the user browser for automatic logon
These instructions work both for Internet Explorer and Google Chrome, since both load their configuration from the Control Panel Internet Options settings.
Close your browser, go to 'Control Panel' and open 'Internet Options' (you can search for it in the search bar):
Select the Security tab and the Local intranet icon
Click at Sites
Click at Advanced and Add sites or URL wildcards, indication which ones you want to be able to login automatically from your Windows account.:
Click Close then OK. You should be back to the Internet Properties Security tab. Click at Custom Level and slide all the way to the bottom of the options list. You should see "Automatic logon only in Intranet zone".
Click OK and then leave the Internet Options Control panel application.
Open a browser and go to the Apache httpd URL you configured with SSO. You should be authenticated without the need to provide a password.
Troubleshooting
Apache config
add LogLevel Debug to apache config to troubleshoot
<VirtualHost *:80>
ServerName sprockets
ServerAlias sprockets.company.local
ServerAdmin admin@company.com
ErrorLog /var/log/httpd/sprockets-error_log
CustomLog /var/log/httpd/sprockets-access_log common
LogLevel Debug
if getting gss_accept_sec_context() failed: An unsupported mechanism was requested (, Unknown error)
edit Apache config to accept KrbServiceName Any, restart apache and try again, this checks if your HTTP service name is misconfigured
If Kerb is not passing the user name over to the Kerb server (NULL)
check the /etc/httpd/httpd.keytab file
a proper Keytab file should contain weird characters, not plain text. An incorrectly formed keytab file will prevent the passing of username to Kerberos
cat httpd.keytab
.G..COMPANY.LOCALweb01.httpd.[N5�...��f\.Z�GR._x?���.G..COMPANY.LOCALweb01.httpd.[N5�...�=.�.�6w!k�e���.W..COMPANY.LOCALweb01.httpd.[N5�.. ]c��84��w�1Jo�.zH�rDY>�
����B.F..COMPANY.LOCAL.HTTtestlogs.[N5�...��f\.Z�GR._x?���.F..COMPANY.LOCAL.HTTtestlogs.[N5�...�=.�.�6w!k�e���.V..