MongoDB Configuration Guide to CIS Benchmark Compliance | Lucideus

This article provides detailed guidelines to establish a secure configuration posture for MongoDB community 3.4 which is CIS benchmark compliant. It does not cover the recommendations for sharded clusters.

CIS(Centre for Internet Security) is a nonprofit organization.  Its mission is to "identify, develop, validate, promote, and sustain best practice solutions for cyber defense and build and lead communities to enable an environment of trust in cyberspace".

CIS Benchmark provides prescriptive guidance for establishing a secure configuration posture for your IT Infrastructure, including a detailed description and rationale of potential vulnerabilities together with clear auditing and remediation steps.

Scoring Information of CIS Benchmark- A scoring status indicates whether compliance with the given recommendation impacts the accessed target’s benchmark score.The scoring status used are-

Scored- Failure to comply with “Scored” recommendations will decrease the finals benchmark score. Compliance with “Scored” recommendations will increase the final benchmark score.

Not Scored- Failure to comply with “Not Scored” recommendations will not decrease the final benchmark score. Compliance with “Not Scored” recommendations will not increase the final benchmark score. 

Profile Definitions of CIS Benchmark 
Level 1- Items in this profile apply to MongoDB running on Linux or Windows and intend to - 
  • Be practical and prudent,
  • Provide a clear security benefit,
  • Not inhibit the utility of the technology beyond acceptable means.
Level 2-  This profile extends the “Level 1” profile. Items in this profiles apply to MongoDB running on linux or Windows and exhibit one or more of the following characteristics-
  • Are intended for environments or use cases where security is paramount
  • Acts as defense in depth measure
  • May negatively inhibit the utility or performance of the technology.
Guidelines

1. Installation and patching
1.1 Ensure the appropriate MongoDB software version/patches are installed(Scored, Level 1)- The MongoDB installation version, along with patch level, should be more recent that is compatible with the organisation’s operational needs.

Installation Steps:
  • Import public key used by package management system-
sudo apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv 0C49F3730359A14518585931BC711F9BA15703C6
Output- 

  • Create the /etc/apt/sources.list.d/mongodb-org-3.4.list list file-                                            
    echo "deb [ arch=amd64,arm64 ] http://repo.mongodb.org/apt/ubuntu  xenial/mongodb-org/3.4 multiverse" | sudo tee /etc/apt/sources.list.d/mongodb-org-3.4.list
  • Reload local package database-
    sudo apt-get update
    Output-

    Install the latest stable version of MongoDB-
    sudo apt-get install -y MongoDB-org
    Output-


    Run MongoDB-

    • Start MongoDB-



    sudo service mongod start/restart
    Note: Mongod can be started using - mongod --port <port number> --dbpath <path to data folder>/data/db1
    The difference between the command is that the first one takes default parameters and also runs as the background process, and as root.


    Verify that MongoDB started successfully
    cat /var/log/mongodb/mongod.log
    Search for-
    [initandlisten] waiting for connections on port <port>
    Where <port> is the port configured in /etc/mongod.conf, 27017 by default.


    Start mongo shell on the same host as mongod-
    mongo --host 127.0.0.1:27017



    Stop MongoDB-
    sudo service mongod stop


    2. Authentication
    2.1 Ensure that authentication is enabled for MongoDB databases(Scored,Level 1)- This setting ensures that all the clients, users, and/or servers are required to authenticate prior to being granted access to the MongoDB database.
    Steps:


    • Start mongoDb without authentication:



    mongod --port <port number> --dbpath <path to data folder>/data/db

    • Start mongo shell -
    • Create the system user administrator, ensuring that its password meets organizationally-defined password complexity requirements-

    mongo
    use admin
    db.createUser(
    {
    user: "username",
    pwd: "password",
    roles: [ { role: "userAdminAnyDatabase", db: "admin" } ]
    } )
    Output-



    • Restart the MongoDB instance with authentication enabled-
    mongod --auth --port <port number> --dbpath=<path to data folder>/data/db1
    • To authenticate during connecting -
    mongo -u "username" -p "password" --authenticationDatabase "databasename"

    To authenticate after connecting-
    use admin
    db.auth("username", "password" )


    2.2 Ensure that MongoDb does not bypass authentication via the localhost exception(Scored, Level 1)


    Disabling this exception will prevent unauthorized local access to mongoDB database.It also ensure traceability of each database activity to a specific user.
    Since enableLocalhostAuthBypass is not available using the setParameter database
    setParameter:
    command, use the setParameter option in the configuration file to set it to false.
    enableLocalhostAuthBypass:false
    Note- the --setParameter option on the command line may also be used to configure this;
    However, having it in config file may provide greater confidence that this setting is configure
    correctly in every instance.

    2.3 Ensure an industry standard authentication mechanism is used(Scored, Level 2)

    Using one or more industry standard authentication mechanisms helps organizations enforce their account and password policies for their MongoDB users. Sample of MongoDb with Kerberos
    Authentication(supported by MongoDB Enterprise) on Linux is - Security: authorization:enabled setParameter: authenticationMechanisms: GSSAPI Storage:
    dbPath: /opt/mongodb/data

    3. Access Control

    3.1 Ensure that role-based access control is enabled and configured appropriately(Level 1, Scored)

    RBAC enables users to carry out a wide range of authorized tasks by dynamically regulating their actions according to flexible functions.

    • Establish roles for mongoDB and assign appropriate privileges to each role
    To create a role-
    use admin
    db.createRole
    (
    {
     role: "<name>",
      privileges: [
         { resource: { <resource> }, actions: [ "<action>", ... ] },
         ...
      ],
      roles: [
         { role: "<role>", db: "<database>" } | "<role>",
        ...
      ],
      authenticationRestrictions: [
        {
          clientSource: ["<IP>" | "<CIDR range>", ...],
          serverAddress: ["<IP>" | "<CIDR range>", ...]
        },
        ...
      ]
    }
    )

    Description
    Role: The name of new role

    Privileges: The privileges to grant the role. A privilege consists of a resource upon which privilege actions will apply.Privileges field must be included. Use an empty array to specify no privileges.

    Roles- An array of roles from which this role inherits privileges.Roles field must be included. Use an empty array to specify no roles to inherit from.

    authenticationRestrictions(optional)-The authentication restrictions the server enforces on the role.Specifies a list of IP addresses and CIDR ranges users granted this role are allowed to connect to and/or which they can connect from.

    To view the role-                                                         
     db.getRole(<rolename>,{showPrivilages:true})

    To view all the roles-                                                                                                        db.getRoles()

    To grant privileges to role-
     db.runCommand(
    {
      grantPrivilegesToRole: "<role>",
                privileges: [
          {
    resource: { <resource> }, actions: [ "<action>", ... ]
          },
          …
      ]
    }
    )

    OR

    db.grantPrivilegesToRole(
        "<rolename>",
         [
            { resource: { <resource> }, actions: [ "<action>", ... ] },
            ...
        ]
    )

    To grant roles to role- 
    db.runCommand(
    { grantRolesToRole: "<role>",
      roles: [
                 { role: "<role>", db: "<database>" },
                 ...
             ]
    })

    To grant roles to user-
    db.grantRolesToUser(
        “<user name>”,
        [
          { role: “<role>”, db: "<database>”}
         ]
    )

    To view roles granted to an user-
    db.getUser(“<username>”)

    3.2 Ensure that MongoDB only listens for network connections on authorized interfaces(Level 1, Scored)
    Configure the MongoDB configuration file to limit its exposure to only the network interfaces on which MongoDB instances should listen for incoming connections. 

    Configure Linux iptables firewall for MongoDB-
    • Traffic to and from mongod instances -This pattern is applicable to all mongod instances running as standalone instances or as part of a replica set.The goal of this pattern is to explicitly allow traffic to the mongod instance from the application server.
    iptables -A INPUT -s <ip-address> -p tcp --destination-port 27017 -m state --state
    NEW,ESTABLISHED -j ACCEPT
    iptables -A OUTPUT -d <ip-address> -p tcp --source-port 27017 -m state --state 
    ESTABLISHED -j ACCEPT

    • Change the default policy to DROP -The default policy for iptables chains is to allow all traffic. After completing all iptables configuration changes, do change the default policy to DROP so that all traffic that isn’t explicitly allowed  will not be able to reach components of the MongoDB deployment.
    iptables -P INPUT DROP
            iptables -P OUTPUT DROP

    • Make all iptables rules persistent- By default all iptables rules are only stored in memory. When system restarts, firewall rules will revert to their defaults. When a rule set is tested and have guaranteed that it effectively controls traffic the following operations can be used to make the rule set persistent.
    iptables-save > /etc/iptables.conf 

    To restore the network rules:
    iptables-restore < /etc/iptables.conf

    To list all iptables rules- 
    Iptables -L

    To flush all iptables rules- 
    Iptables -F


    3.3 Ensure that MongoDB is run using a non- privileged,dedicated service account(Level 1, Scored): The MongoDB service should not be run using a privileged account such as ‘root’ because this exposes the operating system to high risk. 

    • Create a dedicated user for performing MongoDB database activity.
    • Set database datafiles to only be readable by mongod users
    • Set SSL private key files to only be readable by mongod user(explained later).
    • Set log files to only be writable by mongod user and readable only by root(change file permissions).
    3.4 Ensure that each role for each MongoDB database is needed and grants only the necessary privileges( Level 2, Scored): All the roles should be reviewed periodically  and unneeded roles as well as unneeded privileges from roles should be eliminated.

    To revoke specific privileges from user defined role-
    db.runCommand(
    {
     revokePrivilegesFromRole: "<role>",
    privileges: 
    {
    resource: { <resource> }, actions: [ "<action>", ... ]
    }, …
     ]
    }
    )

    OR

    db.revokePrivilegesFromRole(
      "<rolename>",
      [
        { resource: { <resource> }, actions: [ "<action>", ... ] },
          ...
       ]
    )

    3.5 Review User-Defined Roles(Level 2, Scored):  Reviewing all roles periodically and removing all users from roles  who do not need to belong to them helps minimize the privileges that each user has.

    To revoke role from user- 
    db.revokeRolesFromUser(
        “<user name>”,
        [
          { role: “<role>”, db: "<database>”}
      ]
    )

    3.6 Review Super/Admin Roles(Level 2,Scored) : Reviewing the SuperUser/Admin roles within a database helps minimize the possibility of privileged unwanted access.

    4. Data Encryption

    4.1 Ensure TLS or SSL protects all network communications(Level 1, Scored): Use TLs or SSL to protect all incoming and outgoing connections. This prevents sniffing of cleartext traffic between MongoDB components or performing a man-in-the-middle attack for MongoDB.

    In the configuration file /etc/mongod.conf , set the PEMKeyFile option to the certificate file’s 
    path 
    net:
       ssl:
         mode: requireSSL
         PEMKeyFile: /etc/ssl/mongodb.pem
         CAFile: /etc/ssl/ca.pem  
    Where-
    PEMKeyfile with the name of the .pem file that contains the signed TLS/SSL certificate and
    key.
    CAFile with the name of the .pem file that contains the root certificate chain from the
    Certificate Authority.
    Modes- 
    • Disabled- The server does not user TLS/SSL.
    • allowSSL- Connections between servers do not use TLS/SSL. For incoming connections, the server accepts both TLS/SSL and non-TLS/non-SSL.
    • preferSSL- Connections between servers use TLS/SSL. For incoming connections, the server accepts both TLS/SSL and non-TLS/non-SSL.
    • requireSSL- The server uses and accepts only TLS/SSL encrypted connections.
    Start mongodb instance - mongod --config /etc/mongod.conf 
    Or 
    mongod --sslMode requireSSL --sslPEMKeyFile /etc/ssl/mongodb.pem --sslCAFile /etc/ssl/ca.pem <additional options>

    4.2 Ensure Federal Information Processing Standard(FIPS) is enabled(Level 1, Scored)
    The FIPS is a computer security standard used to certify software modules and libraries that encrypt and decrypt data securely.FIPS is industry standard that dictates how data should be encrypted in rest and during transmission. 

    Add the below in configuration file after mongod for TLS/SSL is configured.
    net:
            ssl:
          FIPSMode: true

    Start mongod instance with configuration file-
    Mongod --config /etc/mongod.conf


    5. Auditing(feature provided in MongoDB Enterprise)

    5.1 Ensure that system activity is audited( Level 1, Scored)
    Track access and changes to database configurations and data. MongoDB enterprise includes a system auditing facility that can record system events on a MongoDB instance. System level logs can be handy while troubleshooting an operational problem or handling a security incident.

    To enable auditing and print audit events in syslog set auditLog.destination in /etc/mongod.conf -
    auditLog:
            destination: syslog
    Or
    Mongod --dbpath <path to d folder> --auditDestination syslog

    To enable auditing and print audit events to standard output set auditLog.destination in /etc/mongod.conf -
    auditLog:
            destination: console
    Or
    Mongod --dbpath <path to d folder> --auditDestination console

    To enable auditing and print audit events to a file in JSON  format specify these options in /etc/mongod.conf-
    auditLog:
         destination: file
         format: JSON
         path: <path to db folder>/auditLog.json
    Or
    mongod --dbpath data/db --auditDestination file --auditFormat JSON --auditPath <path
    to db folder>/auditLog.json

    Note- Printing audit events to file in JSON format degrades server performance more than
    printing to a file in BSON format.

    To enable auditing and print audit events to a file in BSON binary format specify these options in /etc/mongod.conf-
    auditLog:
       destination: file
       format: BSON
       path: <path to db folder>/auditLog.bson

    Or

    mongod --dbpath data/db --auditDestination file --auditFormat BSON --auditPath <path
    to db folder>/auditLog.bson

    5.2 Ensure that audit filters are configured properly(Level 1, Scored)
    MongoDB Enterprise supports auditing of various operations. To specify which events to record ,auditFilter option is available. Configure the option either in configuration file or command line according to the requirement. 

    The following example audits only createCollection action by using filer- 
    mongod --dbpath data/db --auditDestination file --auditFilter '{ atype: { $in: [ "createCollection", "dropCollection" ] } }' --auditFormat BSON --auditPath data/db/auditLog.bson

    Or 

    storage:
       dbPath: data/db
    auditLog:
       destination: file
       format: BSON
       path: data/db/auditLog.bson
       filter: '{ atype: { $in: [ "createCollection", "dropCollection" ] } }'

    5.3 Ensure that logging captures as much information as possible(Level 2, Not scored)
    The information should be logged whenever possible. The systemLog.quiet option stops logging of informations such as connection events, authentication events, replication sync activities and evidence of some potentially impactful commands being run. Set option to false in /etc/mongod.conf-
    systemLog:
         Quiet:false

    5.4 Ensure that new entries are appended to the end of the log files(Level 2, Not scored)
    By default, new log entries will overwrite old entries after a restart of the mongod service. ENabling the systemLog.logAppend setting causes new entries to be appended to the end of the log file rather than overwriting the existing content of the log when the instance restarts.  Set option to true in /etc/mongod.conf-
    systemLog:
         logAppend :true

    6. Operating System Hardening

    6.1 MongoDb database running with least privileges(Level 1, Scored)
    If all processes ran with the smallest set of privileges needed to perform  the user’s tasks, it would be more difficult for malicious and annoying software to infect a machine and propagate to other machines.

    Create user which is only used for running MongoDB and directly related processes. This user must not have administrative rights to the system-
    Useradd -m -d /home/mongodb -s /bin/bash -g mongodb -u 1234 mongodb
    Set ownership to mongodb user only- 
    Sudo chown -R mongodb:mongodb <path to db folder>

    6.2 Ensure that MongoDB uses a non-default port(Level 1, Scored)
    Changing the port used by mongoDB makes it harder for attackers to find the database and target it. Change the port number for mongoDB server to a number other than 27017.

    6.3 Ensure that operating system resource limits are set for MongoDB (Level 2, Not Scored)
    Operating system provide ways to limit and control the usage of system resources on a per-process and per-user basis. These ulimits prevents a single user from consuming too many system resources. Recommended thresholds and settings are particularly important for mongoDb deployments- 
    • f (file size): unlimited
    • t(cpu time): unlimited
    • v(virtual memory): unlimited
    • n(open files):64000
    • m(memory size):unlimited
    • u(processes/threads):64000

    To check system limits - 
    ulimit -a

    To change ulimit -
    ulimit <resource> <value>

    6.4  Ensure that server-side scripting is disabled if not needed(Level 2, Not Scored)
    MongoDB supports the execution of JavaScript code for certain server-side operations:mapReduce,group,and $where. If these operations are not used then server-side scripting should be disabled. If server-side scripting is not needed and is not disabled, this introduces unnecessary risk that an attacker may take advantage of insecure coding. 

    To disable it - 
    Use --noscripting option on the command line.
    Set security.javascriptEnabled as false in mongod.conf

    7. File Permissions 

    7.1 Ensure that database file permissions are set correctly( Level 1, Scored)
    MongoDB database files need to be protected using file permissions. This will restrict unauthorized users from accessing the database. Set ownership of the database file to mongodb user and remove other permissions using following command- 

    chmod 660 /var/lib/mongodb
    sudo chown mongodb:mongodb /var/lib/mongodb


    Conclusion
    Securing the environment from any kind of vulnerabilities is a crucial step. Following CIS benchmarks can reduce the risk of being a victim of cyber attacks. And this article can help in making the primary daemon process secure. 

    References
    https://www.cisecurity.org/benchmark/mongodb/
    http://docs.mongodb.org/manual/tutorial/upgrade-revision/
    http://docs.mongodb.org/manual/core/authentication/#localhost-exception
    http://docs.mongodb.org/manual/tutorial/manage-users-and-roles/
    http://docs.mongodb.org/manual/tutorial/configure-linux-iptables-firewall/
    http://docs.mongodb.org/manual/tutorial/configure-ssl/
    https://docs.mongodb.com/v3.2/tutorial/configure-fips/
    http://docs.mongodb.org/manual/tutorial/configure-auditing/
    https://docs.mongodb.com/manual/reference/ulimit/#recommended-ulimit-settings

    No comments:

    Powered by Blogger.