The database administrators in a large enterprise may need to configure MongoDB to support Kerberos Authentication. The configuration of MongoDB with authentication is very simple, provided you have some Kerberos knowledge. The MongoDB documentation article, , is pretty extensive on this topic. However, the article states — , resulting in some of the starters/enthusiasts with limited knowledge in Kerberos not proceed any further. This article is geared more towards bridging that gap and to help you understand MongoDB Kerberos Configure MongoDB with Kerberos Authentication on Linux “Setting up and configuring a Kerberos deployment is beyond the scope of this document” How Kerberos Works How to set up Kerberos and MongoDB in your lab Finally, How to integrate MongoDB with Kerberos authentication This is one of the many articles in multi-part series, , solely created for you to master by learning . In a few series of articles, I would like to give various tips to tighten the security on MongoDB. In this article, I would discuss “ . Mastering MongoDB — One tip a day MongoDB ‘one tip a day’ How to Integrate MongoDB with Kerberos Authentication” Mastering — MongoDB with Kerberos Authentication What is a Kerberos is a computer network authentication protocol. It is designed to provide strong authentication for client/server applications by using secret-key cryptography. It works on the basis of tickets to allow nodes communicating over a non-secure network, to prove their identity to one another in a secure manner. The protocol messages are protected against eavesdropping and replay attacks. The was named after the character Kerberos (or ) from Greek mythology, the ferocious three-headed guard dog of Hades. Kerberos Kerberos protocol Cerberus How does Kerberos work Instead of asking the client to enter username/password credentials for every service they access, the Kerberos allows single sign-on by using the tickets. These are issued by a trusted 3rd party (Key Distribution Center) and are typically encrypted with a secret/symmetric key. This section discusses how various resources within the Kerberos Realm interacts with each other during the authentication process. proof of identity tickets Key Distribution Center In order to administer the access to a resource via Kerberos, all of the components, services, and users must be in the . The Kerberos Distribution Center (KDC) is at the core of the Kerberos Realm and has following key server components Kerberos Realm — Stores secret keys of registered users and Services Database Server — Provides a ticket to access Ticket-Granting Server Authentication Server — Provides a ticket to access the service of interest Ticket-Granting Server The KDC’s database stores all of the secret keys for user machines and services. The secret keys are in-turn a hash value of the password plus a salt. The database itself is further encrypted with a to prevent anyone stealing keys from the database’s file system. master key The flow of events during the authentication process Let’s say you want to access the MongoDB Service using Kerberos authentication. During the authentication process, the following resources process/exchange information with a defined objective Client. Objective: Login using kinit Client and Authentication Service. Objective: Get Ticket-Granting-Ticket Client and Ticket-Granting Service. Objective: Get Service Ticket Client and MongoDB Service. Objective: Get access to MongoDB Service The sequence of events occurring during Kerberos authentication process The above diagram shows various resources/components involved in the authentication process and illustrates how they interact with each other. Let’s try to understand the internal details of each step. Kerberos Please pay special attention to the color of the lock icon, an encrypted message. It can only be decrypted by the resource having the same colored secret key. Login using kinit The (AKA Client/Principal) must introduce themselves to the by logging into the computer, or by running the command kinit <username> User Authentication Server Communication between the User and the Authentication Server Every must have a (TGT) issued by before accessing any . The is a ticket that allows the user to get for accessing services of their interest. User Ticket-Granting Ticket Authentication Server Service TGT Tickets The User’s objective is to get a by sending a request to . The request message contains Ticket-Granting Ticket Authentication Server Username: Username / Client ID Service Requested: Ticket-Granting Service Network Address: Client’s IP Address Expiration: Lifetime of TGT Timestamp: When the request message was created The processes the request and checks if in the message is within 5 min, checks if the and requested are in KDC. It finally issues a generates and shares with the Authentication Server Timestamp User Service Ticket-Granting Ticket, Ticket-Granting Session Key User. The responds to the User’s request with two messages. The Response #1 is encrypted with Client Secret Key (Cyan color key) and the message has below contents — Authentication Server Service: Ticket-Granting Service Timestamp: When it was created Validity: Lifetime of TGT TGS Session Key (Magenta color key ) The Response #2 is , TGT, which is encrypted with TGS Secret Key (Yellow color key). It can only be decrypted by . The message has below contents — Ticket Granting Ticket KDC Username: Your Name / ID Service: Ticket-Granting Service Timestamp: When it was created Network Address: IP Address Validity: Lifetime of TGT TGS Session Key The processes response and decrypts Response #1 using the User's Secret Key (Cyan color key). Upon successful decryption, both the and the has TGS Session Key (Magenta color key ). The TGS Session Key is used for encrypting the communication between the Client and the The Client cannot decrypt the Response #2, , as it does not have but it would be stored within client’s credential cache. Client Authentication Service User KDC Ticket Granting Server. TGT TGS Secret Key Communication between the User and the Ticket-Granting Server With the in hand, the client can request Ticket-Granting Server for a ticket to access the MongoDB Service. Upon validating the , the will issue a Service Ticket, to request access for . Ticket-Granting Ticket TGT Ticket Granting Server STKT, MongoDB Server The User’s objective is to get a by sending a request to . The Request #1 message has below contents — Service Ticket Ticket Granting Server Validity: Lifetime of TGT Service Requested: MongoDB Service (only KDC can decrypt) Ticket-Granting Ticket The Request #2 is encrypted with TGS Secret Key (Magenta color key) and the message has below contents — Username: Your Name / ID Timestamp: When it was created The processes the request, checks if in the message is within 5 min, checks if the service MongoDB Service is registered with KDC. It finally issues a generates and shares (Royal Blue color key) with the Ticket-Granting Server Timestamp Service Ticket, MongoDB Service Session Key User. The responds to the User’s request with two messages. The Response #1 is encrypted with TGS Session Key (Magenta color key) and the message has below contents — Ticket Granting Server Service Requested: MongoDB Service Timestamp: When it was created Validity: Lifetime of TGT Service Session Key (Royal Blue key ) The Response #2 is encrypted with MongoDB Secret Key (Green color key) and can be decrypted only by . The message has below message contents — MongoDB Server Username: Your Name / ID Service: MongoDB Service Timestamp: When it was created Network Address: IP Address Validity: Lifetime of STKT MongoDB Service Session Key The MongoDB Service Session Key is used for encrypting the communication between the and the The Client cannot decrypt the Response #2, , as it does not have but it would be stored within the client’s credential cache. User MongoDB server. STKT MongoDB Secret Key Communication between the User and the MongoDB Service With the in hand, the client can send a login request to MongoDB Server. The MongoDB Server will validate the and sets the authorized roles and privileges for the User's login session. Service Ticket Service Ticket The User’s objective is to get access to by sending a login request to . The Request #1 is encrypted with (Royal Blue color key) and the message has below contents — MongoDB Service MongoDB Server MongoDB Session Key Username: Your Name / ID Timestamp: When it was created The Request #2 is the itself which can be decrypted only by using it’s (Green color key). The message has below contents — Service Ticket MongoDB Server Secret Key Username: Your Name / ID Service: MongoDB Service Timestamp: When it was created Network Address: IP Address Validity: Lifetime of STKT MongoDB Service Session Key The processes the request, checks if in the message is within 5 min, checks if the is registered with the database. It finally sets the roles and privileges for the MongoDB Server Timestamp User User. The responds to the User’s request with a message. The Response #1 is encrypted with MongoDB Session Key (Royal Blue color key) and the message has below contents — MongoDB Server Username: Your Name / ID Service: MongoDB Service The processes response and decrypts Response #1 using the (Royal Blue color key). Upon successful decryption, and validation, the Client would communicate directly with the for further database requests. Client MongoDB Service MongoDB Session Key MongoDB Server I know it’s a lot of information to digest especially if you have no knowledge of Kerberos. For further reading on Kerberos, I strongly recommend you to read article and/or watch the YouTube video by . Lynn Root’s Explain like I’m 5: Kerberos Kerberos — CompTIA Security Professor Messer Hands-On lab exercises Now that you understood the theory and information flow during Kerberos authentication, let's work on setting up a lab environment. This lab exercise helps you understand how to set up Kerberos, MongoDB and configure a client to use them on a CentOS 7.5. Setup environment First, you would need an environment to play around. In this example, I have created 3 AWS EC2 instances, one for each server — KDC, MongoDB Server and User machine. If you are short on resources, you could potentially install them all on the same lab server. Please make sure to to allow incoming traffic on ports 88, 749, 27017 for respective services. configure your firewall/security groups sudo yum install -y ntp sudo ntpdate 0.rhel.pool.ntp.org sudo systemctl start ntpd.service sudo systemctl ntpd.service | sudo tee -a /etc/hosts | sudo tee -a /etc/hosts | sudo tee -a /etc/hosts # Run these commands on all 3 servers # Install NTP to synchronize the clock on all three servers enable # Fix the below ip addresses based on your lab environment TODO: echo "172.31.10.101 kdc.mdbkrb5.net" echo "172.31.10.102 mdb01.mdbkrb5.net" echo "172.31.10.103 client01.mdbkrb5.net" A bash script to install ntpd service on all three servers (KDC, MongoDB Server and User machine) Installing & Configuring KDC Server Login to the KDC server to install/configure the Kerberos Server. sudo yum install -y krb5-server sudo sed -i /var/kerberos/krb5kdc/kdc.conf sudo sed -i /var/kerberos/krb5kdc/kadm5.acl sudo sed -i /etc/krb5.conf sudo sed -i /etc/krb5.conf sudo sed -i /etc/krb5.conf sudo sed -i /etc/krb5.conf sudo sed -i /etc/krb5.conf # Rename the Kerberos Realm name from EXAMPLE.COM to MDBKRB5.NET, or any name of your choice 's/EXAMPLE.COM/MDBKRB5.NET/g' 's/EXAMPLE.COM/MDBKRB5.NET/g' 's/kerberos.example.com/kdc.mdbkrb5.net/g' 's/example.com/mdbkrb5.net/g' 's/EXAMPLE.COM/MDBKRB5.NET/g' 's/#//g' 's/^ Configuration/# Configuration/g' A bash script to install Kerberos server on KDC server and configure the files with MDBKRB5.NET realm For your convenience, I am illustrating how the file contents would look like after running the above commands. # : /etc/krb5. # Configuration snippets may be placed this directory well includedir /etc/krb5. . / [logging] default = :/ / /krb5libs. kdc = :/ / /krb5kdc. admin_server = :/ / /kadmind. [libdefaults] dns_lookup_realm = false ticket_lifetime = 24h renew_lifetime = 7d forwardable = true rdns = false default_realm = MDBKRB5. default_ccache_name = KEYRING:persistent:%{uid} [realms] MDBKRB5. = { kdc = kdc.mdbkrb5. admin_server = kdc.mdbkrb5. } [domain_realm] .mdbkrb5. = MDBKRB5. mdbkrb5. = MDBKRB5. # : / /kerberos/krb5kdc/kdc. [kdcdefaults] kdc_ports = 88 kdc_tcp_ports = 88 [realms] MDBKRB5. = { #master_key_type = aes256-cts acl_file = / /kerberos/krb5kdc/kadm5.acl dict_file = /usr/share/dict/words admin_keytab = / /kerberos/krb5kdc/kadm5.keytab supported_enctypes = aes256-cts:normal aes128-cts:normal des3-hmac-sha1:normal arcfour-hmac:normal camellia256-cts:normal camellia128-cts:normal -hmac-sha1:normal -cbc-md5:normal -cbc- : } # : / /kerberos/krb5kdc/kadm5.acl File conf in as conf d FILE var log log FILE var log log FILE var log log NET NET net net net NET net NET File var conf NET var var des des des crc normal File var */admin@MDBKRB5.NET * The file contents of Kerberos configuration files Next, you need to create a Kerberos database for the Realm and create the Principal entries for the Users, Services etc sudo kdb5_util create -s -r MDBKRB5.NET sudo systemctl start krb5kdc.service sudo systemctl start kadmin.service sudo systemctl krb5kdc.service sudo systemctl kadmin.service sudo kadmin.local addprinc root/admin addprinc alex addprinc bob addprinc host/kdc.mdbkrb5.net addprinc mongodb/mdb01.mdbkrb5.net q # Create Kerberos database for the realm # Loading random data # Initializing database '/var/kerberos/krb5kdc/principal' for realm 'MDBKRB5.NET', # master key name 'K/M@MDBKRB5.NET' # You will be prompted for the database Master Password. # It is important that you NOT FORGET this password. # Enter KDC database master key: # Re-enter KDC database master key to verify: enable enable # Set up a Kerberos principal with admin privileges # and principal for the users, KDC host, and MongoDB server # for simplicity I used <user/service name>@123 as the password # Commands you need to run # Authenticating as principal root/admin@MDBKRB5.NET with password. # kadmin.local: # Run the below commands at kadmin.local prompt # Enter password for principal "root/admin@MDBKRB5.NET": # Re-enter password for principal "root/admin@MDBKRB5.NET": # Principal "root/admin@MDBKRB5.NET" created. # Enter password for principal "alex@MDBKRB5.NET": # Re-enter password for principal "alex@MDBKRB5.NET": # Principal "alex@MDBKRB5.NET" created. # Enter password for principal "bob@MDBKRB5.NET": # Re-enter password for principal "bob@MDBKRB5.NET": # Principal "bob@MDBKRB5.NET" created. # Enter password for principal "host/kdc.mdbkrb5.net@MDBKRB5.NET": # Re-enter password for principal "host/kdc.mdbkrb5.net@MDBKRB5.NET": # Principal "host/kdc.mdbkrb5.net@MDBKRB5.NET" created. # Enter password for principal "mongodb/mdb01.mdbkrb5.net@MDBKRB5.NET": # Re-enter password for principal "mongodb/mdb01.mdbkrb5.net@MDBKRB5.NET": # Principal "mongodb/mdb01.mdbkrb5.net@MDBKRB5.NET" created. A bash script to create a Kerberos database for the Realm and create the Principal entries for the Users, Services etc Setup the MongoDB Server Login to the MongoDB server to install/configure the MongoDB Server, mdb01.mdbkrb5.net sudo yum install -y krb5-workstation sudo cat /etc/krb5.conf # Install the Kerberos client # Copy the /etc/krb5.conf file contents from TODO: # Kerberos Server's config file to MongoDB server A bash script to install the Kerberos client and display the Kerberos configuration file Next, you would need to install the MongoDB Enterprise server, create the MongoDB keyfile, configure the /etc/mongod.conf file, etc sudo tee /etc/yum.repos.d/mongodb-enterprise.repo << EOF [mongodb-enterprise] name=MongoDB Enterprise Repository baseurl=https://repo.mongodb.com/yum/redhat/\ /mongodb-enterprise/4.0/\ / gpgcheck=1 enabled=1 gpgkey=https://www.mongodb.org/static/pgp/server-4.0.asc EOF sudo yum install -y mongodb-enterprise sudo setenforce 0 sudo sed -i /etc/selinux/config sudo tee /etc/mongod.conf << EOF systemLog: destination: file logAppend: path: /var/ /mongodb/mongod.log storage: dbPath: /var/lib/mongo journal: enabled: processManagement: fork: pidFilePath: /var/run/mongodb/mongod.pid timeZoneInfo: /usr/share/zoneinfo net: port: 27017 bindIp: 0.0.0.0 security: authorization: enabled keyFile: /var/lib/mongo/private/keyfile sasl: hostName: mdb01.mdbkrb5.net replication: replSetName: rs0 setParameter: authenticationMechanisms: GSSAPI,SCRAM-SHA-256 EOF sudo mkdir -p /var/lib/mongo/private openssl rand -base64 756 | sudo tee /var/lib/mongo/private/keyfile sudo chmod 400 /var/lib/mongo/private/keyfile $releasever $basearch # Install the MongoDB server ## Disable the selinux 's/SELINUX=enforcing/SELINUX=disabled/g' # Configure mongod.conf with Kerberos settings true log true true # fork and run in background # location of pidfile # <-- Exposes MongoDB to Public IP. Please use internal IPs instead TODO: # Create a directory to store MongoDB keyfile and Kerberos keytab file A bash script to install the MongoDB and set the MongoDB configuration files Create a keytab file to store Kerberos service principals and encrypted keys sudo ktutil addent -password -p mongodb/mdb01.mdbkrb5.net -k 2 -e aes256-cts write_kt /var/lib/mongo/private/mon01.keytab q # ktutil: # Run the below commands at ktutil prompt # Password for mongodb/mdb01.mdbkrb5.net@MDBKRB5.NET: A bash script to help you create the Kerberos keytab file Set the folders permissions to only allow the user mongod to read them. sudo klist -k /var/lib/mongo/private/mon01.keytab | sudo tee /etc/sysconfig/mongod sudo chown -R mongod:mongod /var/lib/mongo/private sudo systemctl start mongod # Keytab name: FILE:/var/lib/mongo/private/mon01.keytab # KVNO Principal # ---- ------------------------------------------ # 2 mongodb/mdb01.mdbkrb5.net@MDBKRB5.NET # Set the keytab file location in environment variable echo "KRB5_KTNAME=/var/lib/mongo/private/mon01.keytab" # Change the folder ownership to mongod A bash script to configure environment variables and set permissions for the folders Finally, let’s create the following in MongoDB server superuser with root privileges alex Principal with role on database root admin bob Principal with role on database readWrite social mongo --quiet admin <<EOF rs.initiate(); sleep(10000); db.createUser({user: , : , roles: [ ]}); db.auth( , ); use \ ; db.createUser({user: , roles: [{ role: , db: }]}); db.createUser({user: , roles: [{ role: , db: }]}); EOF 'superuser' pwd 'superuser' 'root' 'superuser' 'superuser' $external 'alex@MDBKRB5.NET' 'root' 'admin' 'bob@MDBKRB5.NET' 'readWrite' 'social' # { # "info2": "no configuration specified. Using a default configuration for the set", # "me": "ip-172-31-10-102.us-west-2.compute.internal:27017", # "ok": 1 # } # Successfully added user: { # "user": "superuser", # "roles": ["root"] # } # 1 # switched to db $external # Successfully added user: { # "user": "alex@MDBKRB5.NET", # "roles": [{ # "role": "root", # "db": "admin" # }] # } # Successfully added user: { # "user": "bob@MDBKRB5.NET", # "roles": [{ # "role": "readWrite", # "db": "social" # }] # } # bye A bash script using mongo client to create replica set and user privileges on $external database Install MongoDB client on the client01.mdbkrb5.net Login to the MongoDB client server to install the Kerberos and MongoDB clients. sudo yum install -y krb5-workstation sudo cat /etc/krb5.conf # Install the Kerberos client # Copy the /etc/krb5.conf file contents from TODO: # Kerberos Server's config file to the Client's machine A bash script to install the Kerberos client and display the Kerberos configuration file on the User machine First, install the MongoDB shell and Enterprise dependencies using . Yum sudo tee /etc/yum.repos.d/mongodb-enterprise.repo << EOF [mongodb-enterprise] name=MongoDB Enterprise Repository baseurl=https://repo.mongodb.com/yum/redhat/\ /mongodb-enterprise/4.0/\ / gpgcheck=1 enabled=1 gpgkey=https://www.mongodb.org/static/pgp/server-4.0.asc EOF sudo yum install -y cyrus-sasl cyrus-sasl-gssapi cyrus-sasl-plain krb5-libs libcurl libpcap lm_sensors-libs net-snmp net-snmp-agent-libs openldap openssl rpm-libs tcp_wrappers-libs sudo yum install -y mongodb-enterprise-shell-4.0.2 $releasever $basearch # Install the mongodb enterprise dependencies and mongodb shell A bash script to install the MongoDB shell and the MongoDB Enterprise dependencies Login to the Kerberos as and then log in to the to test the permissions on the database. bob MongoDB Server readWrite social kinit -p bob klist mongo social --quiet --host mdb01.mdbkrb5.net --authenticationMechanism=GSSAPI --authenticationDatabase= --username bob@MDBKRB5.NET db.people.insert({fname: , lname: }) db.people.findOne() use admin show collections # Login into the Kerberos as bob # Password for bob@MDBKRB5.NET: # Ticket cache: KEYRING:persistent:1000:1000 # Default principal: bob@MDBKRB5.NET # Valid starting Expires Service principal # 10/04/2018 16:58:49 10/05/2018 16:58:48 krbtgt/MDBKRB5.NET@MDBKRB5.NET '$external' # MongoDB Enterprise rs0:PRIMARY> # Run the below commands at rs0:PRIMARY prompt # db.runCommand({connectionStatus: 1}).authInfo # { # "authenticatedUsers": [ # { # "user": "bob@MDBKRB5.NET", # "db": "$external" # } # ], # "authenticatedUserRoles": [ # { # "role": "readWrite", # "db": "social" # } # ] # } # Test the write privilege on social database 'Shyam' 'Arjarapu' # WriteResult({ "nInserted" : 1 }) # Test the read privilege on social database # { # "_id" : ObjectId("5bb647a8315c61d11c361945"), # "fname" : "Shyam", # "lname" : "Arjarapu" # } # Note that bob has no previleges on admin database # switched to db admin # Warning: unable to run listCollections, attempting to approximate collection names by parsing connectionStatus A bash script illustrating authentication to MongoDB via Kerberos SSO and authorization on MongoDB If you run the same tests for the user, alex, then you would be able to query both and databases because of his role. social admin root Summary As stated at the beginning of the article — . However, without proper Kerberos knowledge, your hands are pretty much tied-down to do a simple . “Configuring MongoDB with Kerberos Authentication is very simple!” POC Hopefully, this article has simplified the understanding of Kerberos events, and shed some light on . “How to integrate MongoDB with Kerberos Authentication” The MongoDB Enterprise provides integration with Kerberos as well as LDAP authentication mechanisms. Although the MongoDB is using Kerberos Authentication, the user management still requires the User privileges to be created in the MongoDB. If your organization has 100s of users requiring access to MongoDB then you may to explore the use of LDAP for both authentication and authorization. But that’s a topic for another day. Hopefully, you learned something new today as you scale the path to “ ”. Mastering MongoDB — One tip a day Previously published articles Tip # 005: Now you could deploy MongoDB in Kubernetes under a minute Getting started with MongoDB Enterprise Operator Tip # 004: Measures to reduce the election time during the rolling maintenance Faster elections Tip # 003: A long awaited and most requested feature for many, has finally arrived Transactions Tip # 002: Ahhh …! Someone just dropped a collection createRole Tip # 001: Know the operations currently executing on MongoDB server inside out currentOp