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:
With a working Kerberos environment the driver supports three modes for Kerberos authentication:
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, ' ' );
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.
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>"
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.
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.
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.
Regardless of the mode you are using with the driver the following options can be used with Kerberos authentication.
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, ' ' );
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>"
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>"
To start a MongoDB server with Kerberos support multiple command line options and environment variables must be used.
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
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.