Kerberos Authentication

  • Note: The driver's Kerberos support is provided as part of the extensions jar. See the Notes at the bottom of this documentation for details.

The driver provides the ability for users to authenticate to the MongoDB server via Kerberos. There are several steps involved in getting a working Kerberos environment. Below are links to useful documentation for setting up your MongoDB server to use Kerberos and creating a working Kerberos Java environment.

In particular, one of the following must be completed to support locating the Kerberos domain controller:

  1. Set the system properties java.security.krb5.realm and java.security.krb5.kdc with the values for the Kerberos Realm and domain controller respectively.
  2. Set the system property java.security.krb5.conf to point to an appropriate krb5.conf or krb5.ini file.
  3. Create a krb5.conf or krb5.ini in one of the default locations. See the Java Kerberos Configuration guide for details.

With a working Kerberos environment the driver supports three modes for Kerberos authentication:

  1. User name and password
  2. Keytab File
  3. Cached credentials (commonly by kinit)

Authenticating via a Kerberos User Name and Password

With a working Kerberos infrastructure configuring the driver to use Kerberos for authentication can be as simple as providing the user name and password credentials. For the appropriate user or service Kerberos principal, create a Credential object with the user name and password and add it to the MongoClientConfiguration.

MongoClientConfiguration config = new MongoClientConfiguration("mongodb://locahost:27017/");

char[] password = new char[] { 's', 'u', 'p', 'e', 'r', 's', 'e', 'c', 'r', 'e', 't' };
config.addCredential(Credential.builder().userName("<user>@<REALM>").password(password).kerberos());
Arrays.fill( password, ' ' );
  • Note: The user name provided is the user's full Kerberos principal including the realm name.

The user does not need to be pre-authenticated with the server (via kinit) or even be resident on a machine within the Kerberos domain. The driver will authenticate the user and obtain required tickets automatically from the Kerberos domain controller. The host running the application need not be explicitly part of the Kerberos domain but should, obviously, be able to communicate with the Kerberos domain controller. This is the most flexible mechanism for authenticating with Kerberos but requires the user's password be provided to the driver.

Authenticating via a Kerberos Keytab File

For systems lacking an effective mechanism for obfuscating passwords within the application's configuration, a more secure option might be to place the application's Kerberos credentials within a keytab file that is then secured via DAC (Discretionary Access Controls, e.g., file permissions) and/or MAC (Mandatory Access Controls, e.g., SELinux labels).

To create the keytab file use the kadmin application or the ktutil application. Usage of the ktutil is beyond the scope of this guide but the kadmin command would look like:

kadmin -q "ktadd -k /path/to/secure/location/application.keytab <principal>" 
  • Note: You must have the JCE (Java Cryptography Extension) unlimited strength policy files installed to use some Kerberos tickets. The ktutil command can be used to remove unsupported tickets in a keytab file.

With the keytab file created simply provide the file with the credentials instead of the password.

MongoClientConfiguration config = new MongoClientConfiguration("mongodb://locahost:27017/");

File keytab = new File("/path/to/secure/location/application.keytab");
config.addCredential(Credential.builder().userName("<user>@<REALM>").file(keytab).kerberos());

The driver will then load the appropriate credentials from the key tab file when authenticating with MongoDB.

Authenticating via Cached Credentials (kinit)

  • Note: You must have the JCE unlimited strength policy files installed to use some Kerberos tickets cached via kinit.

Lastly, the driver can leverage previously acquired Kerberos credentials that have been cached locally. The credentials are normally cached via the kinit application similar to the following:

prompt> kinit -l 1d -r 1d 
Password for user@EXAMPLE.COM: 

The cached credentials are then viewable via the klist application. The -e option provides the encryption type for a ticket which can be particularly helpful when debugging.

  • Note: Recent changes to the MIT Kerberos now supports using a KEYRING for storing the tickets which provides secure persistence of the tickets within the kernel. The Java Kerberos libraries do not support using a KEYRING repository and breaks the ability of the usage of the cached credentials in the driver.

    This error normally is seen as a MongoDbAuthenticationException with the message Unable to obtain password from user. You can also verify the use of the KEYRING using klist as shown below. Note the value reported for the Ticket cache.

    prompt> klist
    Ticket cache: KEYRING:persistent:1000:1000
    Default principal: user@EXAMPLE.COM
    
    Valid starting       Expires              Service principal
    01/01/2014 23:14:53  01/02/2014 23:14:53  krbtgt/EXAMPLE.COM@EXAMPLE.COM
            renew until 01/02/2014 23:14:53

    To use the former default location (/tmp/krb5cc_{uid}) and restore Java access to the cached tickets you must modify the kinit invocation to include the cache name via the -c option or KRB5CCNAME environment variable. Below is an example using the bash shell and the -c option.

    prompt> kinit -l 1d -r 1d -c FILE:/tmp/krb5cc_$( id -u ) user@EXAMPLE.COM
    Password for user@EXAMPLE.COM:

With the tickets cached, start the application as the same user (does not need to be the same session) and create a Credential without a password similar to the following:

MongoClientConfiguration config = new MongoClientConfiguration("mongodb://locahost:27017/");

config.addCredential(Credential.builder().userName("<user>@<REALM>").kerberos());

The driver will then automatically switch to using the cached credentials.

We do not recommend this approach as it requires the credentials to be stored in a location not explicitly controlled by the application and its security plan. Further, the application can only be launched after successfully caching credentials requiring coordination and still requires some mechanism to securely store the user password for the kinit invocation.

Options

Regardless of the mode you are using with the driver the following options can be used with Kerberos authentication.

Kerberos Authentication Options
Option Name Default Value Description
kerberos.service.name mongodb The name of the Kerberos service the MongoDB server is providing.

Options are added to the credentials as they are built.

MongoClientConfiguration config = new MongoClientConfiguration("mongodb://locahost:27017/");

char[] password = new char[] { 's', 'u', 'p', 'e', 'r', 's', 'e', 'c', 'r', 'e', 't' };
config.addCredential(
   Credential.builder()
             .userName("<user>@<REALM>")
             .password(password)
             .kerberos()
             .addOption("kerberos.service.name", "mongo"));
Arrays.fill( password, ' ' );

Getting a MongoDB Server Running with Kerberos Support

  • Note: Kerberos support is only available in the 2.3/2.4 and later Enterprise editions.

Creating a Principle for the MongoDB Server

Before starting a MongoDB server with Kerberos support, we need to provision or identify the MongDB server within the Kerberos domain. The first step is to create a principle for the MongoDB service running on each host. The following command will create the principle within the domain using a random key. Replace <fqdn> with the fully qualified domain name of the machine on which MongoDB will be running.

kadmin -q "addprinc -randkey mongodb/<fqdn>"

Creating a Keytab File for the MongoDB Server

With the principle created we now export the key for the principle to a keytab file for the MongoDB process to use. The permissions on the keytab file should be checked to ensure that the file is read-only and only the runtime MongoDB user can read the file. For the command below, we have placed the keytab file in /opt/mongdb but can be in any secured location on the file system.

mkdir -p /opt/mongodb/
kadmin -q "ktadd -k /opt/mongodb/mongodb.keytab mongodb/<fqdn>"

Starting MongoDB Server with Kerberos Support

To start a MongoDB server with Kerberos support multiple command line options and environment variables must be used.

--auth option
Enables authentication on the server.
--setParameter option
Enables the authentication modes. Initially, it is recommended to use the option with the authenticationMechanisms=GSSAPI,MONGODB-CR argument to enable support for Kerberos and traditional challenge response. Once the Kerberos authentication is working the user can switch to just GSSAPI.
--keyFile option
If running a cluster of servers, this option provides the mechanism for the servers to authenticate to each other. All servers must have access to a copy of identical key files.
KRB5_KTNAME Environment Variable
Contains the fully qualified path to the keytab file created above, e.g., /opt/mongodb/mongod.keytab.

For a single stand-alone server the command would look like:

KRB5_KTNAME=/opt/mongodb/mongodb.keytab                          \
mongod --auth                                                    \
       --setParameter authenticationMechanisms=GSSAPI,MONGODB-CR \
       --dbpath /opt/mongodb/data                                \
       --logpath /opt/mongodb/log/mongod.log                     \
       --fork

For more information on running and debugging MongoDB with Kerberos Support see the MongoDB Tutorial

Notes

Kerberos support is provided via the driver's extensions jar available to license holders. Any attempt to add a credential to a configuration using Kerberos will throw an IllegalArgumentException without the extensions jar on the classpath. Please contact Allanbank Consulting, Inc. for information on licensing the driver and obtaining the extensions jar.