Score:1

Troubleshooting Apache with GSS Proxy Authentication and LDAP Authorization

in flag

I'm setting up an internal web server on a domain-joined RHEL server with Kerberos authentication via GSS proxy and tiered authorization with LDAP, where Active Directory is the source of truth. Kerberos and the authentication piece is working fine, but I cannot get authorization working and I'm out of ideas.

Here's the directory configuration:

<Directory /var/www/nietools.elsinor.net/html/>
        AuthType GSSAPI
        AuthName "GSSAPI Login"
        Require valid-user
</Directory>

<Directory /var/www/nietools.elsinor.net/html/tools/config_grep/>
        AuthType GSSAPI
        AuthName "GSSAPI Login"
        #GssapiConnectionBound On
        #GssapiSignalPersistentAuth On
        #GssapiUseSessions On
        #Session On
        #SessionCookieName gssapi_session path=/private;httponly;secure;
        AuthLDAPUrl "ldaps://ad.elsinor.net:636/OU=People,DC=ad,DC=elsinor,DC=net/?sAMAccountName?sub"
        AuthLDAPBindDN "CN=nietools,OU=Services,DC=ad,DC=elsinor,DC=net"
        AuthLDAPBindPassword "exec:/bin/cat /etc/httpd/conf.d/pw"
        Require ldap-group "CN=NIE,OU=Groups,DC=ad,DC=elsinor,DC=net"
</Directory>

The first directory config works exactly as expected. If you're connecting from a domain laptop, it authenticates transparently. If not, it prompts for a login. All good.

The second directory doesn't authorize anyone. The commented-out parameters are all things I've been messing with to try to resolve the issue. I've focused on these parameters because of the messages in the Apache error log. Attempts by an authenticated user to access the second directory produce the following errors:

2023-08-07 15:40:27.893785 clientip=10.61.3.159:41364, hdr_referer="https://nietools.elsinor.net/", servername=nietools.elsinor.net, pid=45071, tid=140289914160704, module=authz_core, loglevel=error, message="AH01631: user [email protected]: authorization failure for "/tools/config_grep": "

2023-08-07 15:40:27.992661 clientip=10.61.3.159:41364, hdr_referer="https://nietools.elsinor.net/", servername=nietools.elsinor.net, pid=45071, tid=140289905768000, module=auth_gssapi, loglevel=error, message="INTERNAL ERROR Mechanism needs continuation but neither GssapiConnectionBound nor GssapiUseSessions are configured"

These error messages appear consistently, seemingly regardless of how I configure GssapiConnectionBound and GssapiUseSessions—neither one of which appear in any of the configuration references I've found pertaining to a setup like this.

And by the way, authentication works as expected if I remove LDAP from the equation and put the users into a manually-defined group, like so:

<Directory /var/www/nietools.elsinor.net/html/tools/config_grep/>
        AuthType GSSAPI
        AuthName "GSSAPI Login"
        AuthGroupFile "/etc/httpd/conf.d/groups"
        Require group nie
</Directory>

Is it possible that the INTERNAL ERROR message is benign, and the real problem is more mundane–like using an attribute other than SamAccountName? (I already tried UserPrincipalName.)

This is RHEL 9, by the way, and Apache 2.4.

EDIT: I noticed something in the Apache debug logs: the Kerberos module passes [email protected] to the LDAP module, but the UserPrincipalName is [email protected]. This may the problem. I suspect I have to use the UserPrincipalName attribute and alias "AD.ELSINOR.NET" to "elsinor.net" somehow.

EDIT 2: Not it. I implemented user1686's suggestion and the Apache logs now indicate that the user identities should match the sAMAccountName. Unfortunately, they're still not authorized. I suspect one of two things:

  1. There's something more fundamental going on and I just can't find it. I've checked the AuthLDAPUrl, AuthLDAPBindDN, and Require values about 20 times each.

  2. The "needs continuation" error is actually relevant and I haven't addressed it properly, because I have no idea what it means.

I should throw in that I've already executed sudo setsebool -P httpd_can_connect_ldap 1 and the SELinux audit is clean, even after disabling the nasty silent denials with semodule -DB.

EDIT 3: The gssproxy configuration:

[service/HTTP]
  mechs = krb5
  cred_store = keytab:/etc/krb5.keytab
  cred_store = ccache:/var/lib/gssproxy/clients/krb5cc_%U
  euid = 48
  krb5_principal = HTTP

[service/ldap]
  mechs = krb5
  cred_store = keytab:/etc/krb5.keytab
  cred_store = ccache:/var/lib/gssproxy/clients/krb5cc_%U
  euid = 55
  krb5_principal = ldap

[service/imap]
  mechs = krb5
  cred_store = keytab:/etc/krb5.keytab
  cred_store = ccache:/var/lib/gssproxy/clients/krb5cc_%U
  euid = 76
  krb5_principal = imap
user1686 avatar
fr flag
"Needs continuation" is strange, as SPNEGO usually starts off with directly sending a Kerberos token and should succeed in just one step; what clients are you testing with and what do you have in gss-proxy configuration?
Vaito avatar
in flag
Updated the post with the relevant gssproxy configuration. The clients are managed, domain-joined computers (on the same domain as the server). This allows silent SSO authentication. Incognito windows prompt for authentication, of course, but it works. It's only authorization that stumbles.
Score:0
fr flag

Kerberos principal names are not exactly the same as Active Directory UPNs. The principal you receive from GSSAPI looks like a UPN (and both are named "principal names", confusingly) but actually has no direct relation to it at all.

Kerberos principals in AD are formed from the NT username (sAMAccountName) plus the domain's Kerberos realm (which is always the upper-case version of the domain, regardless of any UPN suffixes).

I would probably use GssapiLocalName On to have the Krb5 library attempt to translate the principal to a "local account name"; in default configuration this translation always just strips the system default realm. That is, [email protected] becomes just user, which is then suitable for a LDAP query against sAMAccountName (while principals from foreign realms remain as-is).

Vaito avatar
in flag
Great suggestion! This does exactly as advertised, and the Apache logs now indicate that the user identities should match the sAMAccountName. Unfortunately, they're still not authorized. I'll update the main post accordingly.
I sit in a Tesla and translated this thread with Ai:

mangohost

Post an answer

Most people don’t grasp that asking a lot of questions unlocks learning and improves interpersonal bonding. In Alison’s studies, for example, though people could accurately recall how many questions had been asked in their conversations, they didn’t intuit the link between questions and liking. Across four studies, in which participants were engaged in conversations themselves or read transcripts of others’ conversations, people tended not to realize that question asking would influence—or had influenced—the level of amity between the conversationalists.