Valid HTML 4.01 Transitional
Prev: LightDM Greeter Uses User's Background Next: Troubleshooting a Network Screwup
(Index)
Jim Carter's Bugfixes

Apache2-mod_auth_kerb Is Dead, Use Mod_auth_gssapi

James F. Carter
2020-05-31
Symptom:

Apache2-mod_auth_kerb is an Apache authentication module that accepts the client's Kerberos credential for admission. However, starting about 2020-01-xx, if you list it in /etc/sysconfig/apache2 APACHE_MODULES, Apache will not start, complaining undefined symbol: krb5_rc_dfl_init. There are several more undefined symbols but this is the first one encountered.

Versions:

 
What's happening:

/usr/lib64/libkrb5.so.3.3 from krb5-1.18.1-1.1.x86_64 no longer defines these symbols. It looks like the ABI got changed (for the better) but apache2-mod_auth_kerb was not updated accordingly.

How to fix:

Plan A: Update apache2-mod_auth_kerb to use the new ABI in libkrb5. I really don't want to do that. And maintenance on this module seems to have ceased long, long ago.

Plan B: Kerberos can't have just been abandoned on the web. Find what other people are using, and follow the herd.

Yes, there is an alternative: apache2-mod_auth_gssapi . Its source repository is at https://github.com/gssapi/mod_auth_gssapi/. It is being maintained actively; the most recent commit was on 2020-05-15, 15 days ago (as this is written). There is an official version (1.6.1) for OpenSuSE Tumbleweed; for Leap 15.2 and 15.1, and SLE-15 and SP1, version 1.5.0 (older) can be found under experimental packages in the Apache:Modules sub-repo.

Mod_auth_gssapi actually is not fixated on Kerberos; it can do any GSSAPI mechanism; the others listed are iakerb and ntlmssp. Using iakerb, supposing the client is incapable of talking directly to the KDC (perhaps due to firewall or routing issues), it can use the application server as a proxy to get a client ticket. With ntlmssp, the client can authenticate to a Microsoft Windows NT LAN Manager security provider. But each mechanism has some of its unique configuration directives. I have only used the krb5 mechanism.

I use Kerberos authentication several places on my server, and I have a file that I include in the <Location "/pathname"> block for each one. Here are the configuration directives that I use:

#<Location "/path/to/directory/"> (in the including file)
#Include /etc/apache2/conf.d/auth-krb.incl (in the including file)
#AuthName "Unique Description"		(includer provides this)
#Require valid-user			(includer provides this)
    <IfModule mod_auth_gssapi.c>
	AuthType			GSSAPI
		# The keytab with the credentials of your service principals,
		# e,g, HTTP/hostname.example.com@EXAMPLE,COM
	GssapiCredStore			keytab:/etc/krb5.keytab
		# These are (mostly?) off by default and the recommended ones
		# are shown here.  

		# If the browser doesn't provide a credential, do basic auth and
		# try to get a Kerberos ticket with the loginID and password.
	GssapiBasicAuth			On
		# Head off retries doomed to fail. 
	GssapiNegotiateOnce		On
		# For security, recommended to do GSSAPI only over TLS/SSL.
	GssapiSSLonly			On 
		# Set REMOTE_USER to the loginID without $REALM
	GssapiLocalName			On 
		# Use a cookie to propagate auth through a session.  
		# Configure mod_session in the includer, see below. 
	GssapiUseSessions		On 
                # Session cookie is encrypted, and an in-memory key gets wiped
		# on restart.  This provides persistence of the key.  Same key
		# for all sessions.  Jimc thinks it's better to have individual
		# keys and to lose them when the webserver restarts.  
	# GssapiSessionKey... 
		# Is this the default for storing Apache's credential cache?
	# GssapiCredStore ccache:FILE:/run/httpd/krb5ccache
		# Delegated credentials (if enabled) are stored here.
	GssapiDelegCcacheDir		/run/httpd/clientcaches
		# Store error messages in environment variables
		# MAG_ERROR MAG_ERROR_TEXT GSS_ERROR_MAJ GSS_ERROR_MIN
	GssapiPublishErrors		On
		# Sets GSS_MECH = "Negotiate".  SuSE's module rejects it: looks
		# like a recent addition.
	# GssapiPublishMech             On
		# Which service principal should respond to the incoming query?
		# {HOSTNAME} = the virtual host's hostname, from SNI.
	GssapiAcceptorName		HTTP@{HOSTNAME}

    </IfModule>
#</Location> (in the including file)

Configuring mod_session specifically for mod_auth_gssapi: This is technically optional, but generally a web of pages are protected by Kerberos authentication, and without the session the authentication would have to be repeated on every page, style sheet, graphic, etc. This kind of assumes that there will be no competing sessions to collide with gssapi_session, which is apparently hardwired. The following directives should go in the including file within the block for <Location /pathname> :

    <IfModule mod_session.c>
	Session on
    </IfModule>
    <IfModule mod_session_cookie.c>
	SessionCookieName gssapi_session path=/pathname;httponly;secure;
    </IfModule>

The path= cookie parameter needs to duplicate the path name in the containing Location directive, so the cookie will only be sent back as a part of requests covered by the authentication. The cookie header flag httponly tries to tell the browser to not let evil client side scripts steal the cookie (which is encrypted anyway by mod_auth_gssapi). secure tells the browser to send back the cookie only over TLS (HTTPS). mod_session_crypto is not needed because mod_auth_gssapi does the crypto itself.

Remember, Chromium, Firefox and MSIE need to be told that it's OK to use SPNEGO (Kerberos on GSSAPI) with explicitly listed servers or domains.


Prev: LightDM Greeter Uses User's Background Next: Troubleshooting a Network Screwup
(Index)