Knowledgebase:
Authenticating MarkLogic users with Kerberos
24 November 2016 09:27 AM

Introduction

MarkLogic Server allows you to configure MarkLogic Server so that users are authenticated using an external authentication protocol, such as Lightweight Directory Access Protocol (LDAP) or Kerberos. These external agents serve as centralised points of authentication or repositories for user information from which authorisation decisions can be made. In this article you will see the steps required to authenticate a user using Kerberos.

Authenticating MarkLogic users with Kerberos

Kerberos is a ticket-based authentication protocol for trusted hosts on untrusted networks which provides users with encrypted tickets that can be used to request access to particular servers.

Because Kerberos uses tickets, both the user and the server can verify each other's identity and user passwords do not have to pass through the network. This article will also show you how to configure MarkLogic Server to validate Kerberos user tickets and to map them to a MarkLogic database user on your cluster.

Kerberos user principals are defined in the format username@REALM.NAME, for this article we will use the Kerberos principal ml1@MLKRB.LOCAL and the MarkLogic userid krbuser1.

Configuring the MarkLogic cluster

Before MarkLogic can validate Kerberos user tickets the following requirements need to be met.

  1. Configure the Kerberos client on each server on which a MarkLogic instance is running.
  2. Create a Kerberos KeyTab to allow MarkLogic to authenticate users.
  3. Create a MarkLogic External Security configuration for Kerberos.
  4. Configure the MarkLogic AppServer to authenticate Kerberos tickets. 
  5. Add an External Kerberos principal to the MarkLogic user.

Configuring the Kerberos client

In order to authenticate Kerberos users, MarkLogic needs to know which host domains it will be authenticating and which Kerberos realms to authenticate against. This information is held in the /etc/krb5.conf file in Unix or krb5.ini file in Windows (The location will be dependent on the Windows Kerberos implementation being used, i.e Active Directory or MIT Kerberos).

In this example our the MarkLogic servers are installed on domains mwca.marklogic.com, mwcb.marklogic.com and mwcc.marklogic.com and the Kerberos Domain Controller (KDC) resides at kerberos.marklogic.com.

The [domain_realm] section is a series of host domains and realms mappings, in this case all our example MarkLogic hosts are using the .marklogic.com domain and will be using the MLKRB.LOCAL realm.

The [realms] section defines the realms that this client can access and the associated KDC that will be used.

A sample krb5.conf file:

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

[libdefaults]
dns_lookup_realm = false
ticket_lifetime = 24h
renew_lifetime = 7d
forwardable = true
rdns = false
default_realm = MLKRB.LOCAL
default_ccache_name = KEYRING:persistent:%{uid}

[realms]
MLKRB.LOCAL = {
kdc = kerberos.marklogic.com
}

[domain_realm]
.marklogic.com = MLKRB.LOCAL
marklogic.com = MLKRB.LOCAL

Note: If the server is already configured to use Kerberos you should simply merge your new realm and domain settings.

Creating a Kerberos Keytab

The Kerberos Domain Administrator must create a services.keytab file for each MarkLogic instance to permit it to authenticate Kerberos users. This is done by issuing the addprinc and ktpass commands on the kerberos Domain controller.

addprinc -randkey HTTP/mwca.marklogic.com

ktpassprinc HTTP/mwca.marklogic.com@MLKRB.LOCAL mapuser mwca.marklogic.com@MLKRB.LOCAL pass mysecret out services.keytab

Example

[kadmin@kerberos ~]# kadmin.local
Authenticating as principal krbadmin/admin@MLKRB.LOCAL with password.

kadmin.local: addprinc -randkey HTTP/mwca.marklogic.com
WARNING: no policy specified for HTTP/mwca.marklogic.com@MLKRB.LOCAL; defaulting to no policy
Principal "HTTP/mwca.marklogic.com@MLKRB.LOCAL" created.

kadmin.local: ktadd -k services.keytab HTTP/mwca.marklogic.com
Entry for principal HTTP/mwca.marklogic.com with kvno 2, encryption type aes256-cts-hmac-sha1-96 added to keytab WRFILE:services.keytab.
Entry for principal HTTP/mwca.marklogic.com with kvno 2, encryption type aes128-cts-hmac-sha1-96 added to keytab WRFILE:services.keytab.
Entry for principal HTTP/mwca.marklogic.com with kvno 2, encryption type des3-cbc-sha1 added to keytab WRFILE:services.keytab.
Entry for principal HTTP/mwca.marklogic.com with kvno 2, encryption type arcfour-hmac added to keytab WRFILE:services.keytab.
Entry for principal HTTP/mwca.marklogic.com with kvno 2, encryption type camellia256-cts-cmac added to keytab WRFILE:services.keytab.
Entry for principal HTTP/mwca.marklogic.com with kvno 2, encryption type camellia128-cts-cmac added to keytab WRFILE:services.keytab.
Entry for principal HTTP/mwca.marklogic.com with kvno 2, encryption type des-hmac-sha1 added to keytab WRFILE:services.keytab.
Entry for principal HTTP/mwca.marklogic.com with kvno 2, encryption type des-cbc-md5 added to keytab WRFILE:services.keytab.

Repeat the above steps for each MarkLogic host in the cluster and copy the resultant services.keytab file to the corresponding MarkLogic Server Data directory.

Creating a MarkLogic External Security configuration

On the MarkLogic Server "Configure->Security->External Security" panel create a new Kerberos External Security configuration as below:

Configuring the MarkLogic AppServer

On the MarkLogic Server "Configure->Groups->{group-name}->AppServers" panel configure the AppServer to user kerberos-ticket as the authentication method and specify the external security definition created in the previous step:

Add the External Kerberos principal to the MarkLogic server userid

On the MarkLogic Server "Configure->Security->Users" panel add the external Kerberos principal name to the user:

Verify everything is working as expected

From a Kerberos enabled client machine, create a new ticket for your Kerberos user principal using the kinit command:

[martin@local1]# kinit ml1@MLKRB.LOCAL

Password for ml1@MLKRB.LOCAL:

Check the status of the ticket using the klist command

[martin@local1]# klist

Ticket cache: KEYRING:persistent:0:0
Default principal: ml1@MLKRB.LOCAL

Valid starting Expires Service principal
25/09/16 13:22:59 26/09/16 13:12:49 HTTP/mwca.marklogic.com@MLKRB.LOCAL

Negotiate a user connection to the AppServer using Curl; specify the -u switch without a userid and password will use the Kerberos ticket created previously.

 [martin@local]# curl -v --negotiate -u : http://mwca.marklogic.com:8050

* About to connect() to mwca.marklogic.com port 8050 (#0)
* Trying 192.168.0.50...
* Connected to mwca.marklogic.com (192.168.0.50) port 8050 (#0)
> GET / HTTP/1.1
> User-Agent: curl/7.29.0
> Host: mwca.marklogic.com:8050
> Accept: */*
>
...
* Connected to mwca.marklogic.com (192.168.0.50) port 8050 (#0)
* Server auth using GSS-Negotiate with user ''
> GET / HTTP/1.1
> Authorization: Negotiate YIICTwYJKoZIhvcSAQICAQBuggI+MIICOqADAgEFoQMCAQ6iBwMFACAAAACjggFUYYIBUDCCAUygAwIBBaENGwtNTEtSQi5MT0NBTKIiMCCgAwIBA6EZMBcbBEhUVFAbD213Y2EuZHluZG5zLm9yZ6OCARAwggEMoAMCARKhAwIBAqKB/wSB/Fzt6twxVRCPEWVzLq/h6ZV0MQ95iu9sKgNc1Rg+K4EmDBK1z4IHuHGYuYyV42rGZIA4rmF0NJe398b/uzGf3ViY+UHxNSlyj+BKSD6Q2rjAcYzsGsbXeebnClIDd/+/hN7DLrfWZ7HtuXMrAl0ifqnXSnd045ACUGXz4FAKAuAdJYtDUqT3UZ8+K4ExuGWkyViRhLOuTxphS49vMJ+uaRPZo9jiNkfnjZIj2esNChpz/urXCnlTT1Frrg0gPVlS1unAH4pRWg5DLFnajjg722UXR0P6fb/U3kbRxCCu1F1bJNjjAlTLtyhO4ZNh1LQ+28sYf3DnbNPFQZT1j6SBzDCByaADAgESooHBBIG+cik1lxaeURclPAi9t7x8kFt043KnsE4rv7quBbIET6wPgSu60YwuHjBS8xchgoNbJKp4BHNBjoKEBvNVcU1iqU8cuhYGJqmYkiu/DMGQb/pF4AApR09Azj4fWDmZpEcMMCWZFW6idRc9zmk1a0kjM8tkuA5jEH3M1ggev60mLM33ZkZRI5QhrFlDtfwMvJhfsve9sTSdlJPG7nWYgwUcfZN7BmL96O1P8zQCwFeUuICJO9Edlv3RZgiKBXJmnw==
> User-Agent: curl/7.29.0
> Host: mwca.marklogic.com:8050
> Accept: */*
>
< HTTP/1.1 200 OK

If MarkLogic is able to successfully authenticate the Kerberos user, you see an HTTP 200 code in response to the curl command and the MarkLogic AppServer logs should show the details of the external user mapping

External User(ml1@MLKRB.LOCAL) is Mapped to User(krbuser1)

192.168.0.50 - - [25/Sep/2016:13:48:30 +0100] "GET / HTTP/1.1" 200 2103 - "curl/7.29.0"

Troubleshooting

The following is a list of common problems encountered when authenticating with Kerberos.

Unable to generate a Kerberos token

Check that the kdc parameter in krb5.conf file points to a valid Kerberos Domain Controller:

[martin@local ~]# kinit ml1@MLKRB.LOCAL

kinit: Cannot contact any KDC for realm 'MLKRB.LOCAL' while getting initial credentials

Unauthorised 401 response due to gss_init_sec_context() failed: : No Kerberos credentials available error

This indicates that the Kerberos ticket is missing or invalid; use the klist command to check current ticket status and create a new ticket with kinit if required:

[martin@local ~]# curl -v --negotiate -u : http://mwca.marklogic.com:8050

* About to connect() to mwca.marklogic.com port 8050 (#0)
* Trying 192.168.0.50...
* Connected to mwca.marklogic.com (192.168.0.50) port 8050 (#0)
> GET / HTTP/1.1
> User-Agent: curl/7.29.0
> Host: mwca.marklogic.com:8050
> Accept: */*
>
< HTTP/1.1 401 Unauthorized
< Server: MarkLogic
* gss_init_sec_context() failed: : No Kerberos credentials available
< WWW-Authenticate: Negotiate

MarkLogic server not able to validate Kerberos ticket

Check the following:

  • Ensure the host name specified when creating the services.keytab resolves to a valid IP Address.
  • On servers that have multiple hostname use the hostname --fqdn  command to determine the correct hostname to use for generating the services.keytab
  • The services.keytab will only be used if the file permissions are restricted to read/write access for the MarkLogic daemon user on the host, e.g

[admin@mwca MarkLogic]# ls -al services.keytab

-rw------- 1 daemon daemon 594 Sep 25 12:33 services.keytab

Debugging Kerberos connections in MarkLogic

On the MarkLogic Server "Configure->Groups->{group-name}->Diagnostics" panel add Kerberos GSS Negotiate to the list of trace events:

Further Reading



Attachments 
 
(3 vote(s))
Helpful
Not helpful

Comments (0)