diff --git a/.gitignore b/.gitignore index dc6b1ce..9f4a578 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,8 @@ reports/** inputs.yml inspec.lock +spec/ansible/roles/mongo-stig +spec/ansible/roles/mitre.yedit variables.pkrvar.hcl *.zip *.log diff --git a/spec/ansible/mongo-stig-hardening-playbook.yml b/spec/ansible/mongo-stig-hardening-playbook.yml index 2e8ad70..7e0bf93 100644 --- a/spec/ansible/mongo-stig-hardening-playbook.yml +++ b/spec/ansible/mongo-stig-hardening-playbook.yml @@ -4,7 +4,7 @@ roles: - role: roles/prep - role: mitre.yedit - - role: mongoSTIG + - role: mongo-stig vars: fips_mode: true enterprise_edition: true diff --git a/spec/ansible/requirements.yml b/spec/ansible/requirements.yml index 2dd38c3..7fff2e7 100644 --- a/spec/ansible/requirements.yml +++ b/spec/ansible/requirements.yml @@ -1,6 +1,6 @@ --- roles: - - name: mongoSTIG + - name: mongo-stig src: https://github.com/mitre/ansible-mongodb-enterprise-advanced-4-stig-hardening version: main diff --git a/spec/ansible/roles/mongo-stig/README.md b/spec/ansible/roles/mongo-stig/README.md deleted file mode 100644 index 225dd44..0000000 --- a/spec/ansible/roles/mongo-stig/README.md +++ /dev/null @@ -1,38 +0,0 @@ -Role Name -========= - -A brief description of the role goes here. - -Requirements ------------- - -Any pre-requisites that may not be covered by Ansible itself or the role should be mentioned here. For instance, if the role uses the EC2 module, it may be a good idea to mention in this section that the boto package is required. - -Role Variables --------------- - -A description of the settable variables for this role should go here, including any variables that are in defaults/main.yml, vars/main.yml, and any variables that can/should be set via parameters to the role. Any variables that are read from other roles and/or the global scope (ie. hostvars, group vars, etc.) should be mentioned here as well. - -Dependencies ------------- - -A list of other roles hosted on Galaxy should go here, plus any details in regards to parameters that may need to be set for other roles, or variables that are used from other roles. - -Example Playbook ----------------- - -Including an example of how to use your role (for instance, with variables passed in as parameters) is always nice for users too: - - - hosts: servers - roles: - - { role: username.rolename, x: 42 } - -License -------- - -BSD - -Author Information ------------------- - -An optional section for the role authors to include contact information, or a website (HTML is not allowed). diff --git a/spec/ansible/roles/mongo-stig/defaults/main.yml b/spec/ansible/roles/mongo-stig/defaults/main.yml deleted file mode 100644 index 671093d..0000000 --- a/spec/ansible/roles/mongo-stig/defaults/main.yml +++ /dev/null @@ -1,58 +0,0 @@ ---- -### CONFIGURATION FLAGS -prep_conf: true -enterprise_edition: true -fips_mode: true -mongostig_cat1: true -mongostig_cat2: true -# Enable 'encryption_at_rest' if any data is PII, classified or is deemed by the organization the need to be encrypted at rest. -encryption_at_rest: false -kmip_enabled: false - -### CONNECTION VARIABLES -mongo_owner: root -mongo_group: root -mongo_dba: root -mongo_dba_password: root -mongo_host: localhost -mongo_port: 27017 -mongo_auth_source: admin -max_incoming_connections: 800000 -authentication_mechanism: - - SCRAM-SHA-256 - -### ROLES AND USERS -mongo_admin_roles: - - "root" -mongo_super_users: - - "admin.root" -mongo_users: - - "test.myTester" - - "products.myRoleTestUser" -inappropriate_mongo_privileges: - - "changeStream" - - "createCollection" - -### FILE PATHS -mongo_permissions: 0600 -mongod_config_path: /etc/mongod.conf -# Set 'audit_log_destination' to either "file" or "syslog" -audit_log_destination: file -mongo_audit_directory_path: /var/log/mongodb/audit/ -mongo_audit_file_path: /var/log/mongodb/audit/auditLog.bson -certificate_key_file_dest: /etc/ssl/mongodb.pem -certificate_key_file_src: ../../../../certificates/mongodb.pem -ca_file_dest: /etc/ssl/CA_bundle.pem -ca_file_src: ../../../../certificates/dod_CAs.pem -data_file_directory_path: /data/db/ - -### ENCRYPTION SETTINGS -encryption_cipher_mode: AES256-GCM -KMIP_server_host_name: -KMIP_server_port: -KMIP_server_ca_file: -KMIP_client_certificate_file: -security_encryption_key_file: - -### AUDIT SETTINGS -mongo_filter: "'{ atype: { $in: [ \"createCollection\", \"dropCollection\" ] } }'" diff --git a/spec/ansible/roles/mongo-stig/files/conf.template b/spec/ansible/roles/mongo-stig/files/conf.template deleted file mode 100644 index dc4b30f..0000000 --- a/spec/ansible/roles/mongo-stig/files/conf.template +++ /dev/null @@ -1,37 +0,0 @@ -# mongod.conf - -# for documentation of all options, see: -# http://docs.mongodb.org/manual/reference/configuration-options/ - -# Where and how to store data. -#storage: -# dbPath: /var/lib/mongodb -# engine: -# wiredTiger: - -# where to write logging data. -#systemLog: -# destination: file -# logAppend: true -# path: /var/log/mongodb/mongod.log - -# network interfaces -#net: - #port: 27017 - #bindIp: 127.0.0.1 - -# how the process runs -processManagement: - timeZoneInfo: /usr/share/zoneinfo - -#security: - -#operationProfiling: - -#replication: - -#sharding: - -## Enterprise-Only Options: - -#auditLog: \ No newline at end of file diff --git a/spec/ansible/roles/mongo-stig/files/openssl.cnf b/spec/ansible/roles/mongo-stig/files/openssl.cnf deleted file mode 100644 index 9779093..0000000 --- a/spec/ansible/roles/mongo-stig/files/openssl.cnf +++ /dev/null @@ -1,411 +0,0 @@ -# UPDATED TO SUPPORT FIPS -# OpenSSL example configuration file. -# See doc/man5/config.pod for more info. -# -# This is mostly being used for generation of certificate requests, -# but may be used for auto loading of providers - -# Note that you can include other files from the main configuration -# file using the .include directive. -#.include filename - -# This definition stops the following lines choking if HOME isn't -# defined. -HOME = . - - -# Comment out the next line to ignore configuration errors -config_diagnostics = 1 - - # Use this in order to automatically load providers. -openssl_conf = openssl_init - - -# Extra OBJECT IDENTIFIER info: -# oid_file = $ENV::HOME/.oid -oid_section = new_oids - -# To use this configuration file with the "-extfile" option of the -# "openssl x509" utility, name here the section containing the -# X.509v3 extensions to use: -# extensions = -# (Alternatively, use a configuration file that has only -# X.509v3 extensions in its main [= default] section.) - -[ new_oids ] -# We can add new OIDs in here for use by 'ca', 'req' and 'ts'. -# Add a simple OID like this: -# testoid1=1.2.3.4 -# Or use config file substitution like this: -# testoid2=${testoid1}.5.6 - -# Policies used by the TSA examples. -tsa_policy1 = 1.2.3.4.1 -tsa_policy2 = 1.2.3.4.5.6 -tsa_policy3 = 1.2.3.4.5.7 - -# For FIPS -# Optionally include a file that is generated by the OpenSSL fipsinstall -# application. This file contains configuration data required by the OpenSSL -# fips provider. It contains a named section e.g. [fips_sect] which is -# referenced from the [provider_sect] below. -# Refer to the OpenSSL security policy for more information. -# .include fipsmodule.cnf -.include /usr/local/ssl/fipsmodule.cnf - -[openssl_init] -providers = provider_sect -ssl_conf = ssl_sect -alg_section = algorithm_sect - -# List of providers to load -[provider_sect] -default = default_sect -# The fips section name should match the section name inside the -# included fipsmodule.cnf. -# fips = fips_sect -fips = fips_sect -base = base_sect - - -# If no providers are activated explicitly, the default one is activated implicitly. -# See man 7 OSSL_PROVIDER-default for more details. -# -# If you add a section explicitly activating any other provider(s), you most -# probably need to explicitly activate the default provider, otherwise it -# becomes unavailable in openssl. As a consequence applications depending on -# OpenSSL may not work correctly which could lead to significant system -# problems including inability to remotely access the system. -[default_sect] -# activate = 1 - -[base_sect] -activate = 1 - -[algorithm_sect] -default_properties = fips=yes - - -#################################################################### -[ ca ] -default_ca = CA_default # The default ca section - -#################################################################### -[ CA_default ] - -dir = ./demoCA # Where everything is kept -certs = $dir/certs # Where the issued certs are kept -crl_dir = $dir/crl # Where the issued crl are kept -database = $dir/index.txt # database index file. -#unique_subject = no # Set to 'no' to allow creation of - # several certs with same subject. -new_certs_dir = $dir/newcerts # default place for new certs. - -certificate = $dir/cacert.pem # The CA certificate -serial = $dir/serial # The current serial number -crlnumber = $dir/crlnumber # the current crl number - # must be commented out to leave a V1 CRL -crl = $dir/crl.pem # The current CRL -private_key = $dir/private/cakey.pem# The private key - -x509_extensions = usr_cert # The extensions to add to the cert - -# Comment out the following two lines for the "traditional" -# (and highly broken) format. -name_opt = ca_default # Subject Name options -cert_opt = ca_default # Certificate field options - -# Extension copying option: use with caution. -# copy_extensions = copy - -# Extensions to add to a CRL. Note: Netscape communicator chokes on V2 CRLs -# so this is commented out by default to leave a V1 CRL. -# crlnumber must also be commented out to leave a V1 CRL. -# crl_extensions = crl_ext - -default_days = 365 # how long to certify for -default_crl_days= 30 # how long before next CRL -default_md = default # use public key default MD -preserve = no # keep passed DN ordering - -# A few difference way of specifying how similar the request should look -# For type CA, the listed attributes must be the same, and the optional -# and supplied fields are just that :-) -policy = policy_match - -# For the CA policy -[ policy_match ] -countryName = match -stateOrProvinceName = match -organizationName = match -organizationalUnitName = optional -commonName = supplied -emailAddress = optional - -# For the 'anything' policy -# At this point in time, you must list all acceptable 'object' -# types. -[ policy_anything ] -countryName = optional -stateOrProvinceName = optional -localityName = optional -organizationName = optional -organizationalUnitName = optional -commonName = supplied -emailAddress = optional - -#################################################################### -[ req ] -default_bits = 2048 -default_keyfile = privkey.pem -distinguished_name = req_distinguished_name -attributes = req_attributes -x509_extensions = v3_ca # The extensions to add to the self signed cert - -# Passwords for private keys if not present they will be prompted for -# input_password = secret -# output_password = secret - -# This sets a mask for permitted string types. There are several options. -# default: PrintableString, T61String, BMPString. -# pkix : PrintableString, BMPString (PKIX recommendation before 2004) -# utf8only: only UTF8Strings (PKIX recommendation after 2004). -# nombstr : PrintableString, T61String (no BMPStrings or UTF8Strings). -# MASK:XXXX a literal mask value. -# WARNING: ancient versions of Netscape crash on BMPStrings or UTF8Strings. -string_mask = utf8only - -# req_extensions = v3_req # The extensions to add to a certificate request - -[ req_distinguished_name ] -countryName = Country Name (2 letter code) -countryName_default = AU -countryName_min = 2 -countryName_max = 2 - -stateOrProvinceName = State or Province Name (full name) -stateOrProvinceName_default = Some-State - -localityName = Locality Name (eg, city) - -0.organizationName = Organization Name (eg, company) -0.organizationName_default = Internet Widgits Pty Ltd - -# we can do this but it is not needed normally :-) -#1.organizationName = Second Organization Name (eg, company) -#1.organizationName_default = World Wide Web Pty Ltd - -organizationalUnitName = Organizational Unit Name (eg, section) -#organizationalUnitName_default = - -commonName = Common Name (e.g. server FQDN or YOUR name) -commonName_max = 64 - -emailAddress = Email Address -emailAddress_max = 64 - -# SET-ex3 = SET extension number 3 - -[ req_attributes ] -challengePassword = A challenge password -challengePassword_min = 4 -challengePassword_max = 20 - -unstructuredName = An optional company name - -[ usr_cert ] - -# These extensions are added when 'ca' signs a request. - -# This goes against PKIX guidelines but some CAs do it and some software -# requires this to avoid interpreting an end user certificate as a CA. - -basicConstraints=CA:FALSE - -# This is typical in keyUsage for a client certificate. -# keyUsage = nonRepudiation, digitalSignature, keyEncipherment - -# PKIX recommendations harmless if included in all certificates. -subjectKeyIdentifier=hash -authorityKeyIdentifier=keyid,issuer - -# This stuff is for subjectAltName and issuerAltname. -# Import the email address. -# subjectAltName=email:copy -# An alternative to produce certificates that aren't -# deprecated according to PKIX. -# subjectAltName=email:move - -# Copy subject details -# issuerAltName=issuer:copy - -# This is required for TSA certificates. -# extendedKeyUsage = critical,timeStamping - -[ v3_req ] - -# Extensions to add to a certificate request - -basicConstraints = CA:FALSE -keyUsage = nonRepudiation, digitalSignature, keyEncipherment - -[ v3_ca ] - - -# Extensions for a typical CA - - -# PKIX recommendation. - -subjectKeyIdentifier=hash - -authorityKeyIdentifier=keyid:always,issuer - -basicConstraints = critical,CA:true - -# Key usage: this is typical for a CA certificate. However since it will -# prevent it being used as an test self-signed certificate it is best -# left out by default. -# keyUsage = cRLSign, keyCertSign - -# Include email address in subject alt name: another PKIX recommendation -# subjectAltName=email:copy -# Copy issuer details -# issuerAltName=issuer:copy - -# DER hex encoding of an extension: beware experts only! -# obj=DER:02:03 -# Where 'obj' is a standard or added object -# You can even override a supported extension: -# basicConstraints= critical, DER:30:03:01:01:FF - -[ crl_ext ] - -# CRL extensions. -# Only issuerAltName and authorityKeyIdentifier make any sense in a CRL. - -# issuerAltName=issuer:copy -authorityKeyIdentifier=keyid:always - -[ proxy_cert_ext ] -# These extensions should be added when creating a proxy certificate - -# This goes against PKIX guidelines but some CAs do it and some software -# requires this to avoid interpreting an end user certificate as a CA. - -basicConstraints=CA:FALSE - -# This is typical in keyUsage for a client certificate. -# keyUsage = nonRepudiation, digitalSignature, keyEncipherment - -# PKIX recommendations harmless if included in all certificates. -subjectKeyIdentifier=hash -authorityKeyIdentifier=keyid,issuer - -# This stuff is for subjectAltName and issuerAltname. -# Import the email address. -# subjectAltName=email:copy -# An alternative to produce certificates that aren't -# deprecated according to PKIX. -# subjectAltName=email:move - -# Copy subject details -# issuerAltName=issuer:copy - -# This really needs to be in place for it to be a proxy certificate. -proxyCertInfo=critical,language:id-ppl-anyLanguage,pathlen:3,policy:foo - -#################################################################### -[ tsa ] - -default_tsa = tsa_config1 # the default TSA section - -[ tsa_config1 ] - -# These are used by the TSA reply generation only. -dir = ./demoCA # TSA root directory -serial = $dir/tsaserial # The current serial number (mandatory) -crypto_device = builtin # OpenSSL engine to use for signing -signer_cert = $dir/tsacert.pem # The TSA signing certificate - # (optional) -certs = $dir/cacert.pem # Certificate chain to include in reply - # (optional) -signer_key = $dir/private/tsakey.pem # The TSA private key (optional) -signer_digest = sha256 # Signing digest to use. (Optional) -default_policy = tsa_policy1 # Policy if request did not specify it - # (optional) -other_policies = tsa_policy2, tsa_policy3 # acceptable policies (optional) -digests = sha1, sha256, sha384, sha512 # Acceptable message digests (mandatory) -accuracy = secs:1, millisecs:500, microsecs:100 # (optional) -clock_precision_digits = 0 # number of digits after dot. (optional) -ordering = yes # Is ordering defined for timestamps? - # (optional, default: no) -tsa_name = yes # Must the TSA name be included in the reply? - # (optional, default: no) -ess_cert_id_chain = no # Must the ESS cert id chain be included? - # (optional, default: no) -ess_cert_id_alg = sha1 # algorithm to compute certificate - # identifier (optional, default: sha1) - -[insta] # CMP using Insta Demo CA -# Message transfer -server = pki.certificate.fi:8700 -# proxy = # set this as far as needed, e.g., http://192.168.1.1:8080 -# tls_use = 0 -path = pkix/ - -# Server authentication -recipient = "/C=FI/O=Insta Demo/CN=Insta Demo CA" # or set srvcert or issuer -ignore_keyusage = 1 # potentially needed quirk -unprotected_errors = 1 # potentially needed quirk -extracertsout = insta.extracerts.pem - -# Client authentication -ref = 3078 # user identification -secret = pass:insta # can be used for both client and server side - -# Generic message options -cmd = ir # default operation, can be overridden on cmd line with, e.g., kur - -# Certificate enrollment -subject = "/CN=openssl-cmp-test" -newkey = insta.priv.pem -out_trusted = insta.ca.crt -certout = insta.cert.pem - -[pbm] # Password-based protection for Insta CA -# Server and client authentication -ref = $insta::ref # 3078 -secret = $insta::secret # pass:insta - -[signature] # Signature-based protection for Insta CA -# Server authentication -trusted = insta.ca.crt # does not include keyUsage digitalSignature - -# Client authentication -secret = # disable PBM -key = $insta::newkey # insta.priv.pem -cert = $insta::certout # insta.cert.pem - -[ir] -cmd = ir - -[cr] -cmd = cr - -[kur] -# Certificate update -cmd = kur -oldcert = $insta::certout # insta.cert.pem - -[rr] -# Certificate revocation -cmd = rr -oldcert = $insta::certout # insta.cert.pem - -[ssl_sect] -system_default = system_default_sect - -[system_default_sect] -CipherString = DEFAULT:@SECLEVEL=2 -# UPDATED TO SUPPORT FIPS diff --git a/spec/ansible/roles/mongo-stig/handlers/main.yml b/spec/ansible/roles/mongo-stig/handlers/main.yml deleted file mode 100644 index cdfff7c..0000000 --- a/spec/ansible/roles/mongo-stig/handlers/main.yml +++ /dev/null @@ -1,2 +0,0 @@ ---- -# handlers file for mongo-stig diff --git a/spec/ansible/roles/mongo-stig/meta/main.yml b/spec/ansible/roles/mongo-stig/meta/main.yml deleted file mode 100644 index e11875b..0000000 --- a/spec/ansible/roles/mongo-stig/meta/main.yml +++ /dev/null @@ -1,52 +0,0 @@ -galaxy_info: - author: Sean Chacon Cai, Will Dower - description: Apply the MongoDB Enterprise Advanced 5 STIG - company: The MITRE Corporation - - # If the issue tracker for your role is not on github, uncomment the - # next line and provide a value - # issue_tracker_url: http://example.com/issue/tracker - - # Choose a valid license ID from https://spdx.org - some suggested licenses: - # - BSD-3-Clause (default) - # - MIT - # - GPL-2.0-or-later - # - GPL-3.0-only - # - Apache-2.0 - # - CC-BY-4.0 - license: license (GPL-2.0-or-later, MIT, etc) - - min_ansible_version: 2.1 - - # If this a Container Enabled role, provide the minimum Ansible Container version. - # min_ansible_container_version: - - # - # Provide a list of supported platforms, and for each platform a list of versions. - # If you don't wish to enumerate all versions for a particular platform, use 'all'. - # To view available platforms and versions (or releases), visit: - # https://galaxy.ansible.com/api/v1/platforms/ - # - # platforms: - # - name: Fedora - # versions: - # - all - # - 25 - # - name: SomePlatform - # versions: - # - all - # - 1.0 - # - 7 - # - 99.99 - - galaxy_tags: [] - # List tags for your role here, one per line. A tag is a keyword that describes - # and categorizes the role. Users find roles by searching for tags. Be sure to - # remove the '[]' above, if you add tags to this list. - # - # NOTE: A tag is limited to a single word comprised of alphanumeric characters. - # Maximum 20 tags per role. - -dependencies: [] - # List your role dependencies here, one per line. Be sure to remove the '[]' above, - # if you add dependencies to this list. diff --git a/spec/ansible/roles/mongo-stig/tasks/cat1.yml b/spec/ansible/roles/mongo-stig/tasks/cat1.yml deleted file mode 100644 index 36cd939..0000000 --- a/spec/ansible/roles/mongo-stig/tasks/cat1.yml +++ /dev/null @@ -1,177 +0,0 @@ ---- -- name: "HIGH | SV-252139 | If passwords are used for authentication, MongoDB must transmit only encrypted representations of passwords." - yedit: - src: "{{ mongod_config_path }}" - edits: - - key: net.tls.mode - value: requireTLS - - key: net.tls.certificateKeyFile - value: "{{ certificate_key_file_dest }}" - - key: net.tls.CAFile - value: "{{ ca_file_dest }}" - - key: net.tls.allowInvalidCertificates - value: false - - key: net.tls.allowConnectionsWithoutCertificates - value: false - ignore_errors: true - when: enterprise_edition - tags: - - cat1 - - high - - SV-252139 - - enterprise - -- name: "HIGH | SV-252146 | MongoDB must use NIST FIPS 140-2 or 140-3 validated cryptographic modules for cryptographic operations." - yedit: - src: "{{ mongod_config_path }}" - key: net.tls.FIPSMode - value: true - ignore_errors: true - when: enterprise_edition and fips_mode - tags: - - cat1 - - high - - SV-252146 - - enterprise - - fips - -- name: "HIGH | SV-252149 | MongoDB must integrate with an organization-level authentication/access mechanism providing account management and automation for all users, groups, roles, and any other principals." - yedit: - src: "{{ mongod_config_path }}" - key: security.authorization - value: enabled - ignore_errors: true - when: enterprise_edition - tags: - - cat1 - - high - - SV-252149 - - enterprise - -- name: "HIGH | SV-252150 | MongoDB must enforce approved authorizations for logical access to information and system resources in accordance with applicable access control policies." - ansible.builtin.debug: - msg: "Consult the STIG documentation to manually address and verify compliance for SV-252170." - ignore_errors: true - tags: - - cat1 - - high - - SV-252150 - - manual - -- name: "HIGH | SV-252152 | MongoDB software installation account must be restricted to authorized users." - ansible.builtin.debug: - msg: "Consult the STIG documentation to manually address and verify compliance for SV-252152." - ignore_errors: true - tags: - - cat1 - - high - - SV-252152 - - manual - -- name: "HIGH | SV-252158 | If passwords are used for authentication, MongoDB must implement LDAP or Kerberos for authentication to enforce the DoD standards for password complexity and lifetime." - ansible.builtin.debug: - msg: "Consult the STIG documentation to manually address and verify compliance for SV-252158." - ignore_errors: true - tags: - - cat1 - - high - - SV-252158 - - manual - -- name: "HIGH | SV-252159 | If passwords are used for authentication, MongoDB must store only hashed, salted representations of passwords." - yedit: - src: "{{ mongod_config_path }}" - key: setParameter.authenticationMechanisms - value: "{{ authentication_mechanism | join(',') }}" - ignore_errors: true - when: enterprise_edition - tags: - - cat1 - - high - - SV-252159 - - enterprise - -- name: "HIGH | SV-252160 | MongoDB must enforce authorized access to all PKI private keys stored/utilized by MongoDB." - block: - - name: "HIGH | SV-252160 | MongoDB must enforce authorized access to all PKI private keys stored/utilized by MongoDB. | Certificate Key File" - ansible.builtin.file: - path: "{{ certificate_key_file_dest }}" - owner: "{{ mongo_owner }}" - group: "{{ mongo_group }}" - mode: "{{ mongo_permissions }}" - - name: "HIGH | SV-252160 | MongoDB must enforce authorized access to all PKI private keys stored/utilized by MongoDB. | CA File" - ansible.builtin.file: - path: "{{ ca_file_dest }}" - owner: "{{ mongo_owner }}" - group: "{{ mongo_group }}" - mode: "{{ mongo_permissions }}" - when: enterprise_edition - ignore_errors: true - tags: - - cat1 - - high - - SV-252160 - - enterprise - -- name: "HIGH | SV-252162 | MongoDB must obscure feedback of authentication information during the authentication process to protect the information from possible exploitation/use by unauthorized individuals." - ansible.builtin.debug: - msg: "Consult the STIG documentation to manually address and verify compliance for SV-252162." - ignore_errors: true - tags: - - cat1 - - high - - SV-252162 - - manual - -- name: "HIGH | SV-252165 | MongoDB must protect the confidentiality and integrity of all information at rest." - block: - - name: "HIGH | SV-252165 | MongoDB must protect the confidentiality and integrity of all information at rest. | KMIP Enabled" - yedit: - src: "{{ mongod_config_path }}" - edits: - - key: net.tls.FIPSMode - value: true - - key: security.encryptionCipherMode - value: "{{ encryption_cipher_mode }}" - - key: security.enableEncryption - value: true - - key: kmip.serverName - value: "{{ KMIP_server_host_name }}" - - key: kmip.port - value: "{{ KMIP_server_port }}" - - key: kimp.ServerCAFile - value: "{{ KMIP_server_ca_file }}" - - key: kmip.clientCertificationFile - value: "{{ KMIP_client_certificate_file }}" - when: kmip_enabled - - - name: "HIGH | SV-252165 | MongoDB must protect the confidentiality and integrity of all information at rest. | Local Encryption Key File" - yedit: - src: "{{ mongod_config_path }}" - edits: - - key: net.tls.FIPSMode - value: true - - key: security.enableEncryption - value: true - - key: security.encryptionCipherMode - value: "{{ encryption_cipher_mode }}" - - key: security.encryptionKeyFile - value: "{{ security_encryption_key_file }}" - when: not kmip_enabled - ignore_errors: true - when: enterprise_edition and encryption_at_rest - tags: - - cat1 - - high - - SV-252165 - - enterprise - -- name: "HIGH | SV-252184 | MongoDB products must be a version supported by the vendor." - ansible.builtin.debug: - msg: "Consult the STIG documentation to manually address and verify compliance for SV-252184." - ignore_errors: true - tags: - - cat1 - - high - - SV-252184 - - manual diff --git a/spec/ansible/roles/mongo-stig/tasks/cat2.yml b/spec/ansible/roles/mongo-stig/tasks/cat2.yml deleted file mode 100644 index 4491127..0000000 --- a/spec/ansible/roles/mongo-stig/tasks/cat2.yml +++ /dev/null @@ -1,922 +0,0 @@ ---- -- name: "MEDIUM | SV-252134 | MongoDB must provide audit record generation for DoD-defined auditable events within all DBMS/database components." - block: - - name: "MEDIUM | SV-252134 | MongoDB must provide audit record generation for DoD-defined auditable events within all DBMS/database components. | Syslog Option" - yedit: - src: "{{ mongod_config_path }}" - edits: - - key: auditLog.destination - value: "{{ audit_log_destination}}" - - key: setParameter.auditAuthorizationSuccess - value: true - when: audit_log_destination == "syslog" - - - name: "MEDIUM | SV-252134 | MongoDB must provide audit record generation for DoD-defined auditable events within all DBMS/database components. | Check for file directory" - ansible.builtin.file: - path: "{{ mongo_audit_directory_path }}" - state: directory - mode: "{{ mongo_permissions }}" - when: audit_log_destination == "file" - - - name: "MEDIUM | SV-252134 | MongoDB must provide audit record generation for DoD-defined auditable events within all DBMS/database components. | Check if file exists" - ansible.builtin.file: - path: "{{ mongo_audit_file_path }}" - state: touch - when: audit_log_destination == "file" - - - name: "MEDIUM | SV-252134 | MongoDB must provide audit record generation for DoD-defined auditable events within all DBMS/database components. | File option" - yedit: - src: "{{ mongod_config_path }}" - edits: - - key: auditLog.destination - value: file - - key: auditLog.format - value: BSON - - key: auditLog.path - value: "{{ mongo_audit_file_path }}" - - key: auditLog.filter - value: "{{ mongo_filter }}" - - key: setParameter.auditAuthorizationSuccess - value: true - when: audit_log_destination == "file" - when: enterprise_edition - ignore_errors: true - tags: - - cat2 - - medium - - SV-252134 - - enterprise - -- name: "MEDIUM | SV-252135 | The audit information produced by MongoDB must be protected from unauthorized access." - ansible.builtin.file: - path: "{{ mongo_audit_directory_path }}" - owner: "{{ mongo_owner }}" - group: "{{ mongo_group}}" - mode: "{{ mongo_permissions }}" - state: directory - recurse: yes - when: enterprise_edition and audit_log_destination == "file" - ignore_errors: true - tags: - - cat2 - - medium - - SV-252135 - - enterprise - -- name: "MEDIUM | SV-252136 | MongoDB must protect its audit features from unauthorized access." - ansible.builtin.file: - path: "{{ mongod_config_path }}" - owner: "{{ mongo_owner }}" - group: "{{ mongo_group}}" - mode: "{{ mongo_permissions }}" - ignore_errors: true - tags: - - cat2 - - medium - - SV-252136 - -- name: "MEDIUM | SV-252137 | Unused database components that are integrated in MongoDB and cannot be uninstalled must be disabled." - yedit: - src: "{{ mongod_config_path }}" - key: net.http - state: absent - ignore_errors: true - tags: - - cat2 - - medium - - SV-252137 - -- name: "MEDIUM | SV-252138 | Unused database components that are integrated in MongoDB and cannot be uninstalled must be disabled." - yedit: - src: "{{ mongod_config_path }}" - key: net.http - state: absent - ignore_errors: true - tags: - - cat2 - - medium - - SV-252138 - -- name: "MEDIUM | SV-252140 | MongoDB must uniquely identify and authenticate non-organizational users (or processes acting on behalf of non-organizational users)." - vars: - reg_mongo_users_140: [] - user_ids_140: [] - user_names_140: [] - db_names_140: [] - databases_140: [] - users_140: [] - roles_140: [] - id_map_140: [] - block: - - name: "MEDIUM | SV-252140 | MongoDB must uniquely identify and authenticate non-organizational users (or processes acting on behalf of non-organizational users). | Extract _id fields from MongoDB user data" - set_fact: - user_ids_140: "{{ user_ids_140 + [item._id] }}" - loop: "{{ user_list.stdout }}" - - - name: "MEDIUM | SV-252140 | MongoDB must uniquely identify and authenticate non-organizational users (or processes acting on behalf of non-organizational users). | Filter out users not in mongo_users" - set_fact: - reg_mongo_users_140: "{{ reg_mongo_users_140 + [item] }}" - loop: "{{ user_ids_140 }}" - when: item in mongo_users - - - name: "MEDIUM | SV-252140 | MongoDB must uniquely identify and authenticate non-organizational users (or processes acting on behalf of non-organizational users). | Split each db.user in non_mongo_users" - set_fact: - user_names_140: "{{ user_names_140 + [item.split('.')[1]] }}" - db_names_140: "{{ db_names_140 + [item.split('.')[0]] }}" - loop: "{{ reg_mongo_users_140 }}" - - - name: "MEDIUM | SV-252140 | MongoDB must uniquely identify and authenticate non-organizational users (or processes acting on behalf of non-organizational users). | Get users" - ansible.builtin.command: | - mongosh "mongodb://{{ mongo_host }}:{{ mongo_port }}/{{ db_names_140[index] }}" --quiet --eval "EJSON.stringify(db.getUser('{{ user_names_140[index] }}'))" - loop: "{{ range(0, user_names_140|length) }}" - loop_control: - loop_var: index - register: command_output - - - name: "MEDIUM | SV-252140 | MongoDB must uniquely identify and authenticate non-organizational users (or processes acting on behalf of non-organizational users). | Extract stdout from command execution" - set_fact: - users_data: "{{ command_output.results | map(attribute='stdout') | list }}" - - - name: "MEDIUM | SV-252140 | MongoDB must uniquely identify and authenticate non-organizational users (or processes acting on behalf of non-organizational users). | Convert users_data into a dictionary" - set_fact: - users_dict: "{{ users_data | map('from_json') | list }}" - - - name: "MEDIUM | SV-252140 | MongoDB must uniquely identify and authenticate non-organizational users (or processes acting on behalf of non-organizational users). | Extract _id and roles" - set_fact: - id_map_140: "{{ id_map_140 | combine({ item['_id']: item['roles'] }) }}" - loop: "{{ users_dict }}" - loop_control: - label: "{{ item }}" - - - name: "MEDIUM | SV-252140 | MongoDB must uniquely identify and authenticate non-organizational users (or processes acting on behalf of non-organizational users). | Extract users with inappropriate roles" - set_fact: - users_140: "{{ users_140 + [item.key.split('.')[1]] }}" - databases_140: "{{ databases_140 + [item.key.split('.')[0]] }}" - roles_140: "{{ roles_140 + filtered_roles }}" - loop: "{{ id_map_140 | dict2items }}" - vars: - role_items: "{{ item.value }}" - filtered_roles: "{{ role_items | selectattr('role', 'in', mongo_admin_roles) | map(attribute='role') | list }}" - when: filtered_roles | length > 0 - - - name: "MEDIUM | SV-252140 | MongoDB must uniquely identify and authenticate non-organizational users (or processes acting on behalf of non-organizational users). | Revoke roles" - ansible.builtin.command: | - mongosh "mongodb://{{ mongo_host }}:{{ mongo_port }}/{{ databases_140[index] }}" --quiet --eval "EJSON.stringify(db.revokeRolesFromUser('{{ users_140[index]}}', ['{{ roles_140[index] }}']))" - loop: "{{ range(0, users_140|length) }}" - loop_control: - loop_var: index - - ignore_errors: true - tags: - - cat2 - - medium - - SV-252140 - -- name: "MEDIUM | SV-252141 | MongoDB must fail to a secure state if system initialization fails, shutdown fails, or aborts fail." - yedit: - src: "{{ mongod_config_path }}" - key: storage.journal.enabled - value: true - when: mongodb_version.stdout is version('6.1.0', '<=', 'version_type=semver') - ignore_errors: true - tags: - - cat2 - - medium - - SV-252141 - -- name: "MEDIUM | SV-252142 | MongoDB must prevent unauthorized and unintended information transfer via shared system resources." - block: - - name: "MEDIUM | SV-252142 | MongoDB must prevent unauthorized and unintended information transfer via shared system resources. | Conf file" - ansible.builtin.file: - path: "{{ mongod_config_path }}" - owner: "{{ mongo_owner }}" - group: "{{ mongo_group}}" - mode: "{{ mongo_permissions }}" - - - name: "MEDIUM | SV-252142 | MongoDB must prevent unauthorized and unintended information transfer via shared system resources. | Data directory" - ansible.builtin.file: - path: "{{ data_file_directory_path }}" - owner: "{{ mongo_owner }}" - group: "{{ mongo_group}}" - mode: "{{ mongo_permissions }}" - state: directory - recurse: yes - ignore_errors: true - tags: - - cat2 - - medium - - SV-252142 - -- name: "MEDIUM | SV-252143 | MongoDB and associated applications must reserve the use of dynamic code execution for situations that require it." - yedit: - src: "{{ mongod_config_path }}" - key: security.javascriptEnabled - value: false - ignore_errors: true - tags: - - cat2 - - medium - - SV-252143 - -- name: "MEDIUM | SV-252144 | MongoDB must associate organization-defined types of security labels having organization-defined security label values with information in storage and transmission." - ansible.builtin.debug: - msg: "Consult the STIG documentation to manually address and verify compliance for SV-252144." - ignore_errors: true - tags: - - cat2 - - medium - - SV-252144 - - manual - -- name: "MEDIUM | SV-252145 | MongoDB must enforce discretionary access control policies, as defined by the data owner, over defined subjects and objects." - yedit: - src: "{{ mongod_config_path }}" - key: security.authorization - value: enabled - ignore_errors: true - tags: - - cat2 - - medium - - SV-252145 - -- name: "MEDIUM | SV-252147 | MongoDB must implement cryptographic mechanisms to prevent unauthorized modification of organization-defined information at rest (to include, at a minimum, PII and classified information) on organization-defined information system components." - block: - - name: "MEDIUM | SV-252147 | MongoDB must implement cryptographic mechanisms to prevent unauthorized modification of organization-defined information at rest (to include, at a minimum, PII and classified information) on organization-defined information system components. | KMIP Enabled" - yedit: - src: "{{ mongod_config_path }}" - edits: - - key: net.tls.FIPSMode - value: true - - key: security.enableEncryption - value: true - - key: kmip.serverName - value: "{{ KMIP_server_host_name }}" - - key: kmip.port - value: "{{ KMIP_server_port }}" - - key: kimp.ServerCAFile - value: "{{ KMIP_server_ca_file }}" - - key: kmip.clientCertificationFile - value: "{{ KMIP_client_certificate_file }}" - when: kmip_enabled - - - name: "MEDIUM | SV-252147 | MongoDB must implement cryptographic mechanisms to prevent unauthorized modification of organization-defined information at rest (to include, at a minimum, PII and classified information) on organization-defined information system components. | Local Encryption Key File" - yedit: - src: "{{ mongod_config_path }}" - edits: - - key: net.tls.FIPSMode - value: true - - key: security.enableEncryption - value: true - - key: security.encryptionKeyFile - value: "{{ security_encryption_key_file }}" - when: not kmip_enabled - ignore_errors: true - when: enterprise_edition and encryption_at_rest - tags: - - cat2 - - medium - - SV-252147 - - enterprise - - pii - -- name: "MEDIUM | SV-252148 | MongoDB must limit the total number of concurrent connections to the database." - yedit: - src: "{{ mongod_config_path }}" - key: net.maxIncomingConnections - value: "{{ max_incoming_connections }}" - ignore_errors: true - tags: - - cat2 - - medium - - SV-252148 - -- name: "MEDIUM | SV-252151 | MongoDB must limit privileges to change software modules, to include stored procedures, functions and triggers, and links to software external to MongoDB." - ansible.builtin.debug: - msg: "Consult the STIG documentation to manually address and verify compliance for SV-252151." - ignore_errors: true - tags: - - cat2 - - medium - - SV-252151 - - manual - -- name: "MEDIUM | SV-252153 | Database software, including DBMS configuration files, must be stored in dedicated directories, or DASD pools, separate from the host OS and other applications." - ansible.builtin.debug: - msg: "Consult the STIG documentation to manually address and verify compliance for SV-252153." - ignore_errors: true - tags: - - cat2 - - medium - - SV-252153 - - manual - -- name: "MEDIUM | SV-252154 | Database objects (including but not limited to tables, indexes, storage, stored procedures, functions, triggers, links to software external to MongoDB, etc.) must be owned by database/DBMS principals authorized for ownership." - ansible.builtin.debug: - msg: "Consult the STIG documentation to manually address and verify compliance for SV-252154." - ignore_errors: true - tags: - - cat2 - - medium - - SV-252154 - - manual - -- name: "MEDIUM | SV-252155 | The role(s)/group(s) used to modify database structure (including but not necessarily limited to tables, indexes, storage, etc.) and logic modules (stored procedures, functions, triggers, links to software external to MongoDB, etc.) must be restricted to authorized users." - vars: - reg_mongo_users_155: [] - user_ids_155: [] - user_names_155: [] - db_names_155: [] - databases_155: [] - users_155: [] - roles_155: [] - id_map_155: [] - block: - - name: "MEDIUM | SV-252155 | The role(s)/group(s) used to modify database structure (including but not necessarily limited to tables, indexes, storage, etc.) and logic modules (stored procedures, functions, triggers, links to software external to MongoDB, etc.) must be restricted to authorized users. | Extract _id fields from MongoDB user data" - set_fact: - user_ids_155: "{{ user_ids_155 + [item._id] }}" - loop: "{{ user_list.stdout }}" - - - name: "MEDIUM | SV-252155 | The role(s)/group(s) used to modify database structure (including but not necessarily limited to tables, indexes, storage, etc.) and logic modules (stored procedures, functions, triggers, links to software external to MongoDB, etc.) must be restricted to authorized users. | Filter out users not in mongo_users" - set_fact: - reg_mongo_users_155: "{{ reg_mongo_users_155 + [item] }}" - loop: "{{ user_ids_155 }}" - when: item in mongo_users - - - name: "MEDIUM | SV-252155 | The role(s)/group(s) used to modify database structure (including but not necessarily limited to tables, indexes, storage, etc.) and logic modules (stored procedures, functions, triggers, links to software external to MongoDB, etc.) must be restricted to authorized users. | Split each db.user in non_mongo_users" - set_fact: - user_names_155: "{{ user_names_155 + [item.split('.')[1]] }}" - db_names_155: "{{ db_names_155 + [item.split('.')[0]] }}" - loop: "{{ reg_mongo_users_155 }}" - - - name: "MEDIUM | SV-252155 | The role(s)/group(s) used to modify database structure (including but not necessarily limited to tables, indexes, storage, etc.) and logic modules (stored procedures, functions, triggers, links to software external to MongoDB, etc.) must be restricted to authorized users. | Get users" - ansible.builtin.command: | - mongosh "mongodb://{{ mongo_host }}:{{ mongo_port }}/{{ db_names_155[index] }}" --quiet --eval "EJSON.stringify(db.getUser('{{ user_names_155[index] }}'))" - loop: "{{ range(0, user_names_155|length) }}" - loop_control: - loop_var: index - register: command_output - - - name: "MEDIUM | SV-252155 | The role(s)/group(s) used to modify database structure (including but not necessarily limited to tables, indexes, storage, etc.) and logic modules (stored procedures, functions, triggers, links to software external to MongoDB, etc.) must be restricted to authorized users. | Extract stdout from command execution" - set_fact: - users_data: "{{ command_output.results | map(attribute='stdout') | list }}" - - - name: "MEDIUM | SV-252155 | The role(s)/group(s) used to modify database structure (including but not necessarily limited to tables, indexes, storage, etc.) and logic modules (stored procedures, functions, triggers, links to software external to MongoDB, etc.) must be restricted to authorized users. | Convert users_data into a dictionary" - set_fact: - users_dict: "{{ users_data | map('from_json') | list }}" - - - name: "MEDIUM | SV-252155 | The role(s)/group(s) used to modify database structure (including but not necessarily limited to tables, indexes, storage, etc.) and logic modules (stored procedures, functions, triggers, links to software external to MongoDB, etc.) must be restricted to authorized users. | Extract _id and roles" - set_fact: - id_map_155: "{{ id_map_155 | combine({ item['_id']: item['roles'] }) }}" - loop: "{{ users_dict }}" - loop_control: - label: "{{ item }}" - - - name: "MEDIUM | SV-252155 | The role(s)/group(s) used to modify database structure (including but not necessarily limited to tables, indexes, storage, etc.) and logic modules (stored procedures, functions, triggers, links to software external to MongoDB, etc.) must be restricted to authorized users. | Extract users with inappropriate roles" - set_fact: - users_155: "{{ users_155 + [item.key.split('.')[1]] }}" - databases_155: "{{ databases_155 + [item.key.split('.')[0]] }}" - roles_155: "{{ roles_155 + filtered_roles }}" - loop: "{{ id_map_155 | dict2items }}" - vars: - role_items: "{{ item.value }}" - filtered_roles: "{{ role_items | selectattr('role', 'in', mongo_admin_roles) | map(attribute='role') | list }}" - when: filtered_roles | length > 0 - - - name: "MEDIUM | SV-252155 | The role(s)/group(s) used to modify database structure (including but not necessarily limited to tables, indexes, storage, etc.) and logic modules (stored procedures, functions, triggers, links to software external to MongoDB, etc.) must be restricted to authorized users. | Revoke roles" - ansible.builtin.command: | - mongosh "mongodb://{{ mongo_host }}:{{ mongo_port }}/{{ databases_155[index] }}" --quiet --eval "EJSON.stringify(db.revokeRolesFromUser('{{ users_155[index]}}', ['{{ roles_155[index] }}']))" - loop: "{{ range(0, users_155|length) }}" - loop_control: - loop_var: index - ignore_errors: true - tags: - - cat2 - - medium - - SV-252155 - - -- name: "MEDIUM | SV-252156 | Unused database components that are integrated in MongoDB and cannot be uninstalled must be disabled." - yedit: - src: "{{ mongod_config_path }}" - key: net.http - state: absent - ignore_errors: true - tags: - - cat2 - - medium - - SV-252156 - -- name: "MEDIUM | SV-252157 | MongoDB must uniquely identify and authenticate organizational users (or processes acting on behalf of organizational users)." - vars: - non_mongo_users_157: [] - user_ids_157: [] - db_names_157: [] - user_names_157: [] - block: - - name: "MEDIUM | SV-252157 | Enable authorization in MongoDB configuration" - yedit: - src: "{{ mongod_config_path }}" - key: security.authorization - value: enabled - - - name: "MEDIUM | SV-252157 | Enable authorization in MongoDB configuration | Extract _id fields from MongoDB user data" - set_fact: - user_ids_157: "{{ user_ids_157 + [item._id] }}" - loop: "{{ user_list.stdout }}" - - - name: "MEDIUM | SV-252157 | Enable authorization in MongoDB configuration | Combine users and super users" - set_fact: - all_mongo_users: "{{ mongo_super_users + mongo_users}}" - - - name: "MEDIUM | SV-252157 | Enable authorization in MongoDB configuration | Filter out users not in mongo_users" - set_fact: - non_mongo_users_157: "{{ non_mongo_users_157 + [item] }}" - loop: "{{ user_ids_157 }}" - when: item not in all_mongo_users - - - name: "MEDIUM | SV-252157 | Enable authorization in MongoDB configuration | Split each db.user in non_mongo_users" - set_fact: - db_names_157: "{{ db_names_157 + [item.split('.')[0]] }}" - user_names_157: "{{ user_names_157 + [item.split('.')[1]] }}" - loop: "{{ non_mongo_users_157 }}" - - - name: "MEDIUM | SV-252157 | Enable authorization in MongoDB configuration | Drop non_mongo_users" - ansible.builtin.command: | - mongosh "mongodb://{{ mongo_host }}:{{ mongo_port }}/{{ db_names_157[index] }}" --quiet --eval "db.dropUser('{{ user_names_157[index] }}', {w: 'majority', wtimeout: 5000})" - loop: "{{ range(0, user_names_157|length) }}" - loop_control: - loop_var: index - ignore_errors: false - tags: - - cat2 - - medium - - SV-252157 - -- name: "MEDIUM | SV-252161 | MongoDB must map the PKI-authenticated identity to an associated user account." - ansible.builtin.debug: - msg: "Consult the STIG documentation to manually address and verify compliance for SV-252161." - ignore_errors: true - tags: - - cat2 - - medium - - SV-252161 - - manual - -- name: "MEDIUM | SV-252163 | MongoDB must uniquely identify and authenticate non-organizational users (or processes acting on behalf of non-organizational users)." - vars: - reg_mongo_users_163: [] - user_ids_163: [] - user_names_163: [] - db_names_163: [] - databases_163: [] - users_163: [] - roles_163: [] - id_map_163: [] - block: - - name: "MEDIUM | SV-252163 | MongoDB must uniquely identify and authenticate non-organizational users (or processes acting on behalf of non-organizational users). | Extract _id fields from MongoDB user data" - set_fact: - user_ids_163: "{{ user_ids_163 + [item._id] }}" - loop: "{{ user_list.stdout }}" - - - name: "MEDIUM | SV-252163 | MongoDB must uniquely identify and authenticate non-organizational users (or processes acting on behalf of non-organizational users). | Filter out users not in mongo_users" - set_fact: - reg_mongo_users_163: "{{ reg_mongo_users_163 + [item] }}" - loop: "{{ user_ids_163 }}" - when: item in mongo_users - - - name: "MEDIUM | SV-252163 | MongoDB must uniquely identify and authenticate non-organizational users (or processes acting on behalf of non-organizational users). | Split each db.user in non_mongo_users" - set_fact: - user_names_163: "{{ user_names_163 + [item.split('.')[1]] }}" - db_names_163: "{{ db_names_163 + [item.split('.')[0]] }}" - loop: "{{ reg_mongo_users_163 }}" - - - name: "MEDIUM | SV-252163 | MongoDB must uniquely identify and authenticate non-organizational users (or processes acting on behalf of non-organizational users). | Get users" - ansible.builtin.command: | - mongosh "mongodb://{{ mongo_host }}:{{ mongo_port }}/{{ db_names_163[index] }}" --quiet --eval "EJSON.stringify(db.getUser('{{ user_names_163[index] }}'))" - loop: "{{ range(0, user_names_163|length) }}" - loop_control: - loop_var: index - register: command_output - - - name: "MEDIUM | SV-252163 | MongoDB must uniquely identify and authenticate non-organizational users (or processes acting on behalf of non-organizational users). | Extract stdout from command execution" - set_fact: - users_data: "{{ command_output.results | map(attribute='stdout') | list }}" - - - name: "MEDIUM | SV-252163 | MongoDB must uniquely identify and authenticate non-organizational users (or processes acting on behalf of non-organizational users). | Convert users_data into a dictionary" - set_fact: - users_dict: "{{ users_data | map('from_json') | list }}" - - - name: "MEDIUM | SV-252163 | MongoDB must uniquely identify and authenticate non-organizational users (or processes acting on behalf of non-organizational users). | Extract _id and roles" - set_fact: - id_map_163: "{{ id_map_163 | combine({ item['_id']: item['roles'] }) }}" - loop: "{{ users_dict }}" - loop_control: - label: "{{ item }}" - - - name: "MEDIUM | SV-252163 | MongoDB must uniquely identify and authenticate non-organizational users (or processes acting on behalf of non-organizational users). | Extract users with inappropriate roles" - set_fact: - users_163: "{{ users_163 + [item.key.split('.')[1]] }}" - databases_163: "{{ databases_163 + [item.key.split('.')[0]] }}" - roles_163: "{{ roles_163 + filtered_roles }}" - loop: "{{ id_map_163 | dict2items }}" - vars: - role_items: "{{ item.value }}" - filtered_roles: "{{ role_items | selectattr('role', 'in', mongo_admin_roles) | map(attribute='role') | list }}" - when: filtered_roles | length > 0 - - - name: "MEDIUM | SV-252163 | MongoDB must uniquely identify and authenticate non-organizational users (or processes acting on behalf of non-organizational users). | Revoke roles" - ansible.builtin.command: | - mongosh "mongodb://{{ mongo_host }}:{{ mongo_port }}/{{ databases_163[index] }}" --quiet --eval "EJSON.stringify(db.revokeRolesFromUser('{{ users_163[index]}}', ['{{ roles_163[index] }}']))" - loop: "{{ range(0, users_163|length) }}" - loop_control: - loop_var: index - ignore_errors: true - tags: - - cat2 - - medium - - SV-252163 - -- name: "MEDIUM | SV-252164 | MongoDB must maintain the authenticity of communications sessions by guarding against man-in-the-middle attacks that guess at Session ID values." - yedit: - src: "{{ mongod_config_path }}" - key: net.tls.mode - value: requireTLS - ignore_errors: true - when: enterprise_edition and fips_mode - tags: - - cat2 - - medium - - SV-252164 - - enterprise - -- name: "MEDIUM | SV-252166 | Database contents must be protected from unauthorized and unintended information transfer by enforcement of a data-transfer policy." - ansible.builtin.debug: - msg: "Consult the STIG documentation to manually address and verify compliance for SV-252166." - ignore_errors: true - tags: - - cat2 - - medium - - SV-252166 - - manual - -- name: "MEDIUM | SV-252167 | MongoDB must check the validity of all data inputs except those specifically identified by the organization." - yedit: - src: "{{ mongod_config_path }}" - key: security.javascriptEnabled - value: false - ignore_errors: true - tags: - - cat2 - - medium - - SV-252167 - -- name: "MEDIUM | SV-252168 | MongoDB must provide non-privileged users with error messages that provide information necessary for corrective actions without revealing information that could be exploited by adversaries." - yedit: - src: "{{ mongod_config_path }}" - key: security.redactClientLogData - value: true - ignore_errors: true - tags: - - cat2 - - medium - - SV-252168 - -- name: "MEDIUM | SV-252169 | MongoDB must reveal detailed error messages only to the ISSO, ISSM, SA, and DBA." - yedit: - src: "{{ mongod_config_path }}" - key: security.redactClientLogData - value: true - ignore_errors: true - tags: - - cat2 - - medium - - SV-252169 - -- name: "MEDIUM | SV-252170 | MongoDB must automatically terminate a user session after organization-defined conditions or trigger events requiring session disconnect." - ansible.builtin.debug: - msg: "Consult the STIG documentation to manually address and verify compliance for SV-252170." - ignore_errors: true - tags: - - cat2 - - medium - - SV-252170 - - manual - -- name: "MEDIUM | SV-252171 | MongoDB must utilize centralized management of the content captured in audit records generated by all components of MongoDB." - block: - - name: "MEDIUM | SV-252171 | MongoDB must utilize centralized management of the content captured in audit records generated by all components of MongoDB. | Check for file directory" - ansible.builtin.file: - path: "{{ mongo_audit_directory_path }}" - state: directory - mode: "{{ mongo_permissions }}" - when: audit_log_destination == "file" - - - name: "MEDIUM | SV-252171 | MongoDB must utilize centralized management of the content captured in audit records generated by all components of MongoDB. | Check if file exists" - ansible.builtin.file: - path: "{{ mongo_audit_file_path }}" - state: touch - when: audit_log_destination == "file" - - - name: "MEDIUM | SV-252171 | MongoDB must utilize centralized management of the content captured in audit records generated by all components of MongoDB. | File option" - yedit: - src: "{{ mongod_config_path }}" - edits: - - key: auditLog.destination - value: file - - key: auditLog.format - value: BSON - - key: auditLog.path - value: "{{ mongo_audit_file_path }}" - - key: auditLog.filter - value: "{{ mongo_filter }}" - - key: setParameter.auditAuthorizationSuccess - value: true - when: enterprise_edition and audit_log_destination == "file" - ignore_errors: true - tags: - - cat2 - - medium - - SV-252171 - - enterprise - -- name: "MEDIUM | SV-252172 | MongoDB must allocate audit record storage capacity in accordance with site audit record storage requirements." - ansible.builtin.debug: - msg: "Consult the STIG documentation to manually address and verify compliance for SV-252170." - ignore_errors: true - when: enterprise_edition - tags: - - cat2 - - medium - - SV-252172 - - enterprise - - manual - -- name: "MEDIUM | SV-252173 | MongoDB must provide a warning to appropriate support staff when allocated audit record storage volume reaches 75 percent of maximum audit record storage capacity." - ansible.builtin.debug: - msg: "Consult the STIG documentation to manually address and verify compliance for SV-252173." - ignore_errors: true - when: enterprise_edition - tags: - - cat2 - - medium - - SV-252173 - - enterprise - - manual - -- name: "MEDIUM | SV-252174 | MongoDB must prohibit user installation of logic modules (stored procedures, functions, triggers, views, etc.) without explicit privileged status." - vars: - db_list_174: [] - db_names_174: [] - users_174: [] - roles_174: [] - db_role_resource: {} - role_details_174: [] - resource_list_174: [] - updated_resource_list_174: [] - dbs_filtered_174: [] - roles_filtered_174: [] - block: - - name: "MEDIUM | SV-252174 | MongoDB must prohibit user installation of logic modules (stored procedures, functions, triggers, views, etc.) without explicit privileged status. | Get list of databases" - ansible.builtin.command: | - mongosh "mongodb://{{ mongo_host }}:{{ mongo_port }}/admin" --quiet --eval "EJSON.stringify(db.adminCommand({listDatabases: 1}))" - register: db_list_174 - - - name: "MEDIUM | SV-252174 | MongoDB must prohibit user installation of logic modules (stored procedures, functions, triggers, views, etc.) without explicit privileged status. | Extract stdout from each command execution" - set_fact: - users_174: "{{ db_list_174.stdout | from_json }}" - - - name: "MEDIUM | SV-252174 | MongoDB must prohibit user installation of logic modules (stored procedures, functions, triggers, views, etc.) without explicit privileged status. | Extract database names into a list" - set_fact: - db_names_174: "{{ users_174.databases | map(attribute='name') | list }}" - - - name: "MEDIUM | SV-252174 | MongoDB must prohibit user installation of logic modules (stored procedures, functions, triggers, views, etc.) without explicit privileged status. | Get list of roles" - ansible.builtin.command: | - mongosh "mongodb://{{ mongo_host }}:{{ mongo_port }}/{{ db_names_174[index] }}" --quiet --eval "EJSON.stringify(db.getRoles({rolesInfo: 1,showPrivileges: true}))" - loop: "{{ range(0, db_names_174|length) }}" - loop_control: - loop_var: index - register: command_output - - - name: "MEDIUM | SV-252174 | MongoDB must prohibit user installation of logic modules (stored procedures, functions, triggers, views, etc.) without explicit privileged status. | Extract stdout from command execution" - set_fact: - roles_174: "{{ command_output.results | map(attribute='stdout') | map('from_json') | list }}" - - - name: "MEDIUM | SV-252174 | MongoDB must prohibit user installation of logic modules (stored procedures, functions, triggers, views, etc.) without explicit privileged status. | Iterating through the roles, append the details to a list" - set_fact: - role_details_174: "{{ role_details_174 + [item.1] }}" - loop: "{{ roles_174 | subelements('roles') }}" - - - name: "MEDIUM | SV-252174 | MongoDB must prohibit user installation of logic modules (stored procedures, functions, triggers, views, etc.) without explicit privileged status. | Append the privileges of each role to a list" - set_fact: - resource_list_174: "{{ resource_list_174 + item.privileges }}" - loop: "{{ role_details_174 }}" - when: "'privileges' in item" - - - name: "MEDIUM | SV-252174 | MongoDB must prohibit user installation of logic modules (stored procedures, functions, triggers, views, etc.) without explicit privileged status. | Append the inherited privileges of each role to a list" - set_fact: - resource_list_174: "{{ resource_list_174 + item.inheritedPrivileges }}" - loop: "{{ role_details_174 }}" - when: "'inheritedPrivileges' in item" - - - name: "MEDIUM | SV-252174 | MongoDB must prohibit user installation of logic modules (stored procedures, functions, triggers, views, etc.) without explicit privileged status. | Process role details and store results based on privileges" - set_fact: - filtered_role_details_privileges: >- - {%- set results = [] -%} - {%- for role_iter in role_details_174 -%} - {%- if 'privileges' in role_iter -%} - {%- for privilege in role_iter['privileges'] -%} - {%- set filtered_actions = privilege.actions | intersect(inappropriate_mongo_privileges) -%} - {%- if filtered_actions | length > 0 -%} - {%- set _ = results.append({ - "db": role_iter.db, - "role": role_iter.role, - }) -%} - {%- endif -%} - {%- endfor -%} - {%- endif -%} - {%- endfor -%} - {{ results }} - - - name: "MEDIUM | SV-252174 | MongoDB must prohibit user installation of logic modules (stored procedures, functions, triggers, views, etc.) without explicit privileged status. | Add to dbs_filtered_174 and roles_filtered_174 from filtered results based off of privileges" - set_fact: - dbs_filtered_174: "{{ dbs_filtered_174 + [item.db] }}" - roles_filtered_174: "{{ roles_filtered_174 + [item.role] }}" - loop: "{{ filtered_role_details_privileges }}" - - - name: "MEDIUM | SV-252174 | MongoDB must prohibit user installation of logic modules (stored procedures, functions, triggers, views, etc.) without explicit privileged status. | Process role details and store results based on inherited privileges" - set_fact: - filtered_role_details_inherited: >- - {%- set results = [] -%} - {%- for role_iter in role_details_174 -%} - {%- if 'inheritedPrivileges' in role_iter -%} - {%- for privilege in role_iter['inheritedPrivileges'] -%} - {%- set filtered_actions = privilege.actions | intersect(inappropriate_mongo_privileges) -%} - {%- if filtered_actions | length > 0 -%} - {%- set _ = results.append({ - "db": role_iter.db, - "role": role_iter.role, - }) -%} - {%- endif -%} - {%- endfor -%} - {%- endif -%} - {%- endfor -%} - {{ results }} - - - name: "MEDIUM | SV-252174 | MongoDB must prohibit user installation of logic modules (stored procedures, functions, triggers, views, etc.) without explicit privileged status. | Add to dbs_filtered_174 and roles_filtered_174 from filtered results based off of inherited privileges" - set_fact: - dbs_filtered_174: "{{ dbs_filtered_174 + [item.db] }}" - roles_filtered_174: "{{ roles_filtered_174 + [item.role] }}" - loop: "{{ filtered_role_details_inherited }}" - - - name: "MEDIUM | SV-252174 | MongoDB must prohibit user installation of logic modules (stored procedures, functions, triggers, views, etc.) without explicit privileged status. | Replace each action key in the dictionary with the actions from inappropriate_mongo_privileges" - set_fact: - updated_resource_list_174: "{{ updated_resource_list_174 + [item | combine({'actions': inappropriate_mongo_privileges}, recursive=true)] }}" - loop: "{{ resource_list_174 }}" - - - name: "MEDIUM | SV-252174 | MongoDB must prohibit user installation of logic modules (stored procedures, functions, triggers, views, etc.) without explicit privileged status. | Revoke inappropriate privileges from each role" - ansible.builtin.command: | - mongosh "mongodb://{{ mongo_host }}:{{ mongo_port }}/{{ dbs_filtered_174[index] }}" --quiet --eval "db.revokePrivilegesFromRole('{{ roles_filtered_174[index] }}', [{{ updated_resource_list_174[index] }}])" - loop: "{{ range(0, dbs_filtered_174|length) }}" - loop_control: - loop_var: index - ignore_errors: true - tags: - - cat2 - - medium - - SV-252174 - - -- name: "MEDIUM | SV-252175 | MongoDB must enforce access restrictions associated with changes to the configuration of MongoDB or database(s)." - ansible.builtin.debug: - msg: "Consult the STIG documentation to manually address and verify compliance for SV-252175." - ignore_errors: true - tags: - - cat2 - - medium - - SV-252175 - - manual - -- name: "MEDIUM | SV-252176 | MongoDB must require users to reauthenticate when organization-defined circumstances or situations require reauthentication." - ansible.builtin.debug: - msg: "Consult the STIG documentation to manually address and verify compliance for SV-252176." - ignore_errors: true - tags: - - cat2 - - medium - - SV-252176 - - manual - -- name: "MEDIUM | SV-252177 | MongoDB must prohibit the use of cached authenticators after an organization-defined time period." - ansible.builtin.debug: - msg: "Consult the STIG documentation to manually address and verify compliance for SV-252177." - ignore_errors: true - when: enterprise_edition - tags: - - cat2 - - medium - - SV-252177 - - enterprise - - manual - - -- name: "MEDIUM | SV-252178 | MongoDB must only accept end entity certificates issued by DoD PKI or DoD-approved PKI Certification Authorities (CAs) for the establishment of all encrypted sessions." - ansible.builtin.debug: - msg: "Consult the STIG documentation to manually address and verify compliance for SV-252178." - ignore_errors: true - when: enterprise_edition - tags: - - cat2 - - medium - - SV-252178 - - enterprise - - manual - -- name: "MEDIUM | SV-252179 | MongoDB must maintain the confidentiality and integrity of information during preparation for transmission." - yedit: - src: "{{ mongod_config_path }}" - edits: - - key: net.tls.mode - value: requireTLS - - key: net.tls.certificateKeyFile - value: "{{ certificate_key_file_dest }}" - - key: net.tls.CAFile - value: "{{ ca_file_dest }}" - - key: net.tls.allowInvalidCertificates - value: false - - key: net.tls.allowConnectionsWithoutCertificates - value: false - - key: net.tls.FIPSMode - value: true - when: enterprise_edition and fips_mode - ignore_errors: true - tags: - - cat2 - - medium - - SV-252179 - - enterprise - - fips - -- name: "MEDIUM | SV-252180 | MongoDB must maintain the confidentiality and integrity of information during reception." - yedit: - src: "{{ mongod_config_path }}" - edits: - - key: net.tls.mode - value: requireTLS - - key: net.tls.certificateKeyFile - value: "{{ certificate_key_file_dest }}" - - key: net.tls.CAFile - value: "{{ ca_file_dest }}" - - key: net.tls.allowInvalidCertificates - value: false - - key: net.tls.allowConnectionsWithoutCertificates - value: false - - key: net.tls.FIPSMode - value: true - when: enterprise_edition and fips_mode - ignore_errors: true - tags: - - cat2 - - medium - - SV-252180 - - enterprise - - fips - -- name: "MEDIUM | SV-252181 | When invalid inputs are received, MongoDB must behave in a predictable and documented manner that reflects organizational and system objectives." - ansible.builtin.debug: - msg: "Consult the STIG documentation to manually address and verify compliance for SV-252181." - ignore_errors: true - tags: - - cat2 - - medium - - SV-252181 - - manual - -- name: "MEDIUM | SV-252182 | When updates are applied to MongoDB software, any software components that have been replaced or made unnecessary must be removed." - ansible.builtin.debug: - msg: "Consult the STIG documentation to manually address and verify compliance for SV-252182." - ignore_errors: true - tags: - - cat2 - - medium - - SV-252182 - - manual - -- name: "MEDIUM | SV-252183 | Security-relevant software updates to MongoDB must be installed within the time period directed by an authoritative source (e.g., IAVM, CTOs, DTMs, and STIGs)." - ansible.builtin.debug: - msg: "Consult the STIG documentation to manually address and verify compliance for SV-252183." - ignore_errors: true - tags: - - cat2 - - medium - - SV-252183 - - manual - -- name: "MEDIUM | SV-252185 | MongoDB must be configured in accordance with the security configuration settings based on DoD security configuration and implementation guidance, including STIGs, NSA configuration guides, CTOs, DTMs, and IAVMs." - ansible.builtin.debug: - msg: "Consult the STIG documentation to manually address and verify compliance for SV-252185." - ignore_errors: true - tags: - - cat2 - - medium - - SV-252185 - - manual diff --git a/spec/ansible/roles/mongo-stig/tasks/fips.yml b/spec/ansible/roles/mongo-stig/tasks/fips.yml deleted file mode 100644 index 94ec508..0000000 --- a/spec/ansible/roles/mongo-stig/tasks/fips.yml +++ /dev/null @@ -1,72 +0,0 @@ ---- -- name: "FIPS | Download OpenSSL 3.0.0 tarball" - get_url: - url: https://www.openssl.org/source/openssl-3.0.0.tar.gz - dest: /usr/local/src/openssl-3.0.0.tar.gz - validate_certs: no - register: result_300 - until: not result_300.failed - retries: 10 - delay: 10 - -- name: "FIPS | Download OpenSSL 3.1.0 tarball" - ansible.builtin.get_url: - url: https://www.openssl.org/source/openssl-3.1.0.tar.gz - dest: /usr/local/src/openssl-3.1.0.tar.gz - validate_certs: no - register: result_310 - until: not result_310.failed - retries: 10 - delay: 10 - -- name: "FIPS | Extract OpenSSL 3.0.0 tarball" - ansible.builtin.unarchive: - src: /usr/local/src/openssl-3.0.0.tar.gz - dest: /usr/local/src/ - remote_src: yes - creates: /usr/local/src/openssl-3.0.0 - -- name: "FIPS | Configure OpenSSL 3.0.0 with FIPS enabled" - ansible.builtin.command: ./Configure enable-fips - args: - chdir: /usr/local/src/openssl-3.0.0 - -- name: "FIPS | Build OpenSSL 3.0.0" - ansible.builtin.make: - chdir: /usr/local/src/openssl-3.0.0 - target: all - -- name: "FIPS | Extract OpenSSL 3.1.0 tarball" - ansible.builtin.unarchive: - src: /usr/local/src/openssl-3.1.0.tar.gz - dest: /usr/local/src/ - remote_src: yes - creates: /usr/local/src/openssl-3.1.0 - -- name: "FIPS | Configure OpenSSL 3.1.0 with FIPS enabled" - ansible.builtin.command: - cmd: ./Configure enable-fips - chdir: /usr/local/src/openssl-3.1.0 - -- name: "FIPS | Build OpenSSL 3.1.0" - ansible.builtin.make: - chdir: /usr/local/src/openssl-3.1.0 - target: all - -- name: "FIPS | Install OpenSSL 3.1.0" - ansible.builtin.make: - chdir: /usr/local/src/openssl-3.1.0 - target: install - -- name: "FIPS | Install OpenSSL 3.0.0 FIPS module" - ansible.builtin.make: - chdir: /usr/local/src/openssl-3.0.0 - target: install_fips - -- name: "FIPS | Copy openssl.cnf file to container" - ansible.builtin.copy: - src: files/openssl.cnf - dest: /usr/local/ssl/openssl.cnf - owner: "{{ mongo_owner }}" - group: "{{ mongo_group }}" - mode: "{{ mongo_permissions }}" \ No newline at end of file diff --git a/spec/ansible/roles/mongo-stig/tasks/main.yml b/spec/ansible/roles/mongo-stig/tasks/main.yml deleted file mode 100644 index a5ea6e5..0000000 --- a/spec/ansible/roles/mongo-stig/tasks/main.yml +++ /dev/null @@ -1,27 +0,0 @@ ---- -- name: Mongo.conf Prep - ansible.builtin.import_tasks: prep.yml - when: prep_conf - tags: - - prep - -- name: Enable FIPS Mode - ansible.builtin.import_tasks: fips.yml - when: enterprise_edition and fips_mode - tags: - - fips - - enterprise - -- name: Include CAT I - ansible.builtin.import_tasks: cat1.yml - when: mongostig_cat1 - tags: - - CAT1 - - high - -- name: Include CAT II - ansible.builtin.import_tasks: cat2.yml - when: mongostig_cat2 - tags: - - CAT2 - - medium \ No newline at end of file diff --git a/spec/ansible/roles/mongo-stig/tasks/prep.yml b/spec/ansible/roles/mongo-stig/tasks/prep.yml deleted file mode 100644 index 47f98e8..0000000 --- a/spec/ansible/roles/mongo-stig/tasks/prep.yml +++ /dev/null @@ -1,49 +0,0 @@ ---- -- name: "PREP | Check or create {{ mongod_config_path }} file" - ansible.builtin.stat: - path: "{{ mongod_config_path }}" - register: conf - changed_when: no - -- name: "PREP | Copy mongod.conf file to container" - ansible.builtin.copy: - src: files/conf.template - dest: "{{ mongod_config_path }}" - owner: "{{ mongo_owner }}" - group: "{{ mongo_group }}" - mode: "{{ mongo_permissions }}" - when: conf.stat.exists == false - -- name: "PREP | Copy certificate key file to container" - ansible.builtin.copy: - src: "{{ certificate_key_file_src }}" - dest: "{{ certificate_key_file_dest }}" - owner: "{{ mongo_owner }}" - group: "{{ mongo_group }}" - mode: "{{ mongo_permissions }}" - -- name: "PREP | Copy certificate authority file to container" - ansible.builtin.copy: - src: "{{ ca_file_src }}" - dest: "{{ ca_file_dest }}" - owner: "{{ mongo_owner }}" - group: "{{ mongo_group }}" - mode: "{{ mongo_permissions }}" - -- name: "PREP | Create MongoDB root user" - community.mongodb.mongodb_user: - database: "{{ mongo_auth_source }}" - name: "{{ mongo_dba }}" - password: "{{ mongo_dba_password }}" - roles: root - state: present - -- name: "PREP | Get all the users in a database" - ansible.builtin.command: | - mongosh "mongodb://{{ mongo_host }}:{{ mongo_port }}/admin" --quiet --eval "EJSON.stringify(db.system.users.find().toArray())" - register: user_list - -- name: "PREP | Get MongoDB version" - ansible.builtin.command: | - mongosh "mongodb://{{ mongo_host }}:{{ mongo_port }}/test" --quiet --eval "db.version()" - register: mongodb_version diff --git a/spec/ansible/roles/mongo-stig/tests/inventory b/spec/ansible/roles/mongo-stig/tests/inventory deleted file mode 100644 index 878877b..0000000 --- a/spec/ansible/roles/mongo-stig/tests/inventory +++ /dev/null @@ -1,2 +0,0 @@ -localhost - diff --git a/spec/ansible/roles/mongo-stig/tests/test.yml b/spec/ansible/roles/mongo-stig/tests/test.yml deleted file mode 100644 index 9ff4bdf..0000000 --- a/spec/ansible/roles/mongo-stig/tests/test.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -- hosts: localhost - remote_user: root - roles: - - mongo-stig diff --git a/spec/ansible/roles/mongo-stig/vars/main.yml b/spec/ansible/roles/mongo-stig/vars/main.yml deleted file mode 100644 index f4c1215..0000000 --- a/spec/ansible/roles/mongo-stig/vars/main.yml +++ /dev/null @@ -1,2 +0,0 @@ ---- -# vars file for mongo-stig diff --git a/spec/mongo-inspec-profile/inputs_template.yml b/spec/mongo-inspec-profile/inputs_template.yml index 47debea..6c53567 100644 --- a/spec/mongo-inspec-profile/inputs_template.yml +++ b/spec/mongo-inspec-profile/inputs_template.yml @@ -10,4 +10,5 @@ certificate_key_file: "/etc/ssl/mongodb.pem" # Modified Inputs mongo_superusers: - "admin.root" - - "test.myTester" \ No newline at end of file + - "test.myTester" +mongo_version: "7.0.12" \ No newline at end of file