Hi,
I have a question about the configuration of Kerberos authentication in the following scenario. I have a valid SPN saved to a keytab with the following command :
ktpass.exe /princ HTTP/myhost.mydomain@MYDOMAIN /mapuser MYUSER@MYDOMAIN /crypto AES256-SHA1 /ptype KRB5_NT_PRINCIPAL /pass * /out mykeytab.keytab
The keytab is copied to a Linux server and the following configuration is used:
<VirtualHost *:80="">
ServerName myhost.mydomain
...
<Location/>
AuthName "My auth name"
AuthType Kerberos
Krb5Keytab /etc/mykeytab.keytab
KrbMethodNegotiate on
KrbMethodK5Passwd off
KrbSaveCredentials on
Require valid-user
</Location>
</VirtualHost>
Note: the default REALM from the /etc/krb5.conf file is MYDOMAIN. I tried to force it in the Apache HTTPD config file, but nothing changed.
The keytab seems to contain a valid SPN:
klist -k -t -e -K FILE:/etc/mykeytab.keytab
Keytab name: FILE:/etc/mykeytab.keytab
KVNO Timestamp Principal
---- ----------------- --------------------------------------------------------
7 12/31/69 19:00:00 HTTP/myhost.mydomain@MYDOMAIN (aes256-cts-hmac-sha1-96) (...)
With this configuration, I get a HTTP 500 error from Apache HTTPD with the following log lines:
src/mod_auth_kerb.c(1954): [...] kerb_authenticate_user entered with user (NULL) and auth_type Kerberos, referer: http://myhost.mydomain/
src/mod_auth_kerb.c(1295): [...] Acquiring creds for HTTP@myhost.domain, referer: http://myhost.mydomain/
src/mod_auth_kerb.c(1155): [...] GSS-API major_status:000d0000, minor_status:000186a4, referer: http://myhost.mydomain/
But, if I add the following line to the configuration:
KrbServiceName HTTP/myhost.mydomain
Everything is working fine for that part:
src/mod_auth_kerb.c(1295): [...] Acquiring creds for HTTP/myhost.mydomain, referer: http://myhost.mydomain/
src/mod_auth_kerb.c(1708): [...] Verifying client data using KRB5 GSS-API , referer: http://myhost.mydomain/
src/mod_auth_kerb.c(1724): [...] Client didn't delegate us their credential, referer: http://myhost.mydomain/
Now, looking at the source code, I see this in get_gss_creds (this is a cleaned version of the code):
char buf[1024];
int have_server_princ;
have_server_princ = conf->krb_service_name && strchr(conf->krb_service_name, '/') != NULL;
So, if the service name is supplied in the configuration, the boolean have_server_princ is true. Then it is used to create the ticket value:
if (have_server_princ) {
strncpy(buf, conf->krb_service_name, sizeof(buf));
} else {
snprintf(buf, sizeof(buf), "%s@%s",
(conf->krb_service_name) ? conf->krb_service_name : SERVICE_NAME,
ap_get_server_name(r));
}
This match what I see in the log where the ticket is HTTP@myhost.mydomain. Then:
major_status = gss_import_name(&minor_status, &token,
(have_server_princ) ? (gss_OID) GSS_KRB5_NT_PRINCIPAL_NAME : (gss_OID) GSS_C_NT_HOSTBASED_SERVICE,
&server_name);
Now, this doesn't match the ticket type I exported in my keytab file. From the doc:
GSS_C_NT_HOSTBASED_SERVICE: The value should be a string of the form service or service@hostname. This is the most common way to name target services when initiating a security context, and is the most likely name type to work across multiple mechanisms.
GSS_KRB5_NT_PRINCIPAL_NAME: The value should be a principal name string. This name type only works with the krb5 mechanism, and is defined in the <gssapi_krb5.h> header.
The rest of the calls up to gss_acquire_cred are working:
major_status = gss_display_name(&minor_status, server_name, &token, NULL);
log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, "Acquiring creds for %s", token.value);
major_status = gss_acquire_cred(&minor_status, server_name, GSS_C_INDEFINITE,
GSS_C_NO_OID_SET, GSS_C_ACCEPT, server_creds, NULL, NULL);
This is on Red Hat 6.7 with Apache HTTPD 2.4 and mod_auth_kerb v5.4