Select any two versions of this STIG to compare the individual requirements
Select any old version/release of this STIG to view the previous requirements
Verify that no insecure registries are configured by executing the following: oc get image.config.openshift.io/cluster -ojsonpath='{.spec.allowedRegistriesForImport}' | jq -r '.[] | select(.insecure == true)' If the above query finds any registries, this is a finding. Empty output is not a finding. Verify that no insecure registries are configured by executing the following: oc get image.config.openshift.io/cluster -ojsonpath='{.spec.registrySources.insecureRegistries}' If the above query returns anything, then this is a finding. Empty output is not a finding.
Remove insecure registries from the cluster's image registry configuration by executing the following: oc edit image.config.openshift.io/cluster Edit or remove any registries where insecure is set to true or are listed under insecureRegistries. Refer to https://docs.openshift.com/container-platform/4.8/openshift_images/image-configuration.html for more details on configuring registries in OpenShift.
Verify the TLS Security Profile is not set to a profile that does not enforce TLS 1.2 or above. View the TLS security profile for the ingress controllers by executing the following: oc get --all-namespaces ingresscontrollers.operator.openshift.io -ocustom-columns="NAME":.metadata.name,"NAMESPACE":.metadata.namespace,"TLS PROFILE":.spec.tlsSecurityProfile View the TLS security profile for the control plane by executing the following: oc get APIServer cluster -ocustom-columns="TLS PROFILE":.spec.tlsSecurityProfile View the TLS profile for the Kubelet by executing the following: oc get kubeletconfigs -ocustom-columns="NAME":.metadata.name,"TLS PROFILE":.spec.tlsSecurityProfile If any of the above returns a TLS profile of "Old", this is a finding. If any of the above returns a TLS profile of "Custom" and the minTLSVersion is not set to "VersionTLS12" or greater, this is a finding. If the above returns "<none>" TLS profile, this is not a finding as the TLS profile defaults to "Intermediate". If the kubelet TLS profile check does not return any kubeletconfigs, this is not a finding as the default OCP installation uses defaults only.
Edit each resource and set the TLS Security Profile to Intermediate by executing the following: oc edit ingresscontroller <NAME> -n <NAMESPACE> Add the following to the file: apiVersion: config.openshift.io/v1 kind: IngressController ... spec: tlsSecurityProfile: intermediate: {} type: Intermediate Edit API Server by executing the following: oc edit APIServer Add the following to the file: apiVersion: config.openshift.io/v1 kind: APIServer ... spec: tlsSecurityProfile: intermediate: {} type: Intermediate Edit Kubelet by executing the following: oc edit KubeletConfig <NAME> Set to the following: apiVersion: config.openshift.io/v1 kind: KubeletConfig ... spec: tlsSecurityProfile: intermediate: {} type: Intermediate
Verify the authentication operator is configured to use either an LDAP or a OpenIDConnect provider by executing the following: oc get oauth cluster -o jsonpath="{.spec.identityProviders[*].type}{'\n'}" If the output lists any other type besides LDAP or OpenID, this is a finding.
Configure OpenShift to use an appropriate Identity Provider. Do not use HTPasswd. Use either LDAP(AD), OpenIDConnect, or an approved identity provider. To configure LDAP provider: 1. Create Secret for BIND DN password by executing the following: oc create secret generic ldap-secret --from-literal=bindPassword=<secret> -n openshift-config 2. Create config map for LDAP Trust CA by executing the following: oc create configmap ca-config-map --from-file=ca.crt=/path/to/ca -n openshift-config 3. Create LDAP Auth Config Resource YAML: Using the preferred text editor, create a file named ldapidp.yaml using the example content. (replacing config values as appropriate): apiVersion: config.openshift.io/v1 kind: OAuth metadata: name: cluster spec: identityProviders: - name: ldapidp mappingMethod: claim type: LDAP ldap: attributes: id: - dn email: - mail name: - cn preferredUsername: - uid bindDN: <"bindDN"> bindPassword: name: ldap-secret ca: name: ca-config-map insecure: false url: <URL> 4. Apply LDAP config to cluster by executing the following: oc apply -f ldapidp.yaml Note: For more information on configuring an LDAP provider, refer to https://docs.openshift.com/container-platform/4.8/authentication/identity_providers/configuring-ldap-identity-provider.html. To configure OpenID provider: 1. Create Secret for Client Secret by executing the following: oc create secret generic idp-secret --from-literal=clientSecret=<secret> -n openshift-config 2. Create config map for OpenID Trust CA by executing the following: oc create configmap ca-config-map --from-file=ca.crt=/path/to/ca -n openshift-config 3. Create OpenID Auth Config Resource YAML. Using the preferred text editor, create a file named oidcidp.yaml using the example content (replacing config values as appropriate). apiVersion: config.openshift.io/v1 kind: OAuth metadata: name: cluster spec: identityProviders: - name: oidcidp mappingMethod: claim type: OpenID openID: clientID: <clientID> clientSecret: name: oidc-idp-secret claims: preferredUsername: - preferred_username name: - name email: - email ca: name: ca-config-map issuer: <URL> 4. Apply OpenID config to cluster by executing the following: oc apply -f ldapidp.yaml Note: For more information on configuring an OpenID provider, refer to https://docs.openshift.com/container-platform/4.8/authentication/identity_providers/configuring-oidc-identity-provider.html.
Verify the kubeadmin account is disabled by executing the following: oc get secrets kubeadmin -n kube-system If the command returns an error, the secret was not found, and this is not a finding. (Example output: Error from server (NotFound): secrets "kubeadmin" not found) If the command returns a listing that includes the kubeadmin secret, its type, the data count, and age, this is a finding. (Example Output for not a finding: NAME TYPE DATA AGE kubeadmin Opaque 1 6h3m)
If an alternative IDP is already configured and an administrative user exists with the role of cluster-admin, disable the kubeadmin account by running the following command as a cluster administrator: oc delete secrets kubeadmin -n kube-system
Verify Red Hat Enterprise Linux CoreOS (RHCOS) generates audit records for all account creations, modifications, disabling, and termination events that affect "/etc/shadow". Logging on as administrator, check the auditing rules in "/etc/audit/audit.rules" by executing the following: for node in $(oc get node -oname); do oc debug $node -- chroot /host /bin/bash -c 'echo -n "$HOSTNAME: "; grep /etc/shadow /etc/audit/audit.rules /etc/audit/rules.d/*'; done (Example output: -w /etc/shadow -p wa -k identity) If the command does not return a line, or the line is commented out, this is a finding.
Apply the machine config using the following command: for mcpool in $(oc get mcp -oname | sed "s:.*/::" ); do echo "apiVersion: machineconfiguration.openshift.io/v1 kind: MachineConfig metadata: name: 75-account-modifications-rules-$mcpool labels: machineconfiguration.openshift.io/role: $mcpool spec: config: ignition: version: 3.1.0 storage: files: - contents: source: data:,-w%20/etc/sudoers.d/%20-p%20wa%20-k%20actions%0A-w%20/etc/sudoers%20-p%20wa%20-k%20actions%0A mode: 0644 path: /etc/audit/rules.d/75-audit-sysadmin-actions.rules overwrite: true - contents: source: data:,-w%20/etc/group%20-p%20wa%20-k%20audit_rules_usergroup_modification%0A mode: 0644 path: /etc/audit/rules.d/30-etc_group_usergroup_modification.rules overwrite: true - contents: source: data:,-w%20/etc/gshadow%20-p%20wa%20-k%20audit_rules_usergroup_modification%0A mode: 0644 path: /etc/audit/rules.d/30-etc_gshadow_usergroup_modification.rules overwrite: true - contents: source: data:,-w%20/etc/security/opasswd%20-p%20wa%20-k%20audit_rules_usergroup_modification%0A mode: 0644 path: /etc/audit/rules.d/30-etc_security_opasswd_usergroup_modification.rules overwrite: true - contents: source: data:,-w%20/etc/passwd%20-p%20wa%20-k%20audit_rules_usergroup_modification%0A mode: 0644 path: /etc/audit/rules.d/30-etc_passwd_usergroup_modification.rules overwrite: true - contents: source: data:,-w%20/etc/shadow%20-p%20wa%20-k%20audit_rules_usergroup_modification%0A mode: 0644 path: /etc/audit/rules.d/30-etc_shadow_usergroup_modification.rules overwrite: true " | oc apply -f - done
Verify for each of the files that contain account information the system is configured to emit an audit event in case of a write by executing the following: for node in $(oc get node -oname); do oc debug $node -- chroot /host /bin/bash -c 'echo -n "$HOSTNAME "; for f in /etc/passwd /etc/group /etc/gshadow /etc/security/opasswd /etc/shadow /etc/sudoers /etc/sudoers.d/; do grep -q "\-w $f \-p wa \-k" /etc/audit/audit.rules || echo "rule for $f not found"; done' 2>/dev/null; done If for any of the files a line saying "rule for $filename not found" is printed, this is a finding.
Apply the machine config using the following command: for mcpool in $(oc get mcp -oname | sed "s:.*/::" ); do echo "apiVersion: machineconfiguration.openshift.io/v1 kind: MachineConfig metadata: name: 75-account-modifications-rules-$mcpool labels: machineconfiguration.openshift.io/role: $mcpool spec: config: ignition: version: 3.1.0 storage: files: - contents: source: data:,-w%20/etc/sudoers.d/%20-p%20wa%20-k%20actions%0A-w%20/etc/sudoers%20-p%20wa%20-k%20actions%0A mode: 0644 path: /etc/audit/rules.d/75-audit-sysadmin-actions.rules overwrite: true - contents: source: data:,-w%20/etc/group%20-p%20wa%20-k%20audit_rules_usergroup_modification%0A mode: 0644 path: /etc/audit/rules.d/30-etc_group_usergroup_modification.rules overwrite: true - contents: source: data:,-w%20/etc/gshadow%20-p%20wa%20-k%20audit_rules_usergroup_modification%0A mode: 0644 path: /etc/audit/rules.d/30-etc_gshadow_usergroup_modification.rules overwrite: true - contents: source: data:,-w%20/etc/security/opasswd%20-p%20wa%20-k%20audit_rules_usergroup_modification%0A mode: 0644 path: /etc/audit/rules.d/30-etc_security_opasswd_usergroup_modification.rules overwrite: true - contents: source: data:,-w%20/etc/passwd%20-p%20wa%20-k%20audit_rules_usergroup_modification%0A mode: 0644 path: /etc/audit/rules.d/30-etc_passwd_usergroup_modification.rules overwrite: true - contents: source: data:,-w%20/etc/shadow%20-p%20wa%20-k%20audit_rules_usergroup_modification%0A mode: 0644 path: /etc/audit/rules.d/30-etc_shadow_usergroup_modification.rules overwrite: true " | oc apply -f - done
Verify the audit rules capture account creation, modification, disabling, removal, and enabling actions by executing the following: for node in $(oc get node -oname); do oc debug $node -- chroot /host /bin/bash -c 'echo -n "$HOSTNAME "; grep -e user-modify -e group-modify -e audit_rules_usergroup_modification /etc/audit/rules.d/* /etc/audit/audit.rules' 2>/dev/null; done Confirm the following rules exist on each node: -w /etc/group -p wa -k audit_rules_usergroup_modification -w /etc/gshadow -p wa -k audit_rules_usergroup_modification -w /etc/security/opasswd -p wa -k audit_rules_usergroup_modification -w /etc/passwd -p wa -k audit_rules_usergroup_modification -w /etc/shadow -p wa -k audit_rules_usergroup_modification If the above rules are not listed on each node, this is a finding.
Apply the machine config using the following command: for mcpool in $(oc get mcp -oname | sed "s:.*/::" ); do echo "apiVersion: machineconfiguration.openshift.io/v1 kind: MachineConfig metadata: name: 75-account-modifications-rules-$mcpool labels: machineconfiguration.openshift.io/role: $mcpool spec: config: ignition: version: 3.1.0 storage: files: - contents: source: data:,-w%20/etc/sudoers.d/%20-p%20wa%20-k%20actions%0A-w%20/etc/sudoers%20-p%20wa%20-k%20actions%0A mode: 0644 path: /etc/audit/rules.d/75-audit-sysadmin-actions.rules overwrite: true - contents: source: data:,-w%20/etc/group%20-p%20wa%20-k%20audit_rules_usergroup_modification%0A mode: 0644 path: /etc/audit/rules.d/30-etc_group_usergroup_modification.rules overwrite: true - contents: source: data:,-w%20/etc/gshadow%20-p%20wa%20-k%20audit_rules_usergroup_modification%0A mode: 0644 path: /etc/audit/rules.d/30-etc_gshadow_usergroup_modification.rules overwrite: true - contents: source: data:,-w%20/etc/security/opasswd%20-p%20wa%20-k%20audit_rules_usergroup_modification%0A mode: 0644 path: /etc/audit/rules.d/30-etc_security_opasswd_usergroup_modification.rules overwrite: true - contents: source: data:,-w%20/etc/passwd%20-p%20wa%20-k%20audit_rules_usergroup_modification%0A mode: 0644 path: /etc/audit/rules.d/30-etc_passwd_usergroup_modification.rules overwrite: true - contents: source: data:,-w%20/etc/shadow%20-p%20wa%20-k%20audit_rules_usergroup_modification%0A mode: 0644 path: /etc/audit/rules.d/30-etc_shadow_usergroup_modification.rules overwrite: true " | oc apply -f - done
Verify the audit rules capture the execution of setuid and setgid binaries by executing the following: for node in $(oc get node -oname); do oc debug $node -- chroot /host /bin/bash -c 'echo -n "$HOSTNAME "; grep -e key=privileged /etc/audit/audit.rules || echo "not found"' 2>/dev/null; done If "not found" is printed, this is a finding. Confirm the following rules exist on each node: -a always,exit -S all -F path=/usr/libexec/dbus-1/dbus-daemon-launch-helper -F auid>=1000 -F auid!=unset -F key=privileged -a always,exit -S all -F path=/usr/sbin/grub2-set-bootflag -F auid>=1000 -F auid!=unset -F key=privileged -a always,exit -S all -F path=/usr/libexec/openssh/ssh-keysign -F auid>=1000 -F auid!=unset -F key=privileged -a always,exit -S all -F path=/usr/bin/chage -F auid>=1000 -F auid!=unset -F key=privileged -a always,exit -S all -F path=/usr/bin/fusermount3 -F auid>=1000 -F auid!=unset -F key=privileged -a always,exit -S all -F path=/usr/bin/fusermount -F auid>=1000 -F auid!=unset -F key=privileged -a always,exit -S all -F path=/usr/bin/gpasswd -F auid>=1000 -F auid!=unset -F key=privileged -a always,exit -S all -F path=/usr/bin/mount -F auid>=1000 -F auid!=unset -F key=privileged -a always,exit -S all -F path=/usr/bin/newgrp -F auid>=1000 -F auid!=unset -F key=privileged -a always,exit -S all -F path=/usr/bin/passwd -F auid>=1000 -F auid!=unset -F key=privileged -a always,exit -S all -F path=/usr/bin/pkexec -F auid>=1000 -F auid!=unset -F key=privileged -a always,exit -S all -F path=/usr/bin/sudo -F auid>=1000 -F auid!=unset -F key=privileged -a always,exit -S all -F path=/usr/bin/su -F auid>=1000 -F auid!=unset -F key=privileged -a always,exit -S all -F path=/usr/bin/umount -F auid>=1000 -F auid!=unset -F key=privileged -a always,exit -S all -F path=/usr/bin/write -F auid>=1000 -F auid!=unset -F key=privileged -a always,exit -S all -F path=/usr/libexec/sssd/krb5_child -F auid>=1000 -F auid!=unset -F key=privileged -a always,exit -S all -F path=/usr/libexec/sssd/ldap_child -F auid>=1000 -F auid!=unset -F key=privileged -a always,exit -S all -F path=/usr/libexec/sssd/proxy_child -F auid>=1000 -F auid!=unset -F key=privileged -a always,exit -S all -F path=/usr/libexec/sssd/selinux_child -F auid>=1000 -F auid!=unset -F key=privileged -a always,exit -S all -F path=/usr/libexec/utempter -F auid>=1000 -F auid!=unset -F key=privileged -a always,exit -S all -F path=/usr/lib/polkit-1/polkit-agent-helper-1 -F auid>=1000 -F auid!=unset -F key=privileged -a always,exit -S all -F path=/usr/sbin/mount.nfs -F auid>=1000 -F auid!=unset -F key=privileged -a always,exit -S all -F path=/usr/sbin/pam_timestamp_check -F auid>=1000 -F auid!=unset -F key=privileged -a always,exit -S all -F path=/usr/sbin/unix_chkpwd -F auid>=1000 -F auid!=unset -F key=privileged To find all setuid binaries on the system, execute the following: for node in $(oc get node -oname); do oc debug $node -- chroot /host /bin/bash -c 'echo -n "$HOSTNAME "; find / -xdev -type f -perm -4000 -o -type f -perm -2000 2>/dev/null'; done If any setuid binary does not have a corresponding audit rule, this is a finding.
Apply the machine config by executing the following: for mcpool in $(oc get mcp -oname | sed "s:.*/::" ); do echo "apiVersion: machineconfiguration.openshift.io/v1 kind: MachineConfig metadata: name: 75-setuid-setgid-binaries-$mcpool labels: machineconfiguration.openshift.io/role: $mcpool spec: config: ignition: version: 3.1.0 storage: files: - contents: source: data:,-a%20always%2Cexit%20-F%20path%3D/usr/bin/chage%20-F%20auid%3E%3D1000%20-F%20auid%21%3Dunset%20-F%20key%3Dprivileged%0A mode: 0644 path: /etc/audit/rules.d/75-usr_bin_chage_execution.rules overwrite: true - contents: source: data:,-a%20always%2Cexit%20-F%20path%3D/usr/bin/fusermount%20-F%20auid%3E%3D1000%20-F%20auid%21%3Dunset%20-F%20key%3Dprivileged%0A mode: 0644 path: /etc/audit/rules.d/75-usr_bin_fusermount_execution.rules overwrite: true - contents: source: data:,-a%20always%2Cexit%20-F%20path%3D/usr/bin/fusermount3%20-F%20auid%3E%3D1000%20-F%20auid%21%3Dunset%20-F%20key%3Dprivileged%0A mode: 0644 path: /etc/audit/rules.d/75-usr_bin_fusermount3_execution.rules overwrite: true - contents: source: data:,-a%20always%2Cexit%20-F%20path%3D/usr/bin/gpasswd%20-F%20auid%3E%3D1000%20-F%20auid%21%3Dunset%20-F%20key%3Dprivileged%0A mode: 0644 path: /etc/audit/rules.d/75-usr_bin_gpasswd_execution.rules overwrite: true - contents: source: data:,-a%20always%2Cexit%20-F%20path%3D/usr/bin/mount%20-F%20auid%3E%3D1000%20-F%20auid%21%3Dunset%20-F%20key%3Dprivileged%0A mode: 0644 path: /etc/audit/rules.d/75-usr_bin_mount_execution.rules overwrite: true - contents: source: data:,-a%20always%2Cexit%20-F%20path%3D/usr/bin/newgrp%20-F%20auid%3E%3D1000%20-F%20auid%21%3Dunset%20-F%20key%3Dprivileged%0A mode: 0644 path: /etc/audit/rules.d/75-usr_bin_newgrp_execution.rules overwrite: true - contents: source: data:,-a%20always%2Cexit%20-F%20path%3D/usr/bin/passwd%20-F%20auid%3E%3D1000%20-F%20auid%21%3Dunset%20-F%20key%3Dprivileged%0A mode: 0644 path: /etc/audit/rules.d/75-usr_bin_passwd_execution.rules overwrite: true - contents: source: data:,-a%20always%2Cexit%20-F%20path%3D/usr/bin/pkexec%20-F%20auid%3E%3D1000%20-F%20auid%21%3Dunset%20-F%20key%3Dprivileged%0A mode: 0644 path: /etc/audit/rules.d/75-usr_bin_pkexec_execution.rules overwrite: true - contents: source: data:,-a%20always%2Cexit%20-F%20path%3D/usr/bin/su%20-F%20auid%3E%3D1000%20-F%20auid%21%3Dunset%20-F%20key%3Dprivileged%0A mode: 0644 path: /etc/audit/rules.d/75-usr_bin_su_execution.rules overwrite: true - contents: source: data:,-a%20always%2Cexit%20-F%20path%3D/usr/bin/sudo%20-F%20auid%3E%3D1000%20-F%20auid%21%3Dunset%20-F%20key%3Dprivileged%0A mode: 0644 path: /etc/audit/rules.d/75-usr_bin_sudo_execution.rules overwrite: true - contents: source: data:,-a%20always%2Cexit%20-F%20path%3D/usr/bin/umount%20-F%20auid%3E%3D1000%20-F%20auid%21%3Dunset%20-F%20key%3Dprivileged%0A mode: 0644 path: /etc/audit/rules.d/75-usr_bin_umount_execution.rules overwrite: true - contents: source: data:,-a%20always%2Cexit%20-F%20path%3D/usr/lib/polkit-1/polkit-agent-helper-1%20-F%20auid%3E%3D1000%20-F%20auid%21%3Dunset%20-F%20key%3Dprivileged%0A mode: 0644 path: /etc/audit/rules.d/75-usr_lib_polkit_helper_execution.rules overwrite: true - contents: source: data:,-a%20always%2Cexit%20-F%20path%3D/usr/libexec/dbus-1/dbus-daemon-launch-helper%20-F%20auid%3E%3D1000%20-F%20auid%21%3Dunset%20-F%20key%3Dprivileged%0A mode: 0644 path: /etc/audit/rules.d/75-dbus_daemon_launch_helper.rules overwrite: true - contents: source: data:,-a%20always%2Cexit%20-F%20path%3D/usr/libexec/sssd/krb5_child%20-F%20auid%3E%3D1000%20-F%20auid%21%3Dunset%20-F%20key%3Dprivileged%0A mode: 0644 path: /etc/audit/rules.d/75-usr_libexec_sssd_krb5_child.rules overwrite: true - contents: source: data:,-a%20always%2Cexit%20-F%20path%3D/usr/libexec/sssd/ldap_child%20-F%20auid%3E%3D1000%20-F%20auid%21%3Dunset%20-F%20key%3Dprivileged%0A mode: 0644 path: /etc/audit/rules.d/75-usr_libexec_sssd_ldap_child.rules overwrite: true - contents: source: data:,-a%20always%2Cexit%20-F%20path%3D/usr/libexec/sssd/proxy_child%20-F%20auid%3E%3D1000%20-F%20auid%21%3Dunset%20-F%20key%3Dprivileged%0A mode: 0644 path: /etc/audit/rules.d/75-usr_libexec_sssd_proxy_child.rules overwrite: true - contents: source: data:,-a%20always%2Cexit%20-F%20path%3D/usr/libexec/sssd/selinux_child%20-F%20auid%3E%3D1000%20-F%20auid%21%3Dunset%20-F%20key%3Dprivileged%0A mode: 0644 path: /etc/audit/rules.d/75-usr_libexec_sssd_selinux_child.rules overwrite: true - contents: source: data:,-a%20always%2Cexit%20-F%20path%3D/usr/sbin/grub2-set-bootflag%20-F%20auid%3E%3D1000%20-F%20auid%21%3Dunset%20-F%20key%3Dprivileged%0A mode: 0644 path: /etc/audit/rules.d/75-grub2_set_bootflag.rules overwrite: true - contents: source: data:,-a%20always%2Cexit%20-F%20path%3D/usr/sbin/mount.nfs%20-F%20auid%3E%3D1000%20-F%20auid%21%3Dunset%20-F%20key%3Dprivileged%0A mode: 0644 path: /etc/audit/rules.d/75-usr_sbin_mount_nfs.rules overwrite: true - contents: source: data:,-a%20always%2Cexit%20-F%20path%3D/usr/sbin/pam_timestamp_check%20-F%20auid%3E%3D1000%20-F%20auid%21%3Dunset%20-F%20key%3Dprivileged%0A mode: 0644 path: /etc/audit/rules.d/75-usr_sbin_pam_timestamp_check.rules overwrite: true - contents: source: data:,-a%20always%2Cexit%20-F%20path%3D/usr/sbin/unix_chkpwd%20-F%20auid%3E%3D1000%20-F%20auid%21%3Dunset%20-F%20key%3Dprivileged%0A mode: 0644 path: /etc/audit/rules.d/75-usr_sbin_unix_chkpwd.rules overwrite: true " | oc apply -f - done
The administrator must verify that OpenShift is configured with the necessary RBAC access controls. Review the RBAC configuration. As the cluster-admin, view the cluster roles and their associated rule sets by executing the following: oc describe clusterrole.rbac Now, view the current set of cluster role bindings, which shows the users and groups that are bound to various roles by executing the following: oc describe clusterrolebinding.rbac Local roles and bindings can be determined by executing the following: oc describe rolebinding.rbac If these results show users with privileged access that do not require that access, this is a finding.
If users or groups exist that are bound to roles they must not have, modify the user or group permissions using the following cluster and local role binding commands: Remove a user from a Cluster RBAC role by executing the following: oc adm policy remove-cluster-role-from-user <role> <username> Remove a group from a Cluster RBAC role by executing the following: oc adm policy remove-cluster-role-from-group <role> <groupname> Remove a user from a Local RBAC role by executing the following: oc adm policy remove-role-from-user <role> <username> Remove a group from a Local RBAC role by executing the following: oc adm policy remove-role-from-group <role> <groupname> Note: For additional information, refer to https://docs.openshift.com/container-platform/4.8/authentication/using-rbac.html.
Verify that each user namespace has a Network Policy by executing the following: for ns in $(oc get namespaces -ojson | jq -r '.items[] | select((.metadata.name | startswith("openshift") | not) and (.metadata.name | startswith("kube-") | not) and .metadata.name != "default") | .metadata.name '); do oc get networkpolicy -n$ns; done If the above returns any lines saying "No resources found in <PROJECT> namespace.", this is a finding. Empty output is not a finding.
Add a Network Policy to an existing project namespace by performing the following steps: 1. Create <YOURFILE>.yaml and insert the desired resource Network Policy content. The following is an example resource quota definition: apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: allow-from-same-namespace namespace: <NAMESPACE> spec: podSelector: {} ingress: - from: - podSelector: {} 2. Apply the Network Policy definition to the project namespace by executing the following: oc apply -f <YOURFILE>.yaml -n <NAMESPACE> Details regarding the configuration of resource Network Policy can be reviewed at https://docs.openshift.com/container-platform/4.12/networking/network_policy/about-network-policy.html.
Check for Network Policy. Verify a default project template is defined by executing the following: oc get project.config.openshift.io/cluster -o jsonpath="{.spec.projectRequestTemplate.name}" If no project request template is in use by the project config, this is a finding. Verify the project request template creates a Network Policy: oc get templates/<PROJECT-REQUEST-TEMPLATE> -n openshift-config -o jsonpath="{.objects[?(.kind=='NetworkPolicy')]}{'\n'}" Replace <PROJECT-REQUEST-TEMPLATE> with the name of the project request template returned from the earlier query. If the project template is not defined, or there are no Network Policy definitions in it, this is a finding.
Configure a default network policy as necessary to protect the flow of information by performing the following steps: 1. Create a bootstrap project template (if not already created) by executing the following: oc adm create-bootstrap-project-template -o yaml > template.yaml 2. Edit the template and add Network Policy object definitions before the parameters section. For example, the following section defines two policies: one to allow requests from the same namespace and one to allow from the OpenShift ingress routing service. - apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: allow-from-same-namespace spec: podSelector: ingress: - from: - podSelector: {} - apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: allow-from-openshift-ingress spec: ingress: - from: - namespaceSelector: matchLabels: network.openshift.io/policy-group: ingress podSelector: {} policyTypes: - Ingress parameters: 3. Apply the project template to the cluster by executing the following: oc create -f template.yaml -n openshift-config 4. Set the default cluster project request template by executing the following: oc patch project.config.openshift.io/cluster --type=merge -p '{"spec":{"projectRequestTemplate":{"name": "<PROJECT_REQUEST_TEMPLATE>"}}}' For additional information regarding network policies, refer to https://docs.openshift.com/container-platform/4.8/networking/network_policy/about-network-policy.html.
To verify the OpenShift CLI tool is configured to display the DOD Notice and Consent Banner, do either of the following steps: Log in to OpenShift using the oc CLI tool. oc login -u <USER> <OPENSHIFT_URL> enter password when prompted If the DOD Notice and Consent Banner is not displayed, this is a finding. Or Verify that motd config map exists and contains the DOD Notice and Consent Banner by executing the following: oc describe configmap/motd -n openshift If the configmap does not exist, or it does not contain the DOD Notice and Consent Banner text in the message data attribute, this is a finding.
The following command will create a configmap that displays the DOD Notice and Consent Banner when logging in using the OpenShift CLI tool by executing the following: echo 'apiVersion: v1 kind: ConfigMap metadata: name: motd namespace: openshift data: message: "You are accessing a U.S. Government (USG) Information System (IS) that is provided for USG-authorized use only. By using this IS (which includes any device attached to this IS), you consent to the following conditions:\n\n-The USG routinely intercepts and monitors communications on this IS for purposes including, but not limited to, penetration testing, COMSEC monitoring, network operations and defense, personnel misconduct (PM), law enforcement (LE), and counterintelligence (CI) investigations.\n\n-At any time, the USG may inspect and seize data stored on this IS.\n\n-Communications using, or data stored on, this IS are not private, are subject to routine monitoring, interception, and search, and may be disclosed or used for any USG-authorized purpose.\n\n-This IS includes security measures (e.g., authentication and access controls) to protect USG interests--not for your personal benefit or privacy.\n\n-Notwithstanding the above, using this IS does not constitute consent to PM, LE or CI investigative searching or monitoring of the content of privileged communications, or work product, related to personal representation or services by attorneys, psychotherapists, or clergy, and their assistants. Such communications and work product are private and confidential. See User Agreement for details."' | oc apply -f -
To determine at what level the OpenShift audit policy logging verbosity is configured, as a cluster-administrator:execute the following command: oc get apiserver.config.openshift.io/cluster -ojsonpath='{.spec.audit.profile}' If the output from the options does not return WriteRequestBodies or AllRequestBodies, this is a finding.
As the cluster administrator, update the APIServer.config.openshift.io/cluster object to set the profile to the defined level of detail. For example, to configure the profile to WriteRequestBodies, meaning that all write requests to any API server object are logged in their entirety, by executing the following: oc patch apiserver.config.openshift.io/cluster --type=merge -p '{"spec": {"audit": {"profile": "WriteRequestBodies"}}}'
Verify OpenShift is configured to generate audit records when successful/unsuccessful attempts to access or delete security objects, security levels, and privileges occur by executing the following: for node in $(oc get node -oname); do oc debug $node -- chroot /host /bin/bash -c 'echo -n "$HOSTNAME "; grep -e "key=perm_mod" -e "key=unsuccessful-create" -e "key=unsuccessful-modification" -e "key=unsuccessful-access" /etc/audit/audit.rules|| echo "not found"' 2>/dev/null; done Confirm the following rules exist on each node: -a always,exit -F arch=b32 -S fchmodat -F auid>=1000 -F auid!=unset -F key=perm_mod -a always,exit -F arch=b32 -S fchown -F auid>=1000 -F auid!=unset -F key=perm_mod -a always,exit -F arch=b32 -S fchownat -F auid>=1000 -F auid!=unset -F key=perm_mod -a always,exit -F arch=b32 -S fremovexattr -F auid>=1000 -F auid!=unset -F key=perm_mod -a always,exit -F arch=b32 -S fsetxattr -F auid>=1000 -F auid!=unset -F key=perm_mod -a always,exit -F arch=b32 -S lchown -F auid>=1000 -F auid!=unset -F key=perm_mod -a always,exit -F arch=b32 -S lremovexattr -F auid>=1000 -F auid!=unset -F key=perm_mod -a always,exit -F arch=b32 -S lsetxattr -F auid>=1000 -F auid!=unset -F key=perm_mod -a always,exit -F arch=b32 -S removexattr -F auid>=1000 -F auid!=unset -F key=perm_mod -a always,exit -F arch=b32 -S setxattr -F auid>=1000 -F auid!=unset -F key=perm_mod -a always,exit -F arch=b64 -S chmod -F auid>=1000 -F auid!=unset -F key=perm_mod -a always,exit -F arch=b64 -S chown -F auid>=1000 -F auid!=unset -F key=perm_mod -a always,exit -F arch=b64 -S fchmod -F auid>=1000 -F auid!=unset -F key=perm_mod -a always,exit -F arch=b64 -S fchmodat -F auid>=1000 -F auid!=unset -F key=perm_mod -a always,exit -F arch=b64 -S fchown -F auid>=1000 -F auid!=unset -F key=perm_mod -a always,exit -F arch=b64 -S fchownat -F auid>=1000 -F auid!=unset -F key=perm_mod -a always,exit -F arch=b64 -S fremovexattr -F auid>=1000 -F auid!=unset -F key=perm_mod -a always,exit -F arch=b64 -S fsetxattr -F auid>=1000 -F auid!=unset -F key=perm_mod -a always,exit -F arch=b64 -S lchown -F auid>=1000 -F auid!=unset -F key=perm_mod -a always,exit -F arch=b64 -S lremovexattr -F auid>=1000 -F auid!=unset -F key=perm_mod -a always,exit -F arch=b64 -S lsetxattr -F auid>=1000 -F auid!=unset -F key=perm_mod -a always,exit -F arch=b64 -S removexattr -F auid>=1000 -F auid!=unset -F key=perm_mod -a always,exit -F arch=b64 -S setxattr -F auid>=1000 -F auid!=unset -F key=perm_mod -a always,exit -F arch=b32 -S open -F a1&0x40 -F exit=-EACCES -F auid>=1000 -F auid!=unset -F key=unsuccessful-create -a always,exit -F arch=b32 -S open -F a1&0x40 -F exit=-EPERM -F auid>=1000 -F auid!=unset -F key=unsuccessful-create -a always,exit -F arch=b32 -S openat,open_by_handle_at -F a2&0x40 -F exit=-EACCES -F auid>=1000 -F auid!=unset -F key=unsuccessful-create -a always,exit -F arch=b32 -S openat,open_by_handle_at -F a2&0x40 -F exit=-EPERM -F auid>=1000 -F auid!=unset -F key=unsuccessful-create -a always,exit -F arch=b64 -S open -F a1&0x40 -F exit=-EACCES -F auid>=1000 -F auid!=unset -F key=unsuccessful-create -a always,exit -F arch=b64 -S open -F a1&0x40 -F exit=-EPERM -F auid>=1000 -F auid!=unset -F key=unsuccessful-create -a always,exit -F arch=b64 -S openat,open_by_handle_at -F a2&0x40 -F exit=-EACCES -F auid>=1000 -F auid!=unset -F key=unsuccessful-create -a always,exit -F arch=b64 -S openat,open_by_handle_at -F a2&0x40 -F exit=-EPERM -F auid>=1000 -F auid!=unset -F key=unsuccessful-create -a always,exit -F arch=b32 -S open -F a1&0x203 -F exit=-EACCES -F auid>=1000 -F auid!=unset -F key=unsuccessful-modification -a always,exit -F arch=b32 -S open -F a1&0x203 -F exit=-EPERM -F auid>=1000 -F auid!=unset -F key=unsuccessful-modification -a always,exit -F arch=b32 -S openat,open_by_handle_at -F a2&0x203 -F exit=-EACCES -F auid>=1000 -F auid!=unset -F key=unsuccessful-modification -a always,exit -F arch=b32 -S openat,open_by_handle_at -F a2&0x203 -F exit=-EPERM -F auid>=1000 -F auid!=unset -F key=unsuccessful-modification -a always,exit -F arch=b64 -S open -F a1&0x203 -F exit=-EACCES -F auid>=1000 -F auid!=unset -F key=unsuccessful-modification -a always,exit -F arch=b64 -S open -F a1&0x203 -F exit=-EPERM -F auid>=1000 -F auid!=unset -F key=unsuccessful-modification -a always,exit -F arch=b64 -S openat,open_by_handle_at -F a2&0x203 -F exit=-EACCES -F auid>=1000 -F auid!=unset -F key=unsuccessful-modification -a always,exit -F arch=b64 -S openat,open_by_handle_at -F a2&0x203 -F exit=-EPERM -F auid>=1000 -F auid!=unset -F key=unsuccessful-modification -a always,exit -F arch=b32 -S open,creat,truncate,ftruncate,openat,open_by_handle_at -F exit=-EACCES -F auid>=1000 -F auid!=unset -F key=unsuccessful-access -a always,exit -F arch=b32 -S open,creat,truncate,ftruncate,openat,open_by_handle_at -F exit=-EPERM -F auid>=1000 -F auid!=unset -F key=unsuccessful-access -a always,exit -F arch=b64 -S open,truncate,ftruncate,creat,openat,open_by_handle_at -F exit=-EACCES -F auid>=1000 -F auid!=unset -F key=unsuccessful-access -a always,exit -F arch=b64 -S open,truncate,ftruncate,creat,openat,open_by_handle_at -F exit=-EPERM -F auid>=1000 -F auid!=unset -F key=unsuccessful-access -a always,exit -F arch=b32 -S creat -F exit=-EACCES -F auid>=1000 -F auid!=unset -F key=unsuccessful-create -a always,exit -F arch=b32 -S creat -F exit=-EPERM -F auid>=1000 -F auid!=unset -F key=unsuccessful-create -a always,exit -F arch=b64 -S creat -F exit=-EACCES -F auid>=1000 -F auid!=unset -F key=unsuccessful-create -a always,exit -F arch=b64 -S creat -F exit=-EPERM -F auid>=1000 -F auid!=unset -F key=unsuccessful-create -a always,exit -F arch=b32 -S truncate,ftruncate -F exit=-EACCES -F auid>=1000 -F auid!=unset -F key=unsuccessful-modification -a always,exit -F arch=b32 -S truncate,ftruncate -F exit=-EPERM -F auid>=1000 -F auid!=unset -F key=unsuccessful-modification -a always,exit -F arch=b64 -S truncate,ftruncate -F exit=-EACCES -F auid>=1000 -F auid!=unset -F key=unsuccessful-modification -a always,exit -F arch=b64 -S truncate,ftruncate -F exit=-EPERM -F auid>=1000 -F auid!=unset -F key=unsuccessful-modification On each node, if the above rules are not listed, or the return is "not found", this is a finding.
Apply the machine config to generate audit records by executing following: for mcpool in $(oc get mcp -oname | sed "s:.*/::" ); do echo "apiVersion: machineconfiguration.openshift.io/v1 kind: MachineConfig metadata: name: 75-access-privileges-rules-$mcpool labels: machineconfiguration.openshift.io/role: $mcpool spec: config: ignition: version: 3.1.0 storage: files: - contents: source: data:,-a%20always%2Cexit%20-F%20arch%3Db32%20-S%20chmod%20-F%20auid%3E%3D1000%20-F%20auid%21%3Dunset%20-F%20key%3Dperm_mod%0A-a%20always%2Cexit%20-F%20arch%3Db64%20-S%20chmod%20-F%20auid%3E%3D1000%20-F%20auid%21%3Dunset%20-F%20key%3Dperm_mod%0A mode: 0644 path: /etc/audit/rules.d/75-chmod_dac_modification.rules overwrite: true - contents: source: data:,-a%20always%2Cexit%20-F%20arch%3Db32%20-S%20chown%20-F%20auid%3E%3D1000%20-F%20auid%21%3Dunset%20-F%20key%3Dperm_mod%0A-a%20always%2Cexit%20-F%20arch%3Db64%20-S%20chown%20-F%20auid%3E%3D1000%20-F%20auid%21%3Dunset%20-F%20key%3Dperm_mod%0A mode: 0644 path: /etc/audit/rules.d/75-chown_dac_modification.rules overwrite: true - contents: source: data:,-a%20always%2Cexit%20-F%20arch%3Db32%20-S%20fchmod%20-F%20auid%3E%3D1000%20-F%20auid%21%3Dunset%20-F%20key%3Dperm_mod%0A-a%20always%2Cexit%20-F%20arch%3Db64%20-S%20fchmod%20-F%20auid%3E%3D1000%20-F%20auid%21%3Dunset%20-F%20key%3Dperm_mod%0A mode: 0644 path: /etc/audit/rules.d/75-fchmod_dac_modification.rules overwrite: true - contents: source: data:,-a%20always%2Cexit%20-F%20arch%3Db32%20-S%20fchmodat%20-F%20auid%3E%3D1000%20-F%20auid%21%3Dunset%20-F%20key%3Dperm_mod%0A-a%20always%2Cexit%20-F%20arch%3Db64%20-S%20fchmodat%20-F%20auid%3E%3D1000%20-F%20auid%21%3Dunset%20-F%20key%3Dperm_mod%0A mode: 0644 path: /etc/audit/rules.d/75-fchmodat_dac_modification.rules overwrite: true - contents: source: data:,-a%20always%2Cexit%20-F%20arch%3Db32%20-S%20fchown%20-F%20auid%3E%3D1000%20-F%20auid%21%3Dunset%20-F%20key%3Dperm_mod%0A-a%20always%2Cexit%20-F%20arch%3Db64%20-S%20fchown%20-F%20auid%3E%3D1000%20-F%20auid%21%3Dunset%20-F%20key%3Dperm_mod%0A mode: 0644 path: /etc/audit/rules.d/75-fchown_dac_modification.rules overwrite: true - contents: source: data:,-a%20always%2Cexit%20-F%20arch%3Db32%20-S%20fchownat%20-F%20auid%3E%3D1000%20-F%20auid%21%3Dunset%20-F%20key%3Dperm_mod%0A-a%20always%2Cexit%20-F%20arch%3Db64%20-S%20fchownat%20-F%20auid%3E%3D1000%20-F%20auid%21%3Dunset%20-F%20key%3Dperm_mod%0A mode: 0644 path: /etc/audit/rules.d/75-fchownat_dac_modification.rules overwrite: true - contents: source: data:,-a%20always%2Cexit%20-F%20arch%3Db32%20-S%20fremovexattr%20-F%20auid%3E%3D1000%20-F%20auid%21%3Dunset%20-F%20key%3Dperm_mod%0A-a%20always%2Cexit%20-F%20arch%3Db64%20-S%20fremovexattr%20-F%20auid%3E%3D1000%20-F%20auid%21%3Dunset%20-F%20key%3Dperm_mod%0A mode: 0644 path: /etc/audit/rules.d/75-fremovexattr_dac_modification.rules overwrite: true - contents: source: data:,-a%20always%2Cexit%20-F%20arch%3Db32%20-S%20fsetxattr%20-F%20auid%3E%3D1000%20-F%20auid%21%3Dunset%20-F%20key%3Dperm_mod%0A-a%20always%2Cexit%20-F%20arch%3Db64%20-S%20fsetxattr%20-F%20auid%3E%3D1000%20-F%20auid%21%3Dunset%20-F%20key%3Dperm_mod%0A mode: 0644 path: /etc/audit/rules.d/75-fsetxattr_dac_modification.rules overwrite: true - contents: source: data:,-a%20always%2Cexit%20-F%20arch%3Db32%20-S%20lchown%20-F%20auid%3E%3D1000%20-F%20auid%21%3Dunset%20-F%20key%3Dperm_mod%0A-a%20always%2Cexit%20-F%20arch%3Db64%20-S%20lchown%20-F%20auid%3E%3D1000%20-F%20auid%21%3Dunset%20-F%20key%3Dperm_mod%0A mode: 0644 path: /etc/audit/rules.d/75-lchown_dac_modification.rules overwrite: true - contents: source: data:,-a%20always%2Cexit%20-F%20arch%3Db32%20-S%20lremovexattr%20-F%20auid%3E%3D1000%20-F%20auid%21%3Dunset%20-F%20key%3Dperm_mod%0A-a%20always%2Cexit%20-F%20arch%3Db64%20-S%20lremovexattr%20-F%20auid%3E%3D1000%20-F%20auid%21%3Dunset%20-F%20key%3Dperm_mod%0A mode: 0644 path: /etc/audit/rules.d/75-lremovexattr_dac_modification.rules overwrite: true - contents: source: data:,-a%20always%2Cexit%20-F%20arch%3Db32%20-S%20lsetxattr%20-F%20auid%3E%3D1000%20-F%20auid%21%3Dunset%20-F%20key%3Dperm_mod%0A-a%20always%2Cexit%20-F%20arch%3Db64%20-S%20lsetxattr%20-F%20auid%3E%3D1000%20-F%20auid%21%3Dunset%20-F%20key%3Dperm_mod%0A mode: 0644 path: /etc/audit/rules.d/75-lsetxattr_dac_modification.rules overwrite: true - contents: source: data:,-a%20always%2Cexit%20-F%20arch%3Db32%20-S%20removexattr%20-F%20auid%3E%3D1000%20-F%20auid%21%3Dunset%20-F%20key%3Dperm_mod%0A-a%20always%2Cexit%20-F%20arch%3Db64%20-S%20removexattr%20-F%20auid%3E%3D1000%20-F%20auid%21%3Dunset%20-F%20key%3Dperm_mod%0A mode: 0644 path: /etc/audit/rules.d/75-removexattr_dac_modification.rules overwrite: true - contents: source: data:,-a%20always%2Cexit%20-F%20arch%3Db32%20-S%20setxattr%20-F%20auid%3E%3D1000%20-F%20auid%21%3Dunset%20-F%20key%3Dperm_mod%0A-a%20always%2Cexit%20-F%20arch%3Db64%20-S%20setxattr%20-F%20auid%3E%3D1000%20-F%20auid%21%3Dunset%20-F%20key%3Dperm_mod%0A mode: 0644 path: /etc/audit/rules.d/75-setxattr_dac_modification.rules overwrite: true - contents: source: data:,%23%23%20This%20content%20is%20a%20section%20of%20an%20Audit%20config%20snapshot%20recommended%20for%20Red%2520Hat%2520Enterprise%2520Linux%2520CoreOS%25204%20systems%20that%20target%20OSPP%20compliance.%0A%23%23%20The%20following%20content%20has%20been%20retreived%20on%202019-03-11%20from%3A%20https%3A//github.com/linux-audit/audit-userspace/blob/master/rules/30-ospp-v42.rules%0A%0A%23%23%20The%20purpose%20of%20these%20rules%20is%20to%20meet%20the%20requirements%20for%20Operating%0A%23%23%20System%20Protection%20Profile%20%28OSPP%29v4.2.%20These%20rules%20depends%20on%20having%0A%23%23%2010-base-config.rules%2C%2011-loginuid.rules%2C%20and%2043-module-load.rules%20installed.%0A%0A%23%23%20Unsuccessful%20file%20creation%20%28open%20with%20O_CREAT%29%0A-a%20always%2Cexit%20-F%20arch%3Db32%20-S%20openat%2Copen_by_handle_at%20-F%20a2%260100%20-F%20exit%3D-EACCES%20-F%20auid%3E%3D1000%20-F%20auid%21%3Dunset%20-F%20key%3Dunsuccessful-create%0A-a%20always%2Cexit%20-F%20arch%3Db64%20-S%20openat%2Copen_by_handle_at%20-F%20a2%260100%20-F%20exit%3D-EACCES%20-F%20auid%3E%3D1000%20-F%20auid%21%3Dunset%20-F%20key%3Dunsuccessful-create%0A-a%20always%2Cexit%20-F%20arch%3Db32%20-S%20open%20-F%20a1%260100%20-F%20exit%3D-EACCES%20-F%20auid%3E%3D1000%20-F%20auid%21%3Dunset%20-F%20key%3Dunsuccessful-create%0A-a%20always%2Cexit%20-F%20arch%3Db64%20-S%20open%20-F%20a1%260100%20-F%20exit%3D-EACCES%20-F%20auid%3E%3D1000%20-F%20auid%21%3Dunset%20-F%20key%3Dunsuccessful-create%0A-a%20always%2Cexit%20-F%20arch%3Db32%20-S%20openat%2Copen_by_handle_at%20-F%20a2%260100%20-F%20exit%3D-EPERM%20-F%20auid%3E%3D1000%20-F%20auid%21%3Dunset%20-F%20key%3Dunsuccessful-create%0A-a%20always%2Cexit%20-F%20arch%3Db64%20-S%20openat%2Copen_by_handle_at%20-F%20a2%260100%20-F%20exit%3D-EPERM%20-F%20auid%3E%3D1000%20-F%20auid%21%3Dunset%20-F%20key%3Dunsuccessful-create%0A-a%20always%2Cexit%20-F%20arch%3Db32%20-S%20open%20-F%20a1%260100%20-F%20exit%3D-EPERM%20-F%20auid%3E%3D1000%20-F%20auid%21%3Dunset%20-F%20key%3Dunsuccessful-create%0A-a%20always%2Cexit%20-F%20arch%3Db64%20-S%20open%20-F%20a1%260100%20-F%20exit%3D-EPERM%20-F%20auid%3E%3D1000%20-F%20auid%21%3Dunset%20-F%20key%3Dunsuccessful-create%0A-a%20always%2Cexit%20-F%20arch%3Db32%20-S%20creat%20-F%20exit%3D-EACCES%20-F%20auid%3E%3D1000%20-F%20auid%21%3Dunset%20-F%20key%3Dunsuccessful-create%0A-a%20always%2Cexit%20-F%20arch%3Db64%20-S%20creat%20-F%20exit%3D-EACCES%20-F%20auid%3E%3D1000%20-F%20auid%21%3Dunset%20-F%20key%3Dunsuccessful-create%0A-a%20always%2Cexit%20-F%20arch%3Db32%20-S%20creat%20-F%20exit%3D-EPERM%20-F%20auid%3E%3D1000%20-F%20auid%21%3Dunset%20-F%20key%3Dunsuccessful-create%0A-a%20always%2Cexit%20-F%20arch%3Db64%20-S%20creat%20-F%20exit%3D-EPERM%20-F%20auid%3E%3D1000%20-F%20auid%21%3Dunset%20-F%20key%3Dunsuccessful-create%0A%0A%23%23%20Unsuccessful%20file%20modifications%20%28open%20for%20write%20or%20truncate%29%0A-a%20always%2Cexit%20-F%20arch%3Db32%20-S%20openat%2Copen_by_handle_at%20-F%20a2%2601003%20-F%20exit%3D-EACCES%20-F%20auid%3E%3D1000%20-F%20auid%21%3Dunset%20-F%20key%3Dunsuccessful-modification%0A-a%20always%2Cexit%20-F%20arch%3Db64%20-S%20openat%2Copen_by_handle_at%20-F%20a2%2601003%20-F%20exit%3D-EACCES%20-F%20auid%3E%3D1000%20-F%20auid%21%3Dunset%20-F%20key%3Dunsuccessful-modification%0A-a%20always%2Cexit%20-F%20arch%3Db32%20-S%20open%20-F%20a1%2601003%20-F%20exit%3D-EACCES%20-F%20auid%3E%3D1000%20-F%20auid%21%3Dunset%20-F%20key%3Dunsuccessful-modification%0A-a%20always%2Cexit%20-F%20arch%3Db64%20-S%20open%20-F%20a1%2601003%20-F%20exit%3D-EACCES%20-F%20auid%3E%3D1000%20-F%20auid%21%3Dunset%20-F%20key%3Dunsuccessful-modification%0A-a%20always%2Cexit%20-F%20arch%3Db32%20-S%20openat%2Copen_by_handle_at%20-F%20a2%2601003%20-F%20exit%3D-EPERM%20-F%20auid%3E%3D1000%20-F%20auid%21%3Dunset%20-F%20key%3Dunsuccessful-modification%0A-a%20always%2Cexit%20-F%20arch%3Db64%20-S%20openat%2Copen_by_handle_at%20-F%20a2%2601003%20-F%20exit%3D-EPERM%20-F%20auid%3E%3D1000%20-F%20auid%21%3Dunset%20-F%20key%3Dunsuccessful-modification%0A-a%20always%2Cexit%20-F%20arch%3Db32%20-S%20open%20-F%20a1%2601003%20-F%20exit%3D-EPERM%20-F%20auid%3E%3D1000%20-F%20auid%21%3Dunset%20-F%20key%3Dunsuccessful-modification%0A-a%20always%2Cexit%20-F%20arch%3Db64%20-S%20open%20-F%20a1%2601003%20-F%20exit%3D-EPERM%20-F%20auid%3E%3D1000%20-F%20auid%21%3Dunset%20-F%20key%3Dunsuccessful-modification%0A-a%20always%2Cexit%20-F%20arch%3Db32%20-S%20truncate%2Cftruncate%20-F%20exit%3D-EACCES%20-F%20auid%3E%3D1000%20-F%20auid%21%3Dunset%20-F%20key%3Dunsuccessful-modification%0A-a%20always%2Cexit%20-F%20arch%3Db64%20-S%20truncate%2Cftruncate%20-F%20exit%3D-EACCES%20-F%20auid%3E%3D1000%20-F%20auid%21%3Dunset%20-F%20key%3Dunsuccessful-modification%0A-a%20always%2Cexit%20-F%20arch%3Db32%20-S%20truncate%2Cftruncate%20-F%20exit%3D-EPERM%20-F%20auid%3E%3D1000%20-F%20auid%21%3Dunset%20-F%20key%3Dunsuccessful-modification%0A-a%20always%2Cexit%20-F%20arch%3Db64%20-S%20truncate%2Cftruncate%20-F%20exit%3D-EPERM%20-F%20auid%3E%3D1000%20-F%20auid%21%3Dunset%20-F%20key%3Dunsuccessful-modification%0A%0A%23%23%20Unsuccessful%20file%20access%20%28any%20other%20opens%29%20This%20has%20to%20go%20last.%0A-a%20always%2Cexit%20-F%20arch%3Db32%20-S%20open%2Ccreat%2Ctruncate%2Cftruncate%2Copenat%2Copen_by_handle_at%20-F%20exit%3D-EACCES%20-F%20auid%3E%3D1000%20-F%20auid%21%3Dunset%20-F%20key%3Dunsuccessful-access%0A-a%20always%2Cexit%20-F%20arch%3Db64%20-S%20open%2Ccreat%2Ctruncate%2Cftruncate%2Copenat%2Copen_by_handle_at%20-F%20exit%3D-EACCES%20-F%20auid%3E%3D1000%20-F%20auid%21%3Dunset%20-F%20key%3Dunsuccessful-access%0A-a%20always%2Cexit%20-F%20arch%3Db32%20-S%20open%2Ccreat%2Ctruncate%2Cftruncate%2Copenat%2Copen_by_handle_at%20-F%20exit%3D-EPERM%20-F%20auid%3E%3D1000%20-F%20auid%21%3Dunset%20-F%20key%3Dunsuccessful-access%0A-a%20always%2Cexit%20-F%20arch%3Db64%20-S%20open%2Ccreat%2Ctruncate%2Cftruncate%2Copenat%2Copen_by_handle_at%20-F%20exit%3D-EPERM%20-F%20auid%3E%3D1000%20-F%20auid%21%3Dunset%20-F%20key%3Dunsuccessful-access%0A mode: 0644 path: /etc/audit/rules.d/30-ospp-v42-remediation.rules overwrite: true " | oc apply -f - done
Verify the RHCOS boot loader configuration has audit enabled, including backlog: for node in $(oc get node -oname); do oc debug $node -- chroot /host /bin/bash -c 'echo -n "$HOSTNAME "; grep audit /boot/loader/entries/*.conf || echo "not found"' 2>/dev/null; done If "audit" is not set to "1" or returns "not found", this is a finding. If "audit_backlog" is not set to 8192 or returns "not found", this is a finding.
Apply the machine config by executing the following: for mcpool in $(oc get mcp -oname | sed "s:.*/::" ); do echo "apiVersion: machineconfiguration.openshift.io/v1 kind: MachineConfig metadata: name: 05-kernelarg-audit-enabled-$mcpool labels: machineconfiguration.openshift.io/role: $mcpool spec: config: ignition: version: 3.1.0 kernelArguments: - audit=1 - audit_backlog_limit=8192 " | oc create -f - done
Verify the audit service is enabled and active by executing the following: for node in $(oc get node -oname); do oc debug $node -- chroot /host /bin/bash -c 'echo -n "$HOSTNAME "; systemctl is-enabled auditd.service; systemctl is-active auditd.service' 2>/dev/null; done If the auditd service is not "enabled" and "active" this is a finding.
Apply the machine config setting auditd to active and enabled by executing the following: for mcpool in $(oc get mcp -oname | sed "s:.*/::" ); do echo "apiVersion: machineconfiguration.openshift.io/v1 kind: MachineConfig metadata: name: 80-auditd-service-enable-$mcpool labels: machineconfiguration.openshift.io/role: $mcpool spec: config: ignition: version: 3.1.0 systemd: units: - name: auditd.service enabled: true " | oc apply -f - done
1. Verify Red Hat Enterprise Linux CoreOS (RHCOS) Audit Daemon is configured to resolve audit information before writing to disk by executing the following command: for node in $(oc get node -oname); do oc debug $node -- chroot /host /bin/bash -c 'echo -n "$HOSTNAME "; grep "log_format" /etc/audit/auditd.conf' 2>/dev/null; done If the "log_format" option is not "ENRICHED", or the line is missing or commented out, this is a finding. 2. Verify RHCOS takes the appropriate action when an audit processing failure occurs. Verify RHCOS takes the appropriate action when an audit processing failure occurs by executing following command: for node in $(oc get node -oname); do oc debug $node -- chroot /host /bin/bash -c 'echo -n "$HOSTNAME "; grep disk_error_action /etc/audit/auditd.conf' 2>/dev/null; done If the value of the "disk_error_action" option is not "SYSLOG", "SINGLE", or "HALT", or the line is missing or commented out, ask the system administrator to indicate how the system takes appropriate action when an audit process failure occurs. If there is no evidence of appropriate action, this is a finding. 3. Verify the SA and ISSO (at a minimum) are notified when the audit storage volume is full. Check which action RHEL takes when the audit storage volume is full by executing the following command: for node in $(oc get node -oname); do oc debug $node -- chroot /host /bin/bash -c 'echo -n "$HOSTNAME "; grep max_log_file_action /etc/audit/auditd.conf' 2>/dev/null; done If the value of the "max_log_file_action" option is set to "ignore", "rotate", or "suspend", or the line is missing or commented out, ask the system administrator to indicate how the system takes appropriate action when an audit storage volume is full. If there is no evidence of appropriate action, this is a finding.
Apply the machine config by executing the following: for mcpool in $(oc get mcp -oname | sed "s:.*/::" ); do echo "apiVersion: machineconfiguration.openshift.io/v1 kind: MachineConfig metadata: name: 70-auditd-conf-$mcpool labels: machineconfiguration.openshift.io/role: $mcpool spec: config: ignition: version: 3.1.0 storage: files: - contents: source: data:,%23%0A%23%20This%20file%20controls%20the%20configuration%20of%20the%20audit%20daemon%0A%23%0A%0Alocal_events%20%3D%20yes%0Awrite_logs%20%3D%20yes%0Alog_file%20%3D%20%2Fvar%2Flog%2Faudit%2Faudit.log%0Alog_group%20%3D%20root%0Alog_format%20%3D%20ENRICHED%0Aflush%20%3D%20incremental_async%0Afreq%20%3D%2050%0Amax_log_file%20%3D%206%0Anum_logs%20%3D%205%0Apriority_boost%20%3D%204%0Aname_format%20%3D%20hostname%0A%23%23name%20%3D%20mydomain%0Amax_log_file_action%20%3D%20syslog%0Aspace_left%20%3D%2025%25%0Aspace_left_action%20%3D%20syslog%0Averify_email%20%3D%20yes%0Aaction_mail_acct%20%3D%20root%0Aadmin_space_left%20%3D%2050%0Aadmin_space_left_action%20%3D%20syslog%0Adisk_full_action%20%3D%20HALT%0Adisk_error_action%20%3D%20HALT%0Ause_libwrap%20%3D%20yes%0A%23%23tcp_listen_port%20%3D%2060%0Atcp_listen_queue%20%3D%205%0Atcp_max_per_addr%20%3D%201%0A%23%23tcp_client_ports%20%3D%201024-65535%0Atcp_client_max_idle%20%3D%200%0Atransport%20%3D%20TCP%0Akrb5_principal%20%3D%20auditd%0A%23%23krb5_key_file%20%3D%20%2Fetc%2Faudit%2Faudit.key%0Adistribute_network%20%3D%20no%0Aq_depth%20%3D%20400%0Aoverflow_action%20%3D%20syslog%0Amax_restarts%20%3D%2010%0Aplugin_dir%20%3D%20%2Fetc%2Faudit%2Fplugins.d%0A mode: 0640 path: /etc/audit/auditd.conf overwrite: true " | oc apply -f - done
1. Verify Red Hat Enterprise Linux CoreOS (RHCOS) Audit Daemon is configured to resolve audit information before writing to disk, by executing the following command: for node in $(oc get node -oname); do oc debug $node -- chroot /host /bin/bash -c 'echo -n "$HOSTNAME "; grep "log_format" /etc/audit/auditd.conf' 2>/dev/null; done If the "log_format" option is not "ENRICHED", or the line is missing or commented out, this is a finding. 2. Verify RHCOS takes the appropriate action when an audit processing failure occurs by executing following command: for node in $(oc get node -oname); do oc debug $node -- chroot /host /bin/bash -c 'echo -n "$HOSTNAME "; grep disk_error_action /etc/audit/auditd.conf' 2>/dev/null; done If the value of the "disk_error_action" option is not "SYSLOG", "SINGLE", or "HALT", or the line is missing, or commented out, ask the system administrator to indicate how the system takes appropriate action when an audit process failure occurs. If there is no evidence of appropriate action, this is a finding. 3. Verify the SA and ISSO (at a minimum) are notified when the audit storage volume is full. Check which action RHEL takes when the audit storage volume is full by executing the following command: for node in $(oc get node -oname); do oc debug $node -- chroot /host /bin/bash -c 'echo -n "$HOSTNAME "; grep max_log_file_action /etc/audit/auditd.conf' 2>/dev/null; done If the value of the "max_log_file_action" option is set to "ignore", "rotate", or "suspend", or the line is missing or commented out, ask the system administrator to indicate how the system takes appropriate action when an audit storage volume is full. If there is no evidence of appropriate action, this is a finding.
Apply the machine config by executing the following: for mcpool in $(oc get mcp -oname | sed "s:.*/::" ); do echo "apiVersion: machineconfiguration.openshift.io/v1 kind: MachineConfig metadata: name: 70-auditd-conf-$mcpool labels: machineconfiguration.openshift.io/role: $mcpool spec: config: ignition: version: 3.1.0 storage: files: - contents: source: data:,%23%0A%23%20This%20file%20controls%20the%20configuration%20of%20the%20audit%20daemon%0A%23%0A%0Alocal_events%20%3D%20yes%0Awrite_logs%20%3D%20yes%0Alog_file%20%3D%20%2Fvar%2Flog%2Faudit%2Faudit.log%0Alog_group%20%3D%20root%0Alog_format%20%3D%20ENRICHED%0Aflush%20%3D%20incremental_async%0Afreq%20%3D%2050%0Amax_log_file%20%3D%206%0Anum_logs%20%3D%205%0Apriority_boost%20%3D%204%0Aname_format%20%3D%20hostname%0A%23%23name%20%3D%20mydomain%0Amax_log_file_action%20%3D%20syslog%0Aspace_left%20%3D%2025%25%0Aspace_left_action%20%3D%20syslog%0Averify_email%20%3D%20yes%0Aaction_mail_acct%20%3D%20root%0Aadmin_space_left%20%3D%2050%0Aadmin_space_left_action%20%3D%20syslog%0Adisk_full_action%20%3D%20HALT%0Adisk_error_action%20%3D%20HALT%0Ause_libwrap%20%3D%20yes%0A%23%23tcp_listen_port%20%3D%2060%0Atcp_listen_queue%20%3D%205%0Atcp_max_per_addr%20%3D%201%0A%23%23tcp_client_ports%20%3D%201024-65535%0Atcp_client_max_idle%20%3D%200%0Atransport%20%3D%20TCP%0Akrb5_principal%20%3D%20auditd%0A%23%23krb5_key_file%20%3D%20%2Fetc%2Faudit%2Faudit.key%0Adistribute_network%20%3D%20no%0Aq_depth%20%3D%20400%0Aoverflow_action%20%3D%20syslog%0Amax_restarts%20%3D%2010%0Aplugin_dir%20%3D%20%2Fetc%2Faudit%2Fplugins.d%0A mode: 0640 path: /etc/audit/auditd.conf overwrite: true " | oc apply -f - done
Verify there is a Prometheus rule to watch for audit events by executing the following: oc get prometheusrule -o yaml --all-namespaces | grep apiserver_audit Output: sum by (apiserver,instance)(rate(apiserver_audit_error_total{apiserver=~".+-apiserver"}[5m])) / sum by (apiserver,instance) (rate(apiserver_audit_event_total{apiserver=~".+-apiserver"}[5m])) > 0 If the output above is not displayed, this is a finding.
Apply the following Prometheus rule by executing the following: oc apply -f - << 'EOF' --- # platform = multi_platform_ocp apiVersion: monitoring.coreos.com/v1 kind: PrometheusRule metadata: name: audit-errors namespace: openshift-kube-apiserver spec: groups: - name: apiserver-audit rules: - alert: AuditLogError annotations: summary: |- An API Server instance was unable to write audit logs. This could be triggered by the node running out of space, or a malicious actor tampering with the audit logs. description: An API Server had an error writing to an audit log. expr: | sum by (apiserver,instance)(rate(apiserver_audit_error_total{apiserver=~".+-apiserver"}[5m])) / sum by (apiserver,instance) (rate(apiserver_audit_event_total{apiserver=~".+-apiserver"}[5m])) > 0 for: 1m labels: severity: warning EOF
Determine if cluster log forwarding is configured. 1. Verify the cluster-logging operator is installed by executing the following: oc get subscription/cluster-logging -n openshift-logging (Example Output: NAME PACKAGE SOURCE CHANNEL cluster-logging cluster-logging redhat-operators stable ) If the cluster-logging operator is not present, this is a finding. 2. List the cluster log forwarders defined by executing the following: oc get clusterlogforwarder -n openshift-logging If there are no clusterlogforwarders defined, this is a finding. 3. For each cluster log forwarder listed above, view the configuration details by executing the following: oc describe clusterlogforwarder/<CLF_NAME> -n openshift-logging Review the details of the cluster log forwarder. If the configuration is not set to forward logs the organization's centralized logging service, this is a finding.
To configure log forwarding, the OpenShift Cluster Logging operator first must be installed, and then the Cluster Log Forwarder is configured to forward logs to a centralized log aggregation service. To install the OpenShift Cluster Logging operator, execute the following command to apply the subscription manifests to the cluster: oc apply -f - << 'EOF' --- apiVersion: project.openshift.io/v1 kind: Project metadata: labels: kubernetes.io/metadata.name: openshift-logging openshift.io/cluster-monitoring: "true" name: openshift-logging spec: {} ... --- apiVersion: operators.coreos.com/v1 kind: OperatorGroup metadata: name: openshift-logging namespace: openshift-logging spec: targetNamespaces: - openshift-logging ... --- apiVersion: operators.coreos.com/v1alpha1 kind: Subscription metadata: labels: operators.coreos.com/cluster-logging.openshift-logging: "" name: cluster-logging namespace: openshift-logging spec: channel: stable installPlanApproval: Automatic name: cluster-logging source: redhat-operators sourceNamespace: openshift-marketplace ... EOF After the OpenShift Logging operator has finished installing, a ClusterLogForwarder instance can be created to forward cluster logs to a log aggregator. A basic configuration that would forward OpenShift audit, application, and infrastructure logs to an rsyslog server that is managed separately and is configured for mTLS authentication over TCP when sending audit logs, but traditional UDP access for other types of logs, can be provided by editing the appropriate values in the Secret resource below and changing the "url" parameters in the "outputs" section of the "spec" below, then running the command to apply (Example): oc apply -f - << 'EOF' --- apiVersion: v1 kind: Secret metadata: name: rsyslog-tls-secret namespace: openshift-logging data: tls.crt: <base64 encoded client certificate> tls.key: <base64 encoded client key> ca-bundle.crt: <base64 encoded CA bundle that signed the certificate of your rsyslog server> ... --- apiVersion: logging.openshift.io/v1 kind: ClusterLogForwarder metadata: name: instance namespace: openshift-logging spec: outputs: - name: rsyslog-audit type: syslog syslog: facility: security rfc: RFC5424 severity: Informational appName: openshift msgID: audit procID: audit url: 'tls://rsyslogserver.example.com:514' secret: name: rsyslog-tls-secret - name: rsyslog-apps type: syslog syslog: facility: user rfc: RFC5424 severity: Informational appName: openshift msgID: apps procID: apps url: 'udp://rsyslogserver.example.com:514' - name: rsyslog-infra type: syslog syslog: facility: local0 rfc: RFC5424 severity: Informational appName: openshift msgID: infra procID: infra url: 'udp://rsyslogserver.example.com:514' pipelines: - name: audit-logs inputRefs: - audit outputRefs: - rsyslog-audit - name: apps-logs inputRefs: - application outputRefs: - rsyslog-apps - name: infrastructure-logs inputRefs: - infrastructure outputRefs: - rsyslog-infra ... EOF Note that many log forwarding destinations are supported, and the fix does not require that users forward audit logs to rsyslog over mTLS. To better understand how to configure the ClusterLogForwarder, consult the OpenShift Logging documentation: https://docs.openshift.com/container-platform/4.8/logging/cluster-logging-external.html
Verify the chronyd service is enabled and active by executing the following: for node in $(oc get node -oname); do oc debug $node -- chroot /host /bin/bash -c 'echo -n "$HOSTNAME "; systemctl is-enabled chronyd.service; systemctl is-active chronyd.service' 2>/dev/null; done If the auditd service is not "enabled" and "active", this is a finding.
Apply the machine config to use internal system clocks for audit records by executing the following: for mcpool in $(oc get mcp -oname | sed "s:.*/::" ); do echo "apiVersion: machineconfiguration.openshift.io/v1 kind: MachineConfig metadata: name: 80-chronyd-service-enable-$mcpool labels: machineconfiguration.openshift.io/role: $mcpool spec: config: ignition: version: 3.1.0 systemd: units: - name: chronyd.service enabled: true " | oc apply -f - done
Verify Red Hat Enterprise Linux CoreOS (RHCOS) chrony Daemon is configured to use multiple NTP servers by executing the following: for node in $(oc get node -oname); do oc debug $node -- chroot /host /bin/bash -c 'echo -n "$HOSTNAME "; grep "server" /etc/chrony.d/*' 2>/dev/null; done (Sample output: server <SERVER1.EXAMPLE.COM> minpoll 4 maxpoll 10 server <SERVER2.EXAMPLE.COM> minpoll 4 maxpoll 10) If multiple NTP servers are not configured, this is a finding.
Apply the machine config by executing the following, replacing the variables in the MachineConfig with organizationally-defined NTP servers. for mcpool in $(oc get mcp -oname | sed ""s:.*/::"" ); do echo "apiVersion: machineconfiguration.openshift.io/v1 kind: MachineConfig metadata: name: 90-chrony-ntp-servers-set-$mcpool labels: machineconfiguration.openshift.io/role: $mcpool spec: config: ignition: version: 3.1.0 storage: files: - contents: source: data:,%23%20Allow%20for%20extra%20configuration%20files.%20This%20is%20useful%0A%23%20for%20admins%20specifying%20their%20own%20NTP%20servers%0Ainclude%20%2Fetc%2Fchrony.d%2F%2A.conf%0A%0A%23%20Set%20chronyd%20as%20client-only.%0Aport%200%0A%0A%23%20Disable%20chronyc%20from%20the%20network%0Acmdport%200%0A%0A%23%20Record%20the%20rate%20at%20which%20the%20system%20clock%20gains%2Flosses%20time.%0Adriftfile%20%2Fvar%2Flib%2Fchrony%2Fdrift%0A%0A%23%20Allow%20the%20system%20clock%20to%20be%20stepped%20in%20the%20first%20three%20updates%0A%23%20if%20its%20offset%20is%20larger%20than%201%20second.%0Amakestep%201.0%203%0A%0A%23%20Enable%20kernel%20synchronization%20of%20the%20real-time%20clock%20%28RTC%29.%0Artcsync%0A%0A%23%20Enable%20hardware%20timestamping%20on%20all%20interfaces%20that%20support%20it.%0A%23hwtimestamp%20%2A%0A%0A%23%20Increase%20the%20minimum%20number%20of%20selectable%20sources%20required%20to%20adjust%0A%23%20the%20system%20clock.%0A%23minsources%202%0A%0A%23%20Allow%20NTP%20client%20access%20from%20local%20network.%0A%23allow%20192.168.0.0%2F16%0A%0A%23%20Serve%20time%20even%20if%20not%20synchronized%20to%20a%20time%20source.%0A%23local%20stratum%2010%0A%0A%23%20Require%20authentication%20%28nts%20or%20key%20option%29%20for%20all%20NTP%20sources.%0A%23authselectmode%20require%0A%0A%23%20Specify%20file%20containing%20keys%20for%20NTP%20authentication.%0Akeyfile%20%2Fetc%2Fchrony.keys%0A%0A%23%20Insert%2Fdelete%20leap%20seconds%20by%20slewing%20instead%20of%20stepping.%0A%23leapsecmode%20slew%0A%0A%23%20Get%20TAI-UTC%20offset%20and%20leap%20seconds%20from%20the%20system%20tz%20database.%0Aleapsectz%20right%2FUTC%0A%0A%23%20Specify%20directory%20for%20log%20files.%0Alogdir%20%2Fvar%2Flog%2Fchrony%0A%0A%23%20Select%20which%20information%20is%20logged.%0A%23log%20measurements%20statistics%20tracking mode: 420 overwrite: true path: /etc/chrony.conf - contents: source: data:, mode: 420 overwrite: true path: /etc/chrony.d/.mco-keep - contents: source: data:,%23%0A%23%20This%20file%20controls%20the%20configuration%20of%20the%20ntp%20server%0A%23%200.pool.ntp.org%2C1.pool.ntp.org%2C2.pool.ntp.org%2C3.pool.ntp.org%20we%20have%20to%20put%20variable%20array%20name%20here%20for%20mutilines%20remediation%20%0A%0Aserver%20<SERVER1.EXAMPLE.COM>%20minpoll%204%20maxpoll%2010%0Aserver%20<SERVER2.EXAMPLE.COM>%20minpoll%204%20maxpoll%2010%0Aserver%20<SERVER3.EXAMPLE.COM>%20minpoll%204%20maxpoll%2010%0Aserver%20<SERVER4.EXAMPLE.COM>%20minpoll%204%20maxpoll%2010%0A mode: 420 overwrite: true path: /etc/chrony.d/ntp-server.conf " | oc apply -f - done
Verify the audit logs have a mode of "0600" by executing the following: for node in $(oc get node -oname); do oc debug $node -- chroot /host /bin/bash -c 'echo -n "$HOSTNAME "; stat -c "%a %n" /var/log/audit/audit.log' 2>/dev/null; done (Sample Output: 600 /var/log/audit/audit.log) If the audit log has a mode more permissive than "0600", this is a finding. Determine if the audit log is owned by "root" executing the following command: for node in $(oc get node -oname); do oc debug $node -- chroot /host /bin/bash -c 'echo -n "$HOSTNAME "; ls -l /var/log/audit/audit.log' 2>/dev/null; done (Sample Output: rw------- 2 root root 23 Jun 11 11:56 /var/log/audit/audit.log) If the audit log is not owned by "root", this is a finding. Verify the audit log directory is group-owned by "root" to prevent unauthorized read access by executing the following. for node in $(oc get node -oname); do oc debug $node -- chroot /host /bin/bash -c 'echo -n "$HOSTNAME "; ls -ld /var/log/audit' 2>/dev/null; done (Sample Output: drw------- 2 root root 23 Jun 11 11:56 /var/log/audit) If the audit log directory is not group-owned by "root", this is a finding. Verify the audit log directories have a mode of "0700" by executing the following command: for node in $(oc get node -oname); do oc debug $node -- chroot /host /bin/bash -c 'echo -n "$HOSTNAME "; stat -c "%a %n" /var/log/audit' 2>/dev/null; done (Sample Output: 700 /var/log/audit) If the audit log directory has a mode more permissive than "0700", this is a finding.
Correct permissions (audit logs have a mode of "0600") by executing the following: for node in $(oc get node -oname); do oc debug $node -- chroot /host /bin/bash -c 'echo -n "$HOSTNAME "; machine_id=$(systemd-machine-id-setup --print); chmod 600 /var/log/audit/audit.log' 2>/dev/null; done Correct permissions (audit log is owned by "root") by executing the following: for node in $(oc get node -oname); do oc debug $node -- chroot /host /bin/bash -c 'echo -n "$HOSTNAME "; machine_id=$(systemd-machine-id-setup --print); chown root:root /var/log/audit/audit.log' 2>/dev/null; done Correct permissions (audit log directory is group-owned by "root") by executing the following: for node in $(oc get node -oname); do oc debug $node -- chroot /host /bin/bash -c 'echo -n "$HOSTNAME "; machine_id=$(systemd-machine-id-setup --print); chown root:root /var/log/audit' 2>/dev/null; done Correct permissions ( audit log directories have a mode of "0700") by executing the following: for node in $(oc get node -oname); do oc debug $node -- chroot /host /bin/bash -c 'echo -n "$HOSTNAME "; machine_id=$(systemd-machine-id-setup --print); chmod 700 /var/log/audit' 2>/dev/null; done
Verify the system journal file has mode "0640" or less permissive by executing the following: for node in $(oc get node -oname); do oc debug $node -- chroot /host /bin/bash -c 'echo -n "$HOSTNAME "; machine_id=$(systemd-machine-id-setup --print); stat -c "%a %n" /var/log/journal/$machine_id/system.journal' 2>/dev/null; done If a value of "0640" or less permissive is not returned, this is a finding.
Correct journal file permissions by executing the following: for node in $(oc get node -oname); do oc debug $node -- chroot /host /bin/bash -c 'echo -n "$HOSTNAME "; machine_id=$(systemd-machine-id-setup --print); chmod 640 /var/log/journal/$machine_id/system.journal' 2>/dev/null; done
Verify the "system journal" file is group-owned by systemd-journal and owned by root by executing the following: for node in $(oc get node -oname); do oc debug $node -- chroot /host /bin/bash -c 'echo -n "$HOSTNAME "; machine_id=$(systemd-machine-id-setup --print); stat -c "%U %G" /var/log/journal/$machine_id/system.journal' 2>/dev/null; done Example output: ip-10-0-150-1 root systemd-journal If "root" is not returned as the owner, this is a finding. If "systemd-journald" is not returned as the group owner, this is a finding.
Correct journal file ownership by executing the following: for node in $(oc get node -oname); do oc debug $node -- chroot /host /bin/bash -c 'echo -n "$HOSTNAME "; machine_id=$(systemd-machine-id-setup --print); chown root:systemd-journal /var/log/journal/$machine_id/system.journal' 2>/dev/null; done
Verify the "/var/log" directory has a mode of "0755" or less by executing the following: for node in $(oc get node -oname); do oc debug $node -- chroot /host /bin/bash -c 'echo -n "$HOSTNAME "; stat -c "%a %n" /var/log' 2>/dev/null; done If a value of "0755" or less permissive is not returned, this is a finding.
Correct log directory permissions by executing the following: for node in $(oc get node -oname); do oc debug $node -- chroot /host /bin/bash -c 'echo -n "$HOSTNAME "; chmod 755 /var/log/' 2>/dev/null; done
Verify the "/var/log" directory is group-owned by root by executing the following command: for node in $(oc get node -oname); do oc debug $node -- chroot /host /bin/bash -c 'echo -n "$HOSTNAME "; stat -c "%G" /var/log' 2>/dev/null; done If "root" is not returned as a result, this is a finding.
Correct log directory ownership by executing the following: for node in $(oc get node -oname); do oc debug $node -- chroot /host /bin/bash -c 'echo -n "$HOSTNAME "; chown root:root /var/log/' 2>/dev/null; done
Verify the permissions and ownership of files located under "/var/log/pods" that store the output of pods are set to protect from unauthorized access. 1. Verify the files are readable only by the owner by executing the following command: for node in $(oc get node -oname); do oc debug $node -- chroot /host /bin/bash -c 'echo -n "$HOSTNAME "; find /var/log/pods/ -type f \( -perm /022 -o -perm /044 \)' 2>/dev/null; done If any files are returned, this is a finding. 2. Verify files are group-owned by root and owned by root by executing the following: for node in $(oc get node -oname); do oc debug $node -- chroot /host /bin/bash -c 'echo -n "$HOSTNAME "; find /var/log/pods/ -type f \! -user 0' 2>/dev/null; done (Example output: ip-10-0-150-1 root root) If "root" is not returned as the owner, this is a finding. If "root" is not returned as the group owner, this is a finding.
Change the permissions and ownership of files located under "/var/log/pods" to protect from unauthorized access. 1. Execute the following to set the output of pods readable only by the owner: for node in $(oc get node -oname); do oc debug $node -- chroot /host /bin/bash -c 'echo -n "$HOSTNAME "; find /var/log/pods/ -type f \( -perm /022 -o -perm /044 \) | xargs -r chmod 600' 2>/dev/null; done 2. Execute the following to set the group and group-ownership to root for files that store the output of pods: for node in $(oc get node -oname); do oc debug $node -- chroot /host /bin/bash -c 'echo -n "$HOSTNAME "; find /var/log/pods/ -type f \! -user 0 | xargs -r chown root:root' 2>/dev/null; done
Verify the audit system prevents unauthorized changes by executing the following command: for node in $(oc get node -oname); do oc debug $node -- chroot /host /bin/bash -c 'echo -n ""$HOSTNAME ""; grep "^\-e\s2\s*$" /etc/audit/audit.rules /etc/audit/rules.d/* || echo "not found"' 2>/dev/null; done If the check returns "not found", the audit system is not set to be immutable by adding the ""-e 2"" option to the ""/etc/audit/audit.rules"", this is a finding.
Apply the machine config to prevent unauthorized changes by executing the following: for mcpool in $(oc get mcp -oname | sed "s:.*/::" ); do echo "apiVersion: machineconfiguration.openshift.io/v1 kind: MachineConfig metadata: name: 90-immutable-rules-$mcpool labels: machineconfiguration.openshift.io/role: $mcpool spec: config: ignition: version: 3.1.0 storage: files: - contents: source: data:,-e%202%0A mode: 0600 path: /etc/audit/rules.d/90-immutable.rules overwrite: true " | oc apply -f - done
Verify the audit system prevents unauthorized changes to logon UIDs by executing the following: for node in $(oc get node -oname); do oc debug $node -- chroot /host /bin/bash -c 'echo -n "$HOSTNAME "; grep -i immutable /etc/audit/audit.rules || echo "not found"' 2>/dev/null; done If the login UIDs are not set to be immutable by adding the "--loginuid-immutable" option to the "/etc/audit/audit.rules", this is a finding.
Apply the machine config to prevent changes to logon UIDs by executing the following: for mcpool in $(oc get mcp -oname | sed "s:.*/::" ); do echo "apiVersion: machineconfiguration.openshift.io/v1 kind: MachineConfig metadata: name: 11-loginuid-rules-$mcpool labels: machineconfiguration.openshift.io/role: $mcpool spec: config: ignition: version: 3.1.0 storage: files: - contents: source: data:,%23%23%20Make%20the%20loginuid%20immutable.%20This%20prevents%20tampering%20with%20the%20auid.%0A--loginuid-immutable%0A mode: 0644 path: /etc/audit/rules.d/11-loginuid.rules overwrite: true " | oc apply -f - done
List the users and groups who have permission to view the cluster logging configuration by executing the following two commands: oc policy who-can view ClusterLogging -n openshift-logging oc policy who-can view ClusterLoggingForwarder -n openshift-logging Review the list of users and groups who have view access to the cluster logging resources. If any user or group listed must not have access to view the cluster logging resources, this is a finding.
Remove view permissions from any unauthorized user or group by performing one or more of the following commands. Remove role from user by executing the following: oc adm policy remove-role-from-user <ROLE> <USER> -n openshift-logging Remove role from group by executing the following: oc adm policy remove-role-from-group <ROLE> <GROUP> -n openshift-logging Remove cluster role from user by executing the following: oc adm policy remove-cluster-role-from-user <CLUSTER_ROLE> <USER> -n openshift-logging Remove cluster role from group by executing the following: oc adm policy remove-cluster-role-from-group <CLUSTER_ROLE> <GROUP> -n openshift-logging Note: ROLE/CLUSTER_ROLE is the role granting user view permission to resources in openshift-logging namespace.
Verify the Cluster Log Forwarder is using an encrypted transport by executing the following: oc get clusterlogforwarder -n openshift-logging For each Cluster Log Forwarder, run the following command to display the configuration. oc describe clusterlogforwarder <name> -n openshift-logging Review the configuration and determine if the transport is secure, such as tls:// or https://. If there are any transports configured that are not secured by TLS, this is a finding.
Edit the Cluster Log Forwarder configuration to configure TLS on the transport by executing the following: oc edit clusterlogforwarder <name> -n openshift-logging For any output->url value that is not using a secure transport, edit the url to use a secure (https:// or tls://) transport. For detailed information regarding configuration of the Cluster Log Forwarder, refer to https://docs.openshift.com/container-platform/4.8/logging/cluster-logging-external.html.
Determine if a policy has been put in place by running the following command: for node in $(oc get node -oname); do oc debug $node -- chroot /host /bin/bash -c 'echo -n "$HOSTNAME "; cat /etc/containers/policy.json' 2>/dev/null; done If the policy is not set to "reject" by default, or the signature keys are not configure appropriately on the registries, this is a finding. The following is an example of how this will look on a system using Red Hat's public registries: <pre> { "default": [{"type": "reject"}], "transports": { "docker": { "registry.access.redhat.com": [ { "type": "signedBy", "keyType": "GPGKeys", "keyPath": "/etc/pki/rpm-gpg/RPM-GPG-KEY-redhat-release" } ], "registry.redhat.io": [ { "type": "signedBy", "keyType": "GPGKeys", "keyPath": "/etc/pki/rpm-gpg/RPM-GPG-KEY-redhat-release" } ], ... }
Configure the OpenShift Container policy to validate that image signatures are verified and enforced by executing the following: Note: This can be configured manually or through the use of the MachineConfig Operator published by Red Hat. for mcpool in $(oc get mcp -oname | sed "s:.*/::" ); do echo "apiVersion: machineconfiguration.openshift.io/v1 kind: MachineConfig metadata: labels: machineconfiguration.openshift.io/role: $mcpool name: 51-rh-registry-trust-$mcpool spec: config: ignition: version: 3.2.0 storage: files: - contents: source: data:text/plain;charset=utf-8;base64,LS0tCmRvY2tlcjoKICByZWdpc3RyeS5hY2Nlc3MucmVkaGF0LmNvbToKICAgIHNpZ3N0b3JlOiBodHRwczovL2FjY2Vzcy5yZWRoYXQuY29tL3dlYmFzc2V0cy9kb2NrZXIvY29udGVudC9zaWdzdG9yZQo= verification: {} filesystem: root mode: 420 path: /etc/containers/registries.d/registry.access.redhat.com.yaml - contents: source: data:text/plain;charset=utf-8;base64,LS0tCmRvY2tlcjoKICByZWdpc3RyeS5yZWRoYXQuaW86CiAgICBzaWdzdG9yZTogaHR0cHM6Ly9yZWdpc3RyeS5yZWRoYXQuaW8vY29udGFpbmVycy9zaWdzdG9yZQo= verification: {} filesystem: root mode: 420 path: /etc/containers/registries.d/registry.redhat.io.yaml - contents: source: data:text/plain;charset=utf-8;base64,ewogICJkZWZhdWx0IjogW3sidHlwZSI6ICJyZWplY3QifV0sCiAgInRyYW5zcG9ydHMiOiB7CiAgICAiZG9ja2VyIjogewogICAgICAicmVnaXN0cnkuYWNjZXNzLnJlZGhhdC5jb20iOiBbCiAgICAgICAgewogICAgICAgICAgInR5cGUiOiAic2lnbmVkQnkiLAogICAgICAgICAgImtleVR5cGUiOiAiR1BHS2V5cyIsCiAgICAgICAgICAia2V5UGF0aCI6ICIvZXRjL3BraS9ycG0tZ3BnL1JQTS1HUEctS0VZLXJlZGhhdC1yZWxlYXNlIgogICAgICAgIH0KICAgICAgXSwKICAgICAgInJlZ2lzdHJ5LnJlZGhhdC5pbyI6IFsKICAgICAgICB7CiAgICAgICAgICAidHlwZSI6ICJzaWduZWRCeSIsCiAgICAgICAgICAia2V5VHlwZSI6ICJHUEdLZXlzIiwKICAgICAgICAgICJrZXlQYXRoIjogIi9ldGMvcGtpL3JwbS1ncGcvUlBNLUdQRy1LRVktcmVkaGF0LXJlbGVhc2UiCiAgICAgICAgfQogICAgICBdLAogICAgICAiaW1hZ2UtcmVnaXN0cnkub3BlbnNoaWZ0LWltYWdlLXJlZ2lzdHJ5LnN2Yzo1MDAwIjogW3sidHlwZSI6ICJpbnNlY3VyZUFjY2VwdEFueXRoaW5nIn1dLAogICAgICAicXVheS5pby9jb21wbGlhbmNlYXNjb2RlIjogW3sidHlwZSI6ICJpbnNlY3VyZUFjY2VwdEFueXRoaW5nIn1dLAogICAgICAicXVheS5pby9jb21wbGlhbmNlLW9wZXJhdG9yIjogW3sidHlwZSI6ICJpbnNlY3VyZUFjY2VwdEFueXRoaW5nIn1dLAogICAgICAicXVheS5pby9rZXljbG9hayI6IFt7InR5cGUiOiAiaW5zZWN1cmVBY2NlcHRBbnl0aGluZyJ9XSwKICAgICAgInF1YXkuaW8vb3BlbnNoaWZ0LXJlbGVhc2UtZGV2IjogW3sidHlwZSI6ICJpbnNlY3VyZUFjY2VwdEFueXRoaW5nIn1dLAogICAgICAicmVnaXN0cnkuYnVpbGQwMi5jaS5vcGVuc2hpZnQub3JnIjogW3sidHlwZSI6ICJpbnNlY3VyZUFjY2VwdEFueXRoaW5nIn1dLAogICAgICAicmVnaXN0cnkuYnVpbGQwMS5jaS5vcGVuc2hpZnQub3JnIjogW3sidHlwZSI6ICJpbnNlY3VyZUFjY2VwdEFueXRoaW5nIn1dCiAgICB9CiAgfQp9Cg== verification: {} filesystem: root mode: 420 path: /etc/containers/policy.json " | oc apply -f - done
To review the container images within the container platform registry, execute the following: oc get images Review the container platform container images to validate that only container images necessary for the functionality of the information system are present. If unnecessary container images exist, this is a finding.
Remove any images from the container registry that are not required for the functionality of the system by executing the following: oc delete image <IMAGE_NAME> -n <IMAGE_NAMESPACE>
Review the OpenShift documentation and configuration. For additional information, refer to https://docs.openshift.com/container-platform/4.12/installing/installing_platform_agnostic/installing-platform-agnostic.html. 1. Interview the application administrator. 2. Identify the TCP/IP port numbers OpenShift is configured to use and is utilizing by using a combination of relevant OS commands and application configuration utilities. 3. Identify the network ports and protocols that are used by kube-apiserver by executing the following: oc get configmap kube-apiserver-pod -n openshift-kube-apiserver -o "jsonpath={ .data['pod\.yaml'] }" | jq '..|.containerPort?' | grep -v "null" oc get configmap kube-apiserver-pod -n openshift-kube-apiserver -o "jsonpath={ .data['pod\.yaml'] }" | jq '..|.hostPort?' | grep -v "null" oc get services -A --show-labels | grep apiserver | awk '{print $6,$8}' | grep apiserver 4. Identify the network ports and protocols used by kube-scheduler by executing the following: oc get configmap kube-scheduler-pod -n openshift-kube-scheduler -o "jsonpath={ .data['pod\.yaml'] }" | jq '..|.containerPort?' | grep -v "null" oc get services -A --show-labels | grep scheduler | awk '{print $6,$8}' | grep scheduler 5. Identify the network ports and protocols used by kube-controller-manager by executing the following: oc get configmap kube-controller-manager-pod -n openshift-kube-controller-manager -o "jsonpath={ .data['pod\.yaml'] }" | jq '..|.containerPort?' | grep -v "null" oc get services -A --show-labels | grep kube-controller 6. Identify the network ports and protocols used by etcd by executing the following: oc get configmap etcd-pod -n openshift-etcd -o "jsonpath={ .data['pod\.yaml'] }" | grep -Po '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}:[0-9]+' | sort -u Review the PPSM web page at: http://www.disa.mil/Network-Services/Enterprise-Connections/PPSM. Review the PPSM Category Assurance List (CAL) directly at the following link: https://disa.deps.mil/ext/cop/iase/ppsm/Pages/cal.aspx. Verify the ports used by the OpenShift are approved by the PPSM CAL. If the ports, protocols, and services have not been registered locally, this is a finding.
Verify the accreditation documentation lists all interfaces and the ports, protocols, and services used. Register OpenShift's ports, protocols, and services with PPSM.
Verify SSH is restricted from logging on as root and network connections are terminated. Prevent logging on directly as "root" using SSH by executing the following command: for node in $(oc get node -oname); do oc debug $node -- chroot /host /bin/bash -c 'echo -n "$HOSTNAME "; grep -i PermitRootLogin /etc/ssh/sshd_config' 2>/dev/null; done If the "PermitRootLogin" keyword is set to "yes", is missing, or is commented out, this is a finding. Verify all network connections associated with SSH traffic are automatically terminated at the end of the session or after 10 minutes of inactivity. Check the "ClientAliveCountMax" and ClientAliveInterval by executing the following command: for node in $(oc get node -oname); do oc debug $node -- chroot /host /bin/bash -c 'echo -n "$HOSTNAME "; grep -i clientalive /etc/ssh/sshd_config ' 2>/dev/null; done If "ClientAliveCountMax" do not exist, is not set to a value of "0" in "/etc/ssh/sshd_config", or is commented out, this is a finding. If "ClientAliveInterval" does not exist, or has a value of > 600 in "/etc/ssh/sshd_config", or is commented out, this is a finding.
Apply the machine config that disables root and terminates network connections by executing the following: for mcpool in $(oc get mcp -oname | sed "s:.*/::" ); do echo "apiVersion: machineconfiguration.openshift.io/v1 kind: MachineConfig metadata: name: 50-sshd-config-$mcpool labels: machineconfiguration.openshift.io/role: $mcpool spec: config: ignition: version: 3.1.0 storage: files: - contents: source: data:,%0A%23%09$OpenBSD:%20sshd_config%2Cv%201.103%202018%2F04%2F09%2020:41:22%20tj%20Exp%20$%0A%0A%23%20This%20is%20the%20sshd%20server%20system-wide%20configuration%20file.%20%20See%0A%23%20sshd_config%285%29%20for%20more%20information.%0A%0A%23%20This%20sshd%20was%20compiled%20with%20PATH=%2Fusr%2Flocal%2Fbin:%2Fusr%2Fbin:%2Fusr%2Flocal%2Fsbin:%2Fusr%2Fsbin%0A%0A%23%20The%20strategy%20used%20for%20options%20in%20the%20default%20sshd_config%20shipped%20with%0A%23%20OpenSSH%20is%20to%20specify%20options%20with%20their%20default%20value%20where%0A%23%20possible%2C%20but%20leave%20them%20commented.%20%20Uncommented%20options%20override%20the%0A%23%20default%20value.%0A%0A%23%20If%20you%20want%20to%20change%20the%20port%20on%20a%20SELinux%20system%2C%20you%20have%20to%20tell%0A%23%20SELinux%20about%20this%20change.%0A%23%20semanage%20port%20-a%20-t%20ssh_port_t%20-p%20tcp%20%23PORTNUMBER%0A%23%0A%23Port%2022%0A%23AddressFamily%20any%0A%23ListenAddress%200.0.0.0%0A%23ListenAddress%20::%0A%0AHostKey%20%2Fetc%2Fssh%2Fssh_host_rsa_key%0AHostKey%20%2Fetc%2Fssh%2Fssh_host_ecdsa_key%0AHostKey%20%2Fetc%2Fssh%2Fssh_host_ed25519_key%0A%0A%23%20Ciphers%20and%20keying%0ARekeyLimit%20512M%201h%0A%0A%23%20System-wide%20Crypto%20policy:%0A%23%20This%20system%20is%20following%20system-wide%20crypto%20policy.%20The%20changes%20to%0A%23%20Ciphers%2C%20MACs%2C%20KexAlgoritms%20and%20GSSAPIKexAlgorithsm%20will%20not%20have%20any%0A%23%20effect%20here.%20They%20will%20be%20overridden%20by%20command-line%20options%20passed%20on%0A%23%20the%20server%20start%20up.%0A%23%20To%20opt%20out%2C%20uncomment%20a%20line%20with%20redefinition%20of%20%20CRYPTO_POLICY=%0A%23%20variable%20in%20%20%2Fetc%2Fsysconfig%2Fsshd%20%20to%20overwrite%20the%20policy.%0A%23%20For%20more%20information%2C%20see%20manual%20page%20for%20update-crypto-policies%288%29.%0A%0A%23%20Logging%0A%23SyslogFacility%20AUTH%0ASyslogFacility%20AUTHPRIV%0A%23LogLevel%20INFO%0A%0A%23%20Authentication:%0A%0A%23LoginGraceTime%202m%0APermitRootLogin%20no%0AStrictModes%20yes%0A%23MaxAuthTries%206%0A%23MaxSessions%2010%0A%0APubkeyAuthentication%20yes%0A%0A%23%20The%20default%20is%20to%20check%20both%20.ssh%2Fauthorized_keys%20and%20.ssh%2Fauthorized_keys2%0A%23%20but%20this%20is%20overridden%20so%20installations%20will%20only%20check%20.ssh%2Fauthorized_keys%0AAuthorizedKeysFile%09.ssh%2Fauthorized_keys%0A%0A%23AuthorizedPrincipalsFile%20none%0A%0A%23AuthorizedKeysCommand%20none%0A%23AuthorizedKeysCommandUser%20nobody%0A%0A%23%20For%20this%20to%20work%20you%20will%20also%20need%20host%20keys%20in%20%2Fetc%2Fssh%2Fssh_known_hosts%0AHostbasedAuthentication%20no%0A%23%20Change%20to%20yes%20if%20you%20don%27t%20trust%20~%2F.ssh%2Fknown_hosts%20for%0A%23%20HostbasedAuthentication%0AIgnoreUserKnownHosts%20yes%0A%23%20Don%27t%20read%20the%20user%27s%20~%2F.rhosts%20and%20~%2F.shosts%20files%0AIgnoreRhosts%20yes%0A%0A%23%20To%20disable%20tunneled%20clear%20text%20passwords%2C%20change%20to%20no%20here%21%0A%23PasswordAuthentication%20yes%0APermitEmptyPasswords%20no%0APasswordAuthentication%20no%0A%0A%23%20Change%20to%20no%20to%20disable%20s%2Fkey%20passwords%0A%23ChallengeResponseAuthentication%20yes%0AChallengeResponseAuthentication%20no%0A%0A%23%20Kerberos%20options%0AKerberosAuthentication%20no%0A%23KerberosOrLocalPasswd%20yes%0A%23KerberosTicketCleanup%20yes%0A%23KerberosGetAFSToken%20no%0A%23KerberosUseKuserok%20yes%0A%0A%23%20GSSAPI%20options%0AGSSAPIAuthentication%20no%0AGSSAPICleanupCredentials%20no%0A%23GSSAPIStrictAcceptorCheck%20yes%0A%23GSSAPIKeyExchange%20no%0A%23GSSAPIEnablek5users%20no%0A%0A%23%20Set%20this%20to%20%27yes%27%20to%20enable%20PAM%20authentication%2C%20account%20processing%2C%0A%23%20and%20session%20processing.%20If%20this%20is%20enabled%2C%20PAM%20authentication%20will%0A%23%20be%20allowed%20through%20the%20ChallengeResponseAuthentication%20and%0A%23%20PasswordAuthentication.%20%20Depending%20on%20your%20PAM%20configuration%2C%0A%23%20PAM%20authentication%20via%20ChallengeResponseAuthentication%20may%20bypass%0A%23%20the%20setting%20of%20%22PermitRootLogin%20without-password%22.%0A%23%20If%20you%20just%20want%20the%20PAM%20account%20and%20session%20checks%20to%20run%20without%0A%23%20PAM%20authentication%2C%20then%20enable%20this%20but%20set%20PasswordAuthentication%0A%23%20and%20ChallengeResponseAuthentication%20to%20%27no%27.%0A%23%20WARNING:%20%27UsePAM%20no%27%20is%20not%20supported%20in%20Fedora%20and%20may%20cause%20several%0A%23%20problems.%0AUsePAM%20yes%0A%0A%23AllowAgentForwarding%20yes%0A%23AllowTcpForwarding%20yes%0A%23GatewayPorts%20no%0AX11Forwarding%20yes%0A%23X11DisplayOffset%2010%0A%23X11UseLocalhost%20yes%0A%23PermitTTY%20yes%0A%0A%23%20It%20is%20recommended%20to%20use%20pam_motd%20in%20%2Fetc%2Fpam.d%2Fsshd%20instead%20of%20PrintMotd%2C%0A%23%20as%20it%20is%20more%20configurable%20and%20versatile%20than%20the%20built-in%20version.%0APrintMotd%20no%0A%0APrintLastLog%20yes%0A%23TCPKeepAlive%20yes%0APermitUserEnvironment%20no%0ACompression%20no%0AClientAliveInterval%20600%0AClientAliveCountMax%200%0A%23UseDNS%20no%0A%23PidFile%20%2Fvar%2Frun%2Fsshd.pid%0A%23MaxStartups%2010:30:100%0A%23PermitTunnel%20no%0A%23ChrootDirectory%20none%0A%23V+G67ersionAddendum%20none%0A%0A%23%20no%20default%20banner%20path%0ABanner%20%2Fetc%2Fissue%0A%0A%23%20Accept%20locale-related%20environment%20variables%0AAcceptEnv%20LANG%20LC_CTYPE%20LC_NUMERIC%20LC_TIME%20LC_COLLATE%20LC_MONETARY%20LC_MESSAGES%0AAcceptEnv%20LC_PAPER%20LC_NAME%20LC_ADDRESS%20LC_TELEPHONE%20LC_MEASUREMENT%0AAcceptEnv%20LC_IDENTIFICATION%20LC_ALL%20LANGUAGE%0AAcceptEnv%20XMODIFIERS%0A%0A%23%20override%20default%20of%20no%20subsystems%0ASubsystem%09sftp%09%2Fusr%2Flibexec%2Fopenssh%2Fsftp-server%0A%0A%23%20Example%20of%20overriding%20settings%20on%20a%20per-user%20basis%0A%23Match%20User%20anoncvs%0A%23%09X11Forwarding%20no%0A%23%09AllowTcpForwarding%20no%0A%23%09PermitTTY%20no%0A%23%09ForceCommand%20cvs%20server%0A%0AUsePrivilegeSeparation%20sandbox mode: 0644 overwrite: true path: /etc/ssh/sshd_config " | oc apply -f - done
Verify the authentication operator is configured to use either an LDAP or a OpenIDConnect provider by executing the following: oc get oauth cluster -o jsonpath="{.spec.identityProviders[*].type}{'\n'}" If the output lists any other type besides LDAP or OpenID, this is a finding.
Configure OpenShift to use an appropriate Identity Provider. Do not use HTPasswd. Use either LDAP(AD), OpenIDConnect, or an approved identity provider. Steps to configure LDAP provider: 1. Create Secret for BIND DN password by executing the following: oc create secret generic ldap-secret --from-literal=bindPassword=<secret> -n openshift-config 2. Create config map for LDAP Trust CA by executing the following: oc create configmap ca-config-map --from-file=ca.crt=/path/to/ca -n openshift-config 3. Create LDAP Auth Config Resource YAML: Using the preferred text editor, create a file named ldapidp.yaml using the example content. (replacing config values as appropriate): apiVersion: config.openshift.io/v1 kind: OAuth metadata: name: cluster spec: identityProviders: - name: ldapidp mappingMethod: claim type: LDAP ldap: attributes: id: - dn email: - mail name: - cn preferredUsername: - uid bindDN: <"bindDN"> bindPassword: name: ldap-secret ca: name: ca-config-map insecure: false url: <URL> 4. Apply LDAP config to cluster by executing the following: oc apply -f ldapidp.yaml Note: For more information on configuring an LDAP provider, refer to https://docs.openshift.com/container-platform/4.8/authentication/identity_providers/configuring-ldap-identity-provider.html. Steps to configure OpenID provider: 1. Create Secret for Client Secret by executing the following: oc create secret generic idp-secret --from-literal=clientSecret=<secret> -n openshift-config 2. Create config map for OpenID Trust CA by executing the following: oc create configmap ca-config-map --from-file=ca.crt=/path/to/ca -n openshift-config 3. Create OpenID Auth Config Resource YAML. Using your preferred text editor, create a file named oidcidp.yaml using the example content (replacing config values as appropriate). apiVersion: config.openshift.io/v1 kind: OAuth metadata: name: cluster spec: identityProviders: - name: oidcidp mappingMethod: claim type: OpenID openID: clientID: <clientID> clientSecret: name: oidc-idp-secret claims: preferredUsername: - preferred_username name: - name email: - email ca: name: ca-config-map issuer: <URL> 4. Apply OpenID config to cluster by executing the following: oc apply -f ldapidp.yaml Note: For more information on configuring an OpenID provider, refer to https://docs.openshift.com/container-platform/4.8/authentication/identity_providers/configuring-oidc-identity-provider.html.
Verify the authentication operator is configured to use a secure transport to an OpenIDConnect provider: oc get oauth cluster -o jsonpath="{.spec.identityProviders[*]}{'\n'}" If the transport is not secure (ex. HTTPS), this is a finding.
Configure OpenShift to use an OpenIDConnect Identity Provider. Note: This STIG was written for OIC; do not use HTPasswd. Only use an approved identity provider. Steps to configure OpenID provider: 1. Create Secret for Client Secret by executing the following: oc create secret generic idp-secret --from-literal=clientSecret=<secret> -n openshift-config 2. Create config map for OpenID Trust CA by executing the following: oc create configmap ca-config-map --from-file=ca.crt=/path/to/ca -n openshift-config 3. Create OpenID Auth Config Resource YAML. Using the preferred text editor, create a file named oidcidp.yaml using the example content (replacing config values as appropriate). apiVersion: config.openshift.io/v1 kind: OAuth metadata: name: cluster spec: identityProviders: - name: oidcidp mappingMethod: claim type: OpenID openID: clientID: ... clientSecret: name: idp-secret claims: preferredUsername: - preferred_username name: - name email: - email issuer: https://www.idp-issuer.com 4. Apply OpenID config to cluster by executing the following: oc apply -f ldapidp.yaml Note: For more information on configuring an OpenID provider, refer to https://docs.openshift.com/container-platform/4.8/authentication/identity_providers/configuring-oidc-identity-provider.html.
Verify the authentication operator is configured to use either an LDAP or a OpenIDConnect provider by executing the following: oc get oauth cluster -o jsonpath="{.spec.identityProviders[*].type}{'\n'}" If the output lists any other type besides LDAP or OpenID, this is a finding.
Configure OpenShift to use an appropriate Identity Provider. Do not use HTPasswd. Use either LDAP(AD), OpenIDConnect or an approved identity provider. To configure LDAP provider: 1. Create Secret for BIND DN password by executing the following: oc create secret generic ldap-secret --from-literal=bindPassword=<secret> -n openshift-config 2. Create config map for LDAP Trust CA by executing the following: oc create configmap ca-config-map --from-file=ca.crt=/path/to/ca -n openshift-config 3. Create LDAP Auth Config Resource YAML: Using the preferred text editor, create a file named ldapidp.yaml using the example content (replacing config values as appropriate). apiVersion: config.openshift.io/v1 kind: OAuth metadata: name: cluster spec: identityProviders: - name: ldapidp mappingMethod: claim type: LDAP ldap: attributes: id: - dn email: - mail name: - cn preferredUsername: - uid bindDN: <"bindDN"> bindPassword: name: ldap-secret ca: name: ca-config-map insecure: false url: <URL> 4. Apply LDAP config to cluster by executing the following: oc apply -f ldapidp.yaml Note: For more information on configuring an LDAP provider, refer to https://docs.openshift.com/container-platform/4.8/authentication/identity_providers/configuring-ldap-identity-provider.html. To configure OpenID provider: 1. Create Secret for Client Secret by executing the following: oc create secret generic idp-secret --from-literal=clientSecret=<secret> -n openshift-config 2. Create config map for OpenID Trust CA by executing the following: oc create configmap ca-config-map --from-file=ca.crt=/path/to/ca -n openshift-config 3. Create OpenID Auth Config Resource YAML. Using your preferred text editor, create a file named oidcidp.yaml using the example content (replacing config values as appropriate). apiVersion: config.openshift.io/v1 kind: OAuth metadata: name: cluster spec: identityProviders: - name: oidcidp mappingMethod: claim type: OpenID openID: clientID: <clientID> clientSecret: name: oidc-idp-secret claims: preferredUsername: - preferred_username name: - name email: - email ca: name: ca-config-map issuer: <URL> 4. Apply OpenID config to cluster by executing the following: oc apply -f ldapidp.yaml Note: For more information on configuring an OpenID provider, refer to https://docs.openshift.com/container-platform/4.8/authentication/identity_providers/configuring-oidc-identity-provider.html.
On each administrators terminal, verify the OC client version includes the required idle timeout by executing the following. oc version If the client version < "4.8.36", this is a finding. Determine if the session token inactivity timeout is set on the oauthclients by executing the following: oc get oauthclients -ojsonpath='{range .items[*]}{.metadata.name}{"\t"}{.accessTokenInactivityTimeoutSeconds}{"\n"}' The output will list each oauth client name followed by a number. The number represents the timeout in seconds. If no number is displayed, or the timeout value is >600, this is a finding.
Download the latest version of the OC client, and remove/replace any older versions. For each oauth client that does not have the idle timeout set, or the timeout is set to the wrong duration, run the following command to set the idle timeout value to 10 minutes. oc patch oauthclient/<CLIENT_NAME> --type=merge -p '{"accessTokenInactivityTimeoutSeconds":600}' where CLIENT_NAME is the name of the oauthclient identified in the check.
Verify that root and core are the only user accounts on the nodes by executing the following: for node in $(oc get node -oname); do oc debug $node -- chroot /host /bin/bash -c 'echo -n "$HOSTNAME "; cat /etc/passwd' 2>/dev/null; done The output will look similar to: <node_name> root:x:0:0:root:/root:/bin/bash core:x:1000:1000:CoreOS Admin:/var/home/core:/bin/bash containers:x:993:995:User for housing the sub ID range for containers:/var/home/containers:/sbin/nologin If there are any user accounts in addition to root, containers, and core, this is a finding. Verify the root and core users are set to disable password logon by executing the following: for node in $(oc get node -oname); do oc debug $node -- chroot /host /bin/bash -c 'echo -n "$HOSTNAME "; grep -e "^root" -e "^core" /etc/shadow' 2>/dev/null; done The output will look similar to: <node_name> root:*:18367:0:99999:7::: core:*:18939:0:99999:7::: If the password entry has anything other than '*', this is a finding.
Disable and remove passwords from root and core accounts by executing the following: for node in $(oc get node -oname); do oc debug $node -- chroot /host /bin/bash -c 'usermod -p "*" root; usermod -p "*" core' 2>/dev/null; done Remove any additional user accounts from the nodes by executing the following: oc debug node/<node> -- chroot /host /bin/bash -c 'userdel <user>'
To validate the OpenShift cluster is running with FIPS enabled on each node by executing the following: for node in $(oc get node -oname); do oc debug $node -- chroot /host /bin/bash -c 'echo -n "$HOSTNAME "; sysctl crypto.fips_enabled' 2>/dev/null; done If any lines of output end in anything other than 1, this is a finding.
Reinstall the OpenShift cluster in FIPS mode. The file install-config.yaml has a top-level key that enables FIPS mode for all nodes and the cluster platform layer. If the install-config.yaml was not backed up prior to consumption as part of the installation, recreate it. An example install-config.yaml with some sections trimmed out for brevity, and the "fips: true" key applied at the top level is shown below: apiVersion: v1 baseDomain: example.com controlPlane: name: master platform: aws: [...] replicas: 3 compute: - name: worker platform: aws: replicas: 3 metadata: name: fips-cluster networking: [...] platform: aws: [...] sshKey: ssh-ed25519 AAAA... pullSecret: '{"auths": ...}' fips: true Once the install-config.yaml is saved with corresponding correct information for the installation infrastructure, run the installer to create a cluster that uses FIPS Validated/Modules in Process cryptographic libraries. The command to install a cluster and consume the install-config.yaml is: > ./openshift-install create cluster --dir=<installation_directory> --log-level=info Where <installation_directory> is the directory that contains install-config.yaml Additional details can be found here: https://docs.openshift.com/container-platform/4.8/installing/installing-fips.html
Verify the Red Hat Enterprise Linux CoreOS (RHCOS) verifies correct operation of all security functions by executing the following: for node in $(oc get node -oname); do oc debug $node -- chroot /host /bin/bash -c 'echo -n "$HOSTNAME "; getenforce' 2>/dev/null; done If "SELinux" is not active and not in "Enforcing" mode, this is a finding.
Apply the machine config by executing the following: for mcpool in $(oc get mcp -oname | sed "s:.*/::" ); do echo "apiVersion: machineconfiguration.openshift.io/v1 kind: MachineConfig metadata: name: 05-kernelarg-selinux-enforcing-$mcpool labels: machineconfiguration.openshift.io/role: $mcpool spec: config: ignition: version: 3.1.0 kernelArguments: - enforcing=1 " | oc apply -f - done
Check the current CoreOS boot loader configuration has page poisoning enabled by executing the following: for node in $(oc get node -oname); do oc debug $node -- chroot /host /bin/bash -c 'echo -n "$HOSTNAME "; grep page_poison /boot/loader/entries/*.conf|| echo "not found"' 2>/dev/null; done If "page_poison" is not set to "1" or returns "not found", this is a finding.
Apply the machine config to enable page poisoning by executing the following: for mcpool in $(oc get mcp -oname | sed "s:.*/::" ); do echo "apiVersion: machineconfiguration.openshift.io/v1 kind: MachineConfig metadata: name: 05-kernelarg-page-poison-$mcpool labels: machineconfiguration.openshift.io/role: $mcpool spec: config: ignition: version: 3.1.0 kernelArguments: - page_poison=1 " | oc apply -f - done
Check the current CoreOS boot loader configuration has virtual syscalls disabled by executing the following: for node in $(oc get node -oname); do oc debug $node -- chroot /host /bin/bash -c 'echo -n "$HOSTNAME "; grep vsyscall=none boot/loader/entries/*.conf || echo "not found"' 2>/dev/null; done If "vsyscall" is not set to "none" or returns "not found", this is a finding.
Apply the machine config to disable virtual syscalls by executing the following: for mcpool in $(oc get mcp -oname | sed "s:.*/::" ); do echo "apiVersion: machineconfiguration.openshift.io/v1 kind: MachineConfig metadata: name: 05-kernelarg-vsyscall-none-$mcpool labels: machineconfiguration.openshift.io/role: $mcpool spec: config: ignition: version: 3.1.0 kernelArguments: - vsyscall=none " | oc apply -f - done
Verify that Red Hat Enterprise Linux CoreOS (RHCOS) is configured to enable poisoning of SLUB/SLAB objects to mitigate use-after-free vulnerabilities by executing the following: for node in $(oc get node -oname); do oc debug $node -- chroot /host /bin/bash -c 'echo -n "$HOSTNAME "; grep slub_debug /boot/loader/entries/*.conf ' 2>/dev/null; done If "slub_debug" is not set to "P" or is missing, this is a finding.
Apply the machine config to enable poisoning of SLUB/SLAB objects by executing the following: for mcpool in $(oc get mcp -oname | sed "s:.*/::" ); do echo "apiVersion: machineconfiguration.openshift.io/v1 kind: MachineConfig metadata: name: 05-kernelarg-slub-debug-$mcpool labels: machineconfiguration.openshift.io/role: $mcpool spec: config: ignition: version: 3.1.0 kernelArguments: - slub_debug=P " | oc apply -f - done
Verify that all world-writable directories have the sticky bit set. List any world-writeable directories that do not have the sticky bit set by executing the following: for node in $(oc get node -oname); do oc debug $node -- chroot /host /bin/bash -c 'echo -n "$HOSTNAME "; find / -type d \( -perm -0002 -a ! -perm -1000 ! -path "/var/lib/containers/*" ! -path "/var/lib/kubelet/pods/*" ! -path "/sysroot/ostree/deploy/*" \) -print 2>/dev/null' 2>/dev/null; done If there are any directories listed in the results, this is a finding.
Fix the directory permissions, by either removing world-writeable permission, or setting the sticky bit by executing the following: oc debug node/<node_name> -- chroot /host /bin/bash -c 'chmod XXXX <directory>' where node_name: The name of the node to connect to (oc get node) XXXX: Either 1777 (sticky bit) or 0755 (remove group and world write permission) <directory>: The directory on which to correct the permissions
Verify the Red Hat Enterprise Linux CoreOS (RHCOS) is configured to restrict access to the kernel message buffer. Check the status of the kernel.dmesg_restrict kernel parameter by executing the following: for node in $(oc get node -oname); do oc debug $node -- chroot /host /bin/bash -c 'echo -n "$HOSTNAME "; sysctl kernel.dmesg_restrict' 2>/dev/null; done If "kernel.dmesg_restrict" is not set to "1" or is missing, this is a finding.
Apply the machine config to restrict access to the kernel message buffer by executing the following: for mcpool in $(oc get mcp -oname | sed "s:.*/::" ); do echo "apiVersion: machineconfiguration.openshift.io/v1 kind: MachineConfig metadata: name: 75-sysctl-kernel-dmesg-restrict-$mcpool labels: machineconfiguration.openshift.io/role: $mcpool spec: config: ignition: version: 3.1.0 storage: files: - contents: source: data:,kernel.dmesg_restrict%3D1%0A mode: 0644 path: /etc/sysctl.d/75-sysctl_kernel_dmesg_restrict.conf overwrite: true " | oc apply -f - done
Verify the Red Hat Enterprise Linux CoreOS (RHCOS) is configured to prevent kernel profiling by unprivileged users. Check the status of the kernel.perf_event_paranoid kernel parameter by executing the following: for node in $(oc get node -oname); do oc debug $node -- chroot /host /bin/bash -c 'echo -n "$HOSTNAME "; sysctl kernel.perf_event_paranoid ' 2>/dev/null; done If "kernel.perf_event_paranoid" is not set to "2" or is missing, this is a finding.
Apply the machine config to prevent kernel profiling by executing the following: for mcpool in $(oc get mcp -oname | sed "s:.*/::" ); do echo "apiVersion: machineconfiguration.openshift.io/v1 kind: MachineConfig metadata: name: 75-sysctl-kernel-perf-event-paranoid-$mcpool labels: machineconfiguration.openshift.io/role: $mcpool spec: config: ignition: version: 3.1.0 storage: files: - contents: source: data:,kernel.perf_event_paranoid%3D2%0A mode: 0644 path: /etc/sysctl.d/75-sysctl_kernel_perf_event_paranoid.conf overwrite: true " | oc apply -f - done
Check for Resource Quota. Verify a default project template is defined by executing the following: oc get project.config.openshift.io/cluster -o jsonpath="{.spec.projectRequestTemplate.name}" If no project request template is in use by the project config, this is a finding. Verify the project template includes a default resource quota. oc get templates/<PROJECT-REQUEST-TEMPLATE> -n openshift-config -o jsonpath="{.objects[?(.kind=='ResourceQuota')]}{'\n'}" Replace <PROJECT-REQUEST-TEMPLATE> with the name of the project request template returned from the earlier query. If the project template is not defined, or there are no ResourceQuota definitions in it, this is a finding.
Configure a default resource quota to protect resource over utilization by performing the following steps: 1. Create a bootstrap project template (if not already created) by executing the following: oc adm create-bootstrap-project-template -o yaml > template.yaml 2. Edit the template and add a ResourceQuota object definition before the parameters section. - apiVersion: v1 kind: ResourceQuota metadata: name: example spec: hard: persistentvolumeclaims: "10" requests.storage: "50Gi" ... parameters: 3. Apply the project template to the cluster by executing the following: oc create -f template.yaml -n openshift-config 4. Set the default cluster project request template by executing the following: oc patch project.config.openshift.io/cluster --type=merge -p '{"spec":{"projectRequestTemplate":{"name": "<PROJECT_REQUEST_TEMPLATE>"}}}' Details regarding the configuration of resource quotas can be reviewed at https://docs.openshift.com/container-platform/4.8/applications/quotas/quotas-setting-per-project.html.
Verify that all namespaces except those that start with kube-* or openshift-* use the rate-limiting annotation by executing the following: oc get routes --all-namespaces -o json | jq '[.items[] | select(.metadata.namespace | startswith("kube-") or startswith("openshift-") | not) | select(.metadata.annotations["haproxy.router.openshift.io/rate-limit-connections"] == "true" | not) | .metadata.name]' If the above command returns any namespaces, this is a finding.
Add the haproxy.router.openshift.io/rate-limit-connections annotation to any routes outside the kube-* or openshift-* namespaces oc annotate route <route_name> -n <namespace> --overwrite=true "haproxy.router.openshift.io/timeout=2s" https://docs.openshift.com/container-platform/4.9/networking/routes/route-configuration.html
Verify the logout redirect setting in web console configuration is set by executing the following: oc get console.config.openshift.io cluster -o jsonpath='{.spec.authentication.logoutRedirect}{"\n"}' If nothing is returned, this is a finding.
Configure the web console's logout redirect to direct to an appropriate logout page. If OpenShift is configured to use an OIDC provider, then the redirect needs to first go to the OIDC provider's logout page, and then it can be redirected to another logout page as needed. Run the following command to update the console: oc patch console.config.openshift.io cluster --type merge -p '{"spec":{"authentication":{"logoutRedirect":"<LOGOUT_URL>"}}}' where LOGOUT_URL is set to the logout page.
Check SCC: 1. Identify any SCC policy that allows containers to access the host network or filesystem resources, or allows privileged containers or where runAsUser is not MustRunAsRange by executing the following: oc get scc -ojson | jq '.items[]|select(.allowHostIPC or .allowHostPID or .allowHostPorts or .allowHostNetwork or .allowHostDirVolumePlugin or .allowPrivilegedContainer or .runAsUser.type != "MustRunAsRange" )|.metadata.name,{"Group:":.groups},{"User":.users}' For each SCC listed, if any of those users or groups are anything other than the following, this is a finding: * system:cluster-admins * system:nodes * system:masters * system:admin * system:serviceaccount:openshift-infra:build-controller * system:serviceaccount:openshift-infra:pv-recycler-controller * system:serviceaccount:openshift-machine-api:machine-api-termination-handler The group "system:authenticated" is the default group for any authenticated user, this group should only be associated with the restricted profile. If this group is listed under any other SCC Policy, or the restricted SCC policy has been altered to allow any of the nonpermitted actions, this is a finding. 2. Determine if there are any cluster roles or local roles that allow the use of use of nonpermitted SCC policies. The following commands will print the role's name and namespace, followed by a list of resource names and if that resource is an SCC. oc get clusterrole.rbac -ojson | jq -r '.items[]|select(.rules[]?|select( (.apiGroups[]? == ("security.openshift.io")) and (.resources[]? == ("securitycontextconstraints")) and (.verbs[]? == ("use"))))|.metadata.name,{"scc":(.rules[]?|select((.resources[]? == ("securitycontextconstraints"))).resourceNames[]?)}' oc get role.rbac --all-namespaces -ojson | jq -r '.items[]|select(.rules[]?|select( (.apiGroups[]? == ("security.openshift.io")) and (.resources[]? == ("securitycontextconstraints")) and (.verbs[]? == ("use"))))|.metadata.name,{"scc":(.rules[]?|select((.resources[]? == ("securitycontextconstraints"))).resourceNames[]?)}' Excluding platform specific roles, identify any roles that allow use of nonpermitted SCC policies. For example, the follow output shows that the role 'examplePrivilegedRole' allows use of the 'privileged' SCC. examplePrivilegedRole { "scc": "privileged" } 3. Determine if there are any role bindings to cluster or local roles that allow use of nonpermitted SCCs by executing the following: oc get clusterrolebinding.rbac -ojson | jq -r '.items[]|select(.roleRef.kind == ("ClusterRole","Role") and .roleRef.name == (<CLUSTER_ROLE_LIST>))|{ "crb": .metadata.name, "roleRef": .roleRef, "subjects": .subjects}' oc get rolebinding.rbac --all-namespaces -ojson | jq -r '.items[]|select(.roleRef.kind == ("ClusterRole","Role") and .roleRef.name == (<LOCAL_ROLE_LIST>))|{ "crb": .metadata.name, "roleRef": .roleRef, "subjects": .subjects}' Where <CLUSTER_ROLE_LIST> and <LOCAL_ROLE_LIST> are comma-separated lists of the roles allowing use of nonpermitted SCC policies as identified above. For example: ... .roleRef.name == ("system:openshift:scc:privileged","system:openshift:scc:hostnetwork","system:openshift:scc:hostaccess") ... Excluding any platform namespaces (kube-*,openshift-*), if there are any rolebindings to roles that are not permitted, this is a finding.
For users and groups that are defined in the SCC policy, execute the following to remove the users or groups by editing the corresponding SCC policy. oc edit scc <SCC> The following instructions will remove the user or group from the cluster role binding for the SCC policy. Remove user from the SCC policy binding by executing the following: oc adm policy remove-scc-from-user <SCC> <USER> Remove a group from the SCC policy binding by executing the following: oc adm policy remove-scc-from-group <SCC> <GROUP> Remove service account from the SCC policy binding by executing the following: oc project <SERVICE_ACC_PROJECT> oc adm policy remove-scc-from-user <SCC> -z <SERVICE_ACC> Remove any roles that allows use of nonpermitted SCC policies (excluding platform-defined roles) by executing the following: oc delete clusterrole.rbac <ROLE> or oc delete role.rbac <ROLE> -n <NAMESPACE>
Verify RHCOS allocates audit record storage capacity to store at least one week of audit records when audit records are not immediately sent to a central audit record storage facility. Check the size of the partition to which audit records are written (with the example being /var/log/audit/) by executing the following: for node in $(oc get node -oname); do oc debug $node -- chroot /host /bin/bash -c 'echo -n "$HOSTNAME "; df -h /var/log/audit/' 2>/dev/null; done <node> Filesystem Size Used Avail Use% Mounted on /dev/sdb4 1.0T 27G 998G 3% /var If the audit record partition is not allocated for sufficient storage capacity, this is a finding. Note: The partition size needed to capture a week of audit records is based on the activity level of the system and the total storage capacity available. Typically, 10.0 GB of storage space for audit records should be sufficient. If the partition used is not exclusively for audit logs, then determine the amount of additional space needed to support the partition reserving enough space for audit logs.
Reinstall the cluster, generating custom ignition configs to allocate audit record storage capacity. 1. Generate manifest files for the cluster by executing the following: openshift-install create manifests --dir <install_dir> 2. Create a Butane config that configures additional partition by executing the following: variant: openshift version: 4.9.0 metadata: labels: machineconfiguration.openshift.io/role: worker name: 98-var-partition storage: disks: - device: /dev/<device_name> partitions: - label: var start_mib: <partition_start_offset> size_mib: <partition_size> filesystems: - device: /dev/disk/by-partlabel/var path: /var format: xfs mount_options: [rw, nodev, nosuid, noexec,...] with_mount_unit: true 3. Create a manifest from the Butane config by executing the following: butane <install_dir>/98-var-partition.bu -o <install_dir>/openshift/98-var-partition.yaml 4. Create the ignition config files by executing the following: openshift-install create ignition-configs --dir <install_dir>
Verify the AlertManager config includes a configured receiver. 1. From the Administrator perspective on the OpenShift web console, navigate to Administration >> Cluster Settings >> Configuration >> Alertmanager. 2. View the list of receivers and inspect the configuration. 3. Verify that at least one receiver is configured as either PagerDuty, Webhook, Email, or Slack according to the organizations policy. If an alert receiver is not configured according to the organizational policy, this is a finding.
Create an alert notification receiver. 1. From the Administrator perspective on the OpenShift web console, navigate to Administration >> Cluster Settings >> Configuration >> Alertmanager. 2. Select "Create Receiver". 3. Set the name and choose a Receiver Type. 4. Complete the form as per the organizations policy. 5. Click "Create". Refer to the following documentation for more information: https://docs.openshift.com/container-platform/4.8/monitoring/managing-alerts.html#sending-notifications-to-external-systems_managing-alerts
Verify OpenShift is configured to audit the execution of the "execve" system call by executing the following: for node in $(oc get node -oname); do oc debug $node -- chroot /host /bin/bash -c 'echo -n "$HOSTNAME "; grep -e "execpriv" /etc/audit/audit.rules' 2>/dev/null; done Confirm the following rules exist on each node: -a always,exit -F arch=b32 -S execve -C uid!=euid -F euid=0 -k execpriv -a always,exit -F arch=b64 -S execve -C uid!=euid -F euid=0 -k execpriv -a always,exit -F arch=b32 -S execve -C gid!=egid -F egid=0 -k execpriv -a always,exit -F arch=b64 -S execve -C gid!=egid -F egid=0 -k execpriv If the above rules are not listed on each node, this is a finding.
Apply the machine config to audit the execution of "execve" by executing the following: for mcpool in $(oc get mcp -oname | sed "s:.*/::" ); do echo "apiVersion: machineconfiguration.openshift.io/v1 kind: MachineConfig metadata: name: 75-audit-rules-suid-privilege-$mcpool labels: machineconfiguration.openshift.io/role: $mcpool spec: config: ignition: version: 3.1.0 storage: files: - contents: source: data:,-a%20always%2Cexit%20-F%20arch=b32%20-S%20execve%20-C%20uid%21=euid%20-F%20euid=0%20-k%20execpriv%0A-a%20always%2Cexit%20-F%20arch=b64%20-S%20execve%20-C%20uid%21=euid%20-F%20euid=0%20-k%20execpriv%0A-a%20always%2Cexit%20-F%20arch=b32%20-S%20execve%20-C%20gid%21=egid%20-F%20egid=0%20-k%20execpriv%0A-a%20always%2Cexit%20-F%20arch=b64%20-S%20execve%20-C%20gid%21=egid%20-F%20egid=0%20-k%20execpriv%0A mode: 0644 path: /etc/audit/rules.d/75-audit-suid-privilege-function.rules overwrite: true " | oc apply -f - done
To verify integrity of the cluster version, execute the following: oc get clusterversion version If the Cluster Version Operator is not installed or the AVAILABLE is not set to True, this is a finding. Run the following command to retrieve the Cluster Version objects in the system: oc get clusterversion version -o yaml If "verified: true", under status history for each item is not present, this is a finding.
By default, the integrity of RH CoreOS is checked by cluster version operator on OpenShift platform. If the integrity is not verified, reinstall of the cluster is necessary. Refer to instructions: https://docs.openshift.com/container-platform/4.10/installing/index.html
To check if the OAuth server token max age is configured, execute the following: oc get oauth cluster -ojsonpath='{.spec.tokenConfig.accessTokenMaxAgeSeconds}' If the output timeout value on the OAuth server is >"28800" or missing, this is a finding. Check the OAuth client token value (this can be set on each client also). Check all clients OAuth client token max age configuration by execute the following: oc get oauthclients -ojson | jq -r '.items[] | { accessTokenMaxAgeSeconds: .accessTokenMaxAgeSeconds}' If the output returns a timeout value of >"28800" for any client, this is a finding.
To set the OAuth server token max age, edit the OAuth server object by executing the following: oc patch oauth cluster --type merge -p '{"spec":{"tokenConfig":{"accessTokenMaxAgeSeconds": 28800}}}' To set the OAuth client token max age, edit the OAuth client object by executing the following: cli in $(oc get oauthclient -oname); do oc patch oauthclient $cli --type=merge -p '{"accessTokenMaxAgeSeconds": 28800}'; done
If no vulnerability scanning tool is used, this requirement is Not Applicable. Identify the service accounts used by the vulnerability scanning tools. If the tool runs as a container on the platform, then service account information can be found in the pod details by executing the following: (oc get pods to list pods) oc get pod <POD_ID> -o jsonpath='{.spec.serviceAccount}{"\n"}' If no service account exists for the vulnerability scanning tool, this is a finding. View cluster role bindings to determine which role the service account is bound to by executing the following: oc get clusterrolebinding -ojson | jq '.items[]|select(.subjects[]?|select(.kind == "ServiceAccount" and .name == "ingress-to-route-controller"))|{ "crb": .metadata.name, "roleRef": .roleRef, "subjects": .subjects}' Find the role to which the service account is bound, if the service account is not bound to a cluster role, or the role does not provide sufficient access, this is a finding.
If no vulnerability scanning tool is used, this requirement is Not Applicable. Create a service if one does not already exist. Change to the appropriate namespace by executing the following: oc project <namespace> Create Service Account in the Project by executing the following: oc create sa <service_account_name> Verify creation of the Service Account by executing the following: oc get sa | grep <service_account_name> Bind to the appropriate cluster RBAC role by executing the following: oc adm policy add-cluster-role-to-user <role_name> -z <service_account_name> For more information, refer to the following guides: https://docs.openshift.com/container-platform/4.8/authentication/using-rbac.html https://docs.openshift.com/container-platform/4.8/authentication/understanding-and-creating-service-accounts.html https://docs.openshift.com/container-platform/4.8/authentication/using-service-accounts-in-applications.html
Review the API server encryption by running by executing the following: oc edit apiserver EXAMPLE OUTPUT spec: encryption: type: aescbc If the encryption type is not "aescbc", this is a finding.
Set API encryption type by executing the following: oc edit apiserver Set the encryption field type to aescbc: spec: encryption: type: aescbc Additional details about the configuration can be found in the documentation: https://docs.openshift.com/container-platform/4.8/security/encrypting-etcd.html
Verify the new project template includes a default resource quota by executing the following: oc get templates/project-request -n openshift-config -o jsonpath="{.objects[?(.kind=='ResourceQuota')]}{'\n'}" Review the ResourceQuota definition. If nothing is return, this is a finding.
Configure a default resource quota as necessary to protect resource over utilization. 1. Create a bootstrap project template by executing the following: oc adm create-bootstrap-project-template -o yaml > template.yaml 2. Edit the template and add a ResourceQuota object definition before the parameters section. - apiVersion: v1 kind: ResourceQuota metadata: name: example spec: hard: persistentvolumeclaims: "10" requests.storage: "50Gi" ... parameters: 3. Apply the project template to the cluster by executing the following: oc create -f template.yaml -n openshift-config Details regarding the configuration of resource quotas can be reviewed at https://docs.openshift.com/container-platform/4.8/applications/quotas/quotas-setting-per-project.html.
Note: CNTR-OS-000140 is a prerequisite to this control. A Network Policy must exist to run this check. Verify that each user namespace has a ResourceQuota defined by executing the following: for ns in $(oc get namespaces -ojson | jq -r '.items[] | select((.metadata.name | startswith("openshift") | not) and (.metadata.name | startswith("kube-") | not) and .metadata.name != "default") | .metadata.name '); do oc get resourcequota -n$ns; done If the above returns any lines saying "No resources found in <PROJECT> namespace.", this is a finding. Empty output is not a finding.
Add a resource quota to an existing project namespace by performing the following steps: 1. Create <YOURFILE>.yaml and insert the desired resource quota content. The following is an example resource quota definition. apiVersion: v1 kind: ResourceQuota metadata: name: compute-resources namespace: <NAMESPACE> spec: hard: pods: "4" requests.cpu: "1" requests.memory: 1Gi requests.ephemeral-storage: 2Gi limits.cpu: "2" limits.memory: 2Gi limits.ephemeral-storage: 4Gi 2. Apply the ResourceQuota definition to the project namespace by executing the following: oc apply -f <YOURFILE>.yaml -n <NAMESPACE> Details regarding the configuration of resource quotas can be reviewed at https://docs.openshift.com/container-platform/4.8/applications/quotas/quotas-setting-per-project.html.
Verify that routes and ingress are using secured transmission ports and protocols by executing the following: oc get routes --all-namespaces Review the ingress ports, if the Ingress is not using a secure TLS transport, this is a finding.
Delete any Route or Ingress that does not use a secure transport. oc delete route <NAME> -n <NAMESPACE> or oc delete ingress <NAME> -n <NAMESPACE>
Verify the NX (no-execution) bit flag is set on the system by executing the following: for node in $(oc get node -oname); do oc debug $node -- chroot /host /bin/bash -c 'echo -n "$HOSTNAME "; dmesg | grep Execute ' 2>/dev/null; done Example Output:([ 0.000000] NX (Execute Disable) protection: active) If "dmesg" does not show "NX (Execute Disable) protection active", check the cpuinfo settings by executing the following command: for node in $(oc get node -oname); do oc debug $node -- chroot /host /bin/bash -c 'echo -n "$HOSTNAME "; less /proc/cpuinfo | grep 'nx' /proc/cpuinfo | uniq' 2>/dev/null; done (Example Output: flags : fpu vme de pse tsc ms nx rdtscp lm constant_tsc...) If "flags" does not contain the "nx" flag, this is a finding.
The NX bit execute protection must be enabled in the system BIOS. The nodes must be reinstalled. Follow the steps found here for more information: https://access.redhat.com/solutions/2936741
Verify Red Hat Enterprise Linux CoreOS (RHCOS) implements ASLR by executing the following: for node in $(oc get node -oname); do oc debug $node -- chroot /host /bin/bash -c 'echo -n "$HOSTNAME "; sysctl kernel.randomize_va_space ' 2>/dev/null; done If "kernel.randomize_va_space" is not set to "2", this is a finding.
Apply the machine config to implement ASLR by executing the following: for mcpool in $(oc get mcp -oname | sed "s:.*/::" ); do echo "apiVersion: machineconfiguration.openshift.io/v1 kind: MachineConfig metadata: name: 75-sysctl-kernel-randomize-va-space-$mcpool labels: machineconfiguration.openshift.io/role: $mcpool spec: config: ignition: version: 3.1.0 storage: files: - contents: source: data:,kernel.randomize_va_space%3D2%0A mode: 0644 path: /etc/sysctl.d/75-sysctl_kernel_randomize_va_space.conf overwrite: true " | oc apply -f - done
Ensure the imagepruner is configured and is not in a suspended state by executing the following: oc get imagepruners.imageregistry.operator.openshift.io/cluster -o jsonpath='{.spec}{"\n"}' Review the settings. If "suspend" is set to "true", this is a finding.
Enable the image pruner to automate the pruning of images from the cluster by executing the following: oc patch imagepruners.imageregistry.operator.openshift.io/cluster --type=merge -p '{"spec":{"suspend":false}}' For additional details on configuring the image pruner operator, refer to the following document: https://docs.openshift.com/container-platform/4.8/applications/pruning-objects.html#pruning-images_pruning-objects
Verify the image source policy is configured by executing the following: oc get image.config.openshift.io/cluster -o jsonpath='{.spec.registrySources}{"\nAllowedRegistriesForImport: "}{.spec.allowedRegistriesForImport}{"\n"}' If nothing is returned, this is a finding. If the registries listed under allowedRegistries, insecureRegistries, or AllowedRegistriesForImport are not from trusted sources as defined by the organization, this is a finding.
Edit the cluster image config resource to define the allowed registries by executing the following: oc edit image.config.openshift.io/cluster The following is an example configuration. For a detailed explanation of the configuration properties, refer to https://docs.openshift.com/container-platform/4.8/openshift_images/image-configuration.html. ---------------------------------------------------------------------- apiVersion: config.openshift.io/v1 kind: Image metadata: annotations: release.openshift.io/create-only: "true" creationTimestamp: "2019-05-17T13:44:26Z" generation: 1 name: cluster resourceVersion: "8302" selfLink: /apis/config.openshift.io/v1/images/cluster uid: e34555da-78a9-11e9-b92b-06d6c7da38dc spec: allowedRegistriesForImport: - domainName: quay.io insecure: false additionalTrustedCA: name: myconfigmap registrySources: allowedRegistries: - example.com - quay.io - registry.redhat.io - image-registry.openshift-image-registry.svc:5000 - reg1.io/myrepo/myapp:latest insecureRegistries: - insecure.com status: internalRegistryHostname: image-registry.openshift-image-registry.svc:5000 ----------------------------------------------------------------------
To list all the imagestreams and identify which imagestream tags are configured to periodically check for updates (imagePolicy = { scheduled: true }), execute the following: oc get imagestream --all-namespaces -o jsonpath='{range .items[*]}{.metadata.name}{"\n"}{range .spec.tags[*]}{"\t"}{.name}{": "}{.importPolicy}{"\n"}' The output will be similar to: httpd 2.4: {} 2.4-el7: {} 2.4-el8: {} latest: {} : installer latest: {"scheduled":true} : installer-artifacts latest: {"scheduled":true} : Review the listing, and for each imagestream tag version that does not have the value '{"scheduled":true}' that should otherwise check for updates, this is a finding.
For container images that are not scheduled to check for updates that otherwise should, update the imagestream to schedule updates for each tag by executing the following: oc patch imagestream <NAME> -n NAMESPACE --type merge -p '{"spec":{"tags":[{"name":"<TAG_NAME>","importPolicy":{"scheduled":true}}]}}' where, NAME: The imagestream name to update NAMESPACE: The namespace the imagestream is in. This will most often be 'openshift'. TAG_NAME: The imagestream tag to update
If Red Hat OpenShift Compliance Operator is not used, this check is Not Applicable. Note: If Red Hat OpenShift Compliance Operator is not used, run the checks manually. Review the cluster configuration to validate that all required security functions are being validated with the Compliance Operator. To determine if any scans have been applied to the cluster and the status of the scans, execute the following: oc get compliancescan -n openshift-compliance Example output: NAME PHASE RESULT ocp4-cis DONE NON-COMPLIANT ocp4-cis-manual DONE NON-COMPLIANT ocp4-cis-node-master DONE NON-COMPLIANT ocp4-cis-node-master-manual DONE NON-COMPLIANT ocp4-cis-node-worker DONE NON-COMPLIANT ocp4-cis-node-worker-manual DONE NON-COMPLIANT ocp4-moderate DONE NON-COMPLIANT ocp4-moderate-manual DONE NON-COMPLIANT rhcos4-moderate-master DONE NON-COMPLIANT rhcos4-moderate-master-manual DONE NON-COMPLIANT rhcos4-moderate-worker DONE NON-COMPLIANT rhcos4-moderate-worker-manual DONE NON-COMPLIANT If no ComplianceScan names return, the scans do not align to the organizationally-defined appropriate security functions, the command returns with an error, or any of the results show "NON-COMPLIANT" as their result, then this is a finding.
If Red Hat OpenShift Compliance Operator is not used,, this check is Not Applicable. The compliance operator must be leveraged to ensure that components are configured in alignment with the SSP. Install the Compliance Operator by executing the following: oc apply -f - << 'EOF' --- apiVersion: project.openshift.io/v1 kind: Project metadata: labels: kubernetes.io/metadata.name: openshift-compliance openshift.io/cluster-monitoring: "true" name: openshift-compliance spec: {} ... --- apiVersion: operators.coreos.com/v1 kind: OperatorGroup metadata: name: compliance-operator namespace: openshift-compliance spec: targetNamespaces: - openshift-compliance ... --- apiVersion: operators.coreos.com/v1alpha1 kind: Subscription metadata: name: compliance-operator namespace: openshift-compliance spec: channel: release-0.1 installPlanApproval: Automatic name: compliance-operator source: redhat-operators sourceNamespace: openshift-marketplace ... EOF Following installation of the Compliance Operator, a ScanSettingBinding object that configures the Compliance Operator to use the desired profile sets must be created. TailoredProfiles enable customization of controls to meet specific organizational controls defined in the SSP and can be based on existing profiles or written from scratch in standard SCAP format. If users have the definition for ScanSettingBinding that aligns profiles with ScanSettings in a YAML file named my-scansettingbinding.yml, users would apply that ScanSettingBinding by executing the following: oc apply -f my-scansettingbinding.yml -n openshift-compliance For more information about the compliance operator and its use, including the creation of TailoredProfiles and the ScanSettings available to meet specific security functions or organizational goals defined in the SSP, refer to https://docs.openshift.com/container-platform/4.8/security/compliance_operator/compliance-operator-understanding.html.
If Red Hat OpenShift Compliance Operator is not used, this check is Not Applicable. Review the cluster configuration to validate that all required security functions are being validated with the Compliance Operator. To map the schedule of every profile through its ScanSettingBinding and output the schedules on which each Profile or TailoredProfile is run, execute the following commands: declare -A binding_profiles declare -A binding_schedule while read binding setting profiles; do binding_profiles[$binding]="$profiles"; binding_schedule[$binding]=$(oc get scansetting -n openshift-compliance $setting -ojsonpath='{.schedule}'); done < <(oc get scansettingbinding -n openshift-compliance -ojsonpath='{range .items[*]}{.metadata.name} {.settingsRef.name} {range .profiles[*]}{.name} {end}{"\n"}{end}') for binding in "${!binding_profiles[@]}"; do for profile in ${binding_profiles[$binding]}; do echo "$profile: ${binding_schedule[$binding]}"; done; done If any error is returned, this is a finding. If the schedules are not at least monthly or within the organizationally defined periodicity, this is a finding. Check the profiles that are bound to schedules by executing the following: To determine which rules are enforced by the profiles that are currently bound to the scheduled periodicities, execute the following commands: for binding in "${!binding_profiles[@]}"; do for profile in ${binding_profiles[$binding]}; do for rule in $(oc get profile.compliance $profile -n openshift-compliance -ojsonpath='{range .rules[*]}{$}{"\n"}{end}'); do echo "$rule: ${binding_schedule[$binding]}"; done; done; done | sort -u If the profiles that are bound to schedules do not cover the organization-designed security functions, this is a finding.
If Red Hat OpenShift Compliance Operator is not used, this check is Not Applicable. The compliance operator must be leveraged to ensure that components are configured in alignment with the SSP at a desired schedule. Install the Compliance Operator by executing the following: oc apply -f - << 'EOF' --- apiVersion: project.openshift.io/v1 kind: Project metadata: labels: kubernetes.io/metadata.name: openshift-compliance openshift.io/cluster-monitoring: "true" name: openshift-compliance spec: {} ... --- apiVersion: operators.coreos.com/v1 kind: OperatorGroup metadata: name: compliance-operator namespace: openshift-compliance spec: targetNamespaces: - openshift-compliance ... --- apiVersion: operators.coreos.com/v1alpha1 kind: Subscription metadata: name: compliance-operator namespace: openshift-compliance spec: channel: release-0.1 installPlanApproval: Automatic name: compliance-operator source: redhat-operators sourceNamespace: openshift-marketplace ... EOF Following installation of the Compliance Operator, a ScanSettingBinding object that configures the Compliance Operator to use the desired scan cadence must be created. If users have the definition for ScanSettingBinding in a YAML file named my-scansettingbinding.yml, users would apply that ScanSettingBinding by executing the following: oc apply -f my-scansettingbinding.yml -n openshift-compliance For more information about the compliance operator and its use, including the configurability of scheduling of scan cadence in ScanSetting resources and the role-based access control requirements for manually triggered scans, refer to https://docs.openshift.com/container-platform/4.8/security/compliance_operator/compliance-operator-understanding.html.
Verify OpenShift is configured to generate audit records when successful/unsuccessful attempts to modify privileges occur by executing the following: for node in $(oc get node -oname); do oc debug $node -- chroot /host /bin/bash -c 'echo -n "$HOSTNAME "; grep -e "key=unsuccessful-create" -e "key=unsuccessful-modification" -e "key=delete" -e "key=unsuccessful-access" -e "actions" -e "key=perm_mod" -e "audit_rules_usergroup_modification" -e "module-change" -e "logins" /etc/audit/audit.rules' 2>/dev/null; done Confirm the following rules exist on each node: -w /etc/group -p wa -k audit_rules_usergroup_modification -w /etc/gshadow -p wa -k audit_rules_usergroup_modification -w /etc/passwd -p wa -k audit_rules_usergroup_modification -w /etc/security/opasswd -p wa -k audit_rules_usergroup_modification -w /etc/shadow -p wa -k audit_rules_usergroup_modification -a always,exit -F arch=b32 -S openat,open_by_handle_at -F a2&0x40 -F exit=-EACCES -F auid>=1000 -F auid!=unset -F key=unsuccessful-create -a always,exit -F arch=b64 -S openat,open_by_handle_at -F a2&0x40 -F exit=-EACCES -F auid>=1000 -F auid!=unset -F key=unsuccessful-create -a always,exit -F arch=b32 -S open -F a1&0x40 -F exit=-EACCES -F auid>=1000 -F auid!=unset -F key=unsuccessful-create -a always,exit -F arch=b64 -S open -F a1&0x40 -F exit=-EACCES -F auid>=1000 -F auid!=unset -F key=unsuccessful-create -a always,exit -F arch=b32 -S openat,open_by_handle_at -F a2&0x40 -F exit=-EPERM -F auid>=1000 -F auid!=unset -F key=unsuccessful-create -a always,exit -F arch=b64 -S openat,open_by_handle_at -F a2&0x40 -F exit=-EPERM -F auid>=1000 -F auid!=unset -F key=unsuccessful-create -a always,exit -F arch=b32 -S open -F a1&0x40 -F exit=-EPERM -F auid>=1000 -F auid!=unset -F key=unsuccessful-create -a always,exit -F arch=b64 -S open -F a1&0x40 -F exit=-EPERM -F auid>=1000 -F auid!=unset -F key=unsuccessful-create -a always,exit -F arch=b32 -S creat -F exit=-EACCES -F auid>=1000 -F auid!=unset -F key=unsuccessful-create -a always,exit -F arch=b64 -S creat -F exit=-EACCES -F auid>=1000 -F auid!=unset -F key=unsuccessful-create -a always,exit -F arch=b32 -S creat -F exit=-EPERM -F auid>=1000 -F auid!=unset -F key=unsuccessful-create -a always,exit -F arch=b64 -S creat -F exit=-EPERM -F auid>=1000 -F auid!=unset -F key=unsuccessful-create -a always,exit -F arch=b32 -S openat,open_by_handle_at -F a2&0x203 -F exit=-EACCES -F auid>=1000 -F auid!=unset -F key=unsuccessful-modification -a always,exit -F arch=b64 -S openat,open_by_handle_at -F a2&0x203 -F exit=-EACCES -F auid>=1000 -F auid!=unset -F key=unsuccessful-modification -a always,exit -F arch=b32 -S open -F a1&0x203 -F exit=-EACCES -F auid>=1000 -F auid!=unset -F key=unsuccessful-modification -a always,exit -F arch=b64 -S open -F a1&0x203 -F exit=-EACCES -F auid>=1000 -F auid!=unset -F key=unsuccessful-modification -a always,exit -F arch=b32 -S openat,open_by_handle_at -F a2&0x203 -F exit=-EPERM -F auid>=1000 -F auid!=unset -F key=unsuccessful-modification -a always,exit -F arch=b64 -S openat,open_by_handle_at -F a2&0x203 -F exit=-EPERM -F auid>=1000 -F auid!=unset -F key=unsuccessful-modmodule-changeification -a always,exit -F arch=b32 -S open -F a1&0x203 -F exit=-EPERM -F auid>=1000 -F auid!=unset -F key=unsuccessful-modification -a always,exit -F arch=b64 -S open -F a1&0x203 -F exit=-EPERM -F auid>=1000 -F auid!=unset -F key=unsuccessful-modification -a always,exit -F arch=b32 -S truncate,ftruncate -F exit=-EACCES -F auid>=1000 -F auid!=unset -F key=unsuccessful-modification -a always,exit -F arch=b64 -S truncate,ftruncate -F exit=-EACCES -F auid>=1000 -F auid!=unset -F key=unsuccessful-modification -a always,exit -F arch=b32 -S truncate,ftruncate -F exit=-EPERM -F auid>=1000 -F auid!=unset -F key=unsuccessful-modification -a always,exit -F arch=b64 -S truncate,ftruncate -F exit=-EPERM -F auid>=1000 -F auid!=unset -F key=unsuccessful-modification -a always,exit -F arch=b32 -S open,creat,truncate,ftruncate,openat,open_by_handle_at -F exit=-EACCES -F auid>=1000 -F auid!=unset -F key=unsuccessful-access -a always,exit -F arch=b64 -S open,truncate,ftruncate,creat,openat,open_by_handle_at -F exit=-EACCES -F auid>=1000 -F auid!=unset -F key=unsuccessful-access -a always,exit -F arch=b32 -S open,creat,truncate,ftruncate,openat,open_by_handle_at -F exit=-EPERM -F auid>=1000 -F auid!=unset -F key=unsuccessful-access -a always,exit -F arch=b64 -S open,truncate,ftruncate,creat,openat,open_by_handle_at -F exit=-EPERM -F auid>=1000 -F auid!=unset -F key=unsuccessful-access -w /etc/sudoers.d -p wa -k actions -w /etc/sudoers -p wa -k actions -a always,exit -F arch=b32 -S chmod -F auid>=1000 -F auid!=unset -F key=perm_mod -a always,exit -F arch=b64 -S chmod -F auid>=1000 -F auid!=unset -F key=perm_mod -a always,exit -F arch=b32 -S chown -F auid>=1000 -F auid!=unset -F key=perm_mod -a always,exit -F arch=b64 -S chown -F auid>=1000 -F auid!=unset -F key=perm_mod -a always,exit -F arch=b32 -S fchmodat -F auid>=1000 -F auid!=unset -F key=perm_mod -a always,exit -F arch=b64 -S fchmodat -F auid>=1000 -F auid!=unset -F key=perm_mod -a always,exit -F arch=b32 -S fchmod -F auid>=1000 -F auid!=unset -F key=perm_mod -a always,exit -F arch=b64 -S fchmod -F auid>=1000 -F auid!=unset -F key=perm_mod -a always,exit -F arch=b32 -S fchownat -F auid>=1000 -F auid!=unset -F key=perm_mod -a always,exit -F arch=b64 -S fchownat -F auid>=1000 -F auid!=unset -F key=perm_mod -a always,exit -F arch=b32 -S fchown -F auid>=1000 -F auid!=unset -F key=perm_mod -a always,exit -F arch=b64 -S fchown -F auid>=1000 -F auid!=unset -F key=perm_mod -a always,exit -F arch=b32 -S fremovexattr -F auid>=1000 -F auid!=unset -F key=perm_mod -a always,exit -F arch=b64 -S fremovexattr -F auid>=1000 -F auid!=unset -F key=perm_mod -a always,exit -F arch=b32 -S fsetxattr -F auid>=1000 -F auid!=unset -F key=perm_mod -a always,exit -F arch=b64 -S fsetxattr -F auid>=1000 -F auid!=unset -F key=perm_mod -a always,exit -F arch=b32 -S delete_module -F key=module-change -a always,exit -F arch=b64 -S delete_module -F key=module-change -a always,exit -F arch=b32 -S finit_module -F key=module-change -a always,exit -F arch=b64 -S finit_module -F key=module-change -a always,exit -F arch=b32 -S init_module -F key=module-change -a always,exit -F arch=b64 -S init_module -F key=module-change -w /var/log/lastlog -p wa -k logins -a always,exit -F arch=b32 -S lchown -F auid>=1000 -F auid!=unset -F key=perm_mod -a always,exit -F arch=b64 -S lchown -F auid>=1000 -F auid!=unset -F key=perm_mod -a always,exit -F arch=b32 -S lremovexattr -F auid>=1000 -F auid!=unset -F key=perm_mod -a always,exit -F arch=b64 -S lremovexattr -F auid>=1000 -F auid!=unset -F key=perm_mod -a always,exit -F arch=b32 -S lsetxattr -F auid>=1000 -F auid!=unset -F key=perm_mod -a always,exit -F arch=b64 -S lsetxattr -F auid>=1000 -F auid!=unset -F key=perm_mod -a always,exit -F arch=b32 -S mount -F auid>=1000 -F auid!=unset -F key=perm_mod -a always,exit -F arch=b64 -S mount -F auid>=1000 -F auid!=unset -F key=perm_mod -a always,exit -F arch=b32 -S removexattr -F auid>=1000 -F auid!=unset -F key=perm_mod -a always,exit -F arch=b64 -S removexattr -F auid>=1000 -F auid!=unset -F key=perm_mod -a always,exit -F arch=b32 -S renameat -F auid>=1000 -F auid!=unset -F key=delete -a always,exit -F arch=b64 -S renameat -F auid>=1000 -F auid!=unset -F key=delete -a always,exit -F arch=b32 -S rename -F auid>=1000 -F auid!=unset -F key=delete -a always,exit -F arch=b64 -S rename -F auid>=1000 -F auid!=unset -F key=delete -a always,exit -F arch=b32 -S rmdir -F auid>=1000 -F auid!=unset -F key=delete -a always,exit -F arch=b64 -S rmdir -F auid>=1000 -F auid!=unset -F key=delete -a always,exit -F arch=b32 -S setxattr -F auid>=1000 -F auid!=unset -F key=perm_mod -a always,exit -F arch=b64 -S setxattr -F auid>=1000 -F auid!=unset -F key=perm_mod -a always,exit -F arch=b32 -S umount2 -F auid>=1000 -F auid!=unset -F key=perm_mod -a always,exit -F arch=b64 -S umount2 -F auid>=1000 -F auid!=unset -F key=perm_mod If the above rules are not listed on each node, this is a finding.
Apply the machine config to generate audit records when successful/unsuccessful attempts to modify privileges by executing the following: for mcpool in $(oc get mcp -oname | sed "s:.*/::" ); do echo "apiVersion: machineconfiguration.openshift.io/v1 kind: MachineConfig metadata: name: 75-modify-privileges-rules-$mcpool labels: machineconfiguration.openshift.io/role: $mcpool spec: config: ignition: version: 3.1.0 storage: files: - contents: source: data:,%23%23%20Make%20the%20loginuid%20immutable.%20This%20prevents%20tampering%20with%20the%20auid.%0A--loginuid-immutable%0A mode: 0644 path: /etc/audit/rules.d/11-loginuid.rules overwrite: true - contents: source: data:,-a%20always%2Cexit%20-F%20arch%3Db32%20-S%20chmod%20-F%20auid%3E%3D1000%20-F%20auid%21%3Dunset%20-F%20key%3Dperm_mod%0A-a%20always%2Cexit%20-F%20arch%3Db64%20-S%20chmod%20-F%20auid%3E%3D1000%20-F%20auid%21%3Dunset%20-F%20key%3Dperm_mod%0A mode: 0644 path: /etc/audit/rules.d/75-chmod_dac_modification.rules overwrite: true - contents: source: data:,-a%20always%2Cexit%20-F%20arch%3Db32%20-S%20chown%20-F%20auid%3E%3D1000%20-F%20auid%21%3Dunset%20-F%20key%3Dperm_mod%0A-a%20always%2Cexit%20-F%20arch%3Db64%20-S%20chown%20-F%20auid%3E%3D1000%20-F%20auid%21%3Dunset%20-F%20key%3Dperm_mod%0A mode: 0644 path: /etc/audit/rules.d/75-chown_dac_modification.rules overwrite: true - contents: source: data:,-a%20always%2Cexit%20-F%20arch%3Db32%20-S%20fchmod%20-F%20auid%3E%3D1000%20-F%20auid%21%3Dunset%20-F%20key%3Dperm_mod%0A-a%20always%2Cexit%20-F%20arch%3Db64%20-S%20fchmod%20-F%20auid%3E%3D1000%20-F%20auid%21%3Dunset%20-F%20key%3Dperm_mod%0A mode: 0644 path: /etc/audit/rules.d/75-fchmod_dac_modification.rules overwrite: true - contents: source: data:,-a%20always%2Cexit%20-F%20arch%3Db32%20-S%20fchmodat%20-F%20auid%3E%3D1000%20-F%20auid%21%3Dunset%20-F%20key%3Dperm_mod%0A-a%20always%2Cexit%20-F%20arch%3Db64%20-S%20fchmodat%20-F%20auid%3E%3D1000%20-F%20auid%21%3Dunset%20-F%20key%3Dperm_mod%0A mode: 0644 path: /etc/audit/rules.d/75-fchmodat_dac_modification.rules overwrite: true - contents: source: data:,-a%20always%2Cexit%20-F%20arch%3Db32%20-S%20fchown%20-F%20auid%3E%3D1000%20-F%20auid%21%3Dunset%20-F%20key%3Dperm_mod%0A-a%20always%2Cexit%20-F%20arch%3Db64%20-S%20fchown%20-F%20auid%3E%3D1000%20-F%20auid%21%3Dunset%20-F%20key%3Dperm_mod%0A mode: 0644 path: /etc/audit/rules.d/75-fchown_dac_modification.rules overwrite: true - contents: source: data:,-a%20always%2Cexit%20-F%20arch%3Db32%20-S%20fchownat%20-F%20auid%3E%3D1000%20-F%20auid%21%3Dunset%20-F%20key%3Dperm_mod%0A-a%20always%2Cexit%20-F%20arch%3Db64%20-S%20fchownat%20-F%20auid%3E%3D1000%20-F%20auid%21%3Dunset%20-F%20key%3Dperm_mod%0A mode: 0644 path: /etc/audit/rules.d/75-fchownat_dac_modification.rules overwrite: true - contents: source: data:,-a%20always%2Cexit%20-F%20arch%3Db32%20-S%20fremovexattr%20-F%20auid%3E%3D1000%20-F%20auid%21%3Dunset%20-F%20key%3Dperm_mod%0A-a%20always%2Cexit%20-F%20arch%3Db64%20-S%20fremovexattr%20-F%20auid%3E%3D1000%20-F%20auid%21%3Dunset%20-F%20key%3Dperm_mod%0A mode: 0644 path: /etc/audit/rules.d/75-fremovexattr_dac_modification.rules overwrite: true - contents: source: data:,-a%20always%2Cexit%20-F%20arch%3Db32%20-S%20fsetxattr%20-F%20auid%3E%3D1000%20-F%20auid%21%3Dunset%20-F%20key%3Dperm_mod%0A-a%20always%2Cexit%20-F%20arch%3Db64%20-S%20fsetxattr%20-F%20auid%3E%3D1000%20-F%20auid%21%3Dunset%20-F%20key%3Dperm_mod%0A mode: 0644 path: /etc/audit/rules.d/75-fsetxattr_dac_modification.rules overwrite: true - contents: source: data:,-a%20always%2Cexit%20-F%20arch%3Db32%20-S%20lchown%20-F%20auid%3E%3D1000%20-F%20auid%21%3Dunset%20-F%20key%3Dperm_mod%0A-a%20always%2Cexit%20-F%20arch%3Db64%20-S%20lchown%20-F%20auid%3E%3D1000%20-F%20auid%21%3Dunset%20-F%20key%3Dperm_mod%0A mode: 0644 path: /etc/audit/rules.d/75-lchown_dac_modification.rules overwrite: true - contents: source: data:,-a%20always%2Cexit%20-F%20arch%3Db32%20-S%20lremovexattr%20-F%20auid%3E%3D1000%20-F%20auid%21%3Dunset%20-F%20key%3Dperm_mod%0A-a%20always%2Cexit%20-F%20arch%3Db64%20-S%20lremovexattr%20-F%20auid%3E%3D1000%20-F%20auid%21%3Dunset%20-F%20key%3Dperm_mod%0A mode: 0644 path: /etc/audit/rules.d/75-lremovexattr_dac_modification.rules overwrite: true - contents: source: data:,-a%20always%2Cexit%20-F%20arch%3Db32%20-S%20lsetxattr%20-F%20auid%3E%3D1000%20-F%20auid%21%3Dunset%20-F%20key%3Dperm_mod%0A-a%20always%2Cexit%20-F%20arch%3Db64%20-S%20lsetxattr%20-F%20auid%3E%3D1000%20-F%20auid%21%3Dunset%20-F%20key%3Dperm_mod%0A mode: 0644 path: /etc/audit/rules.d/75-lsetxattr_dac_modification.rules overwrite: true - contents: source: data:,-a%20always%2Cexit%20-F%20arch%3Db32%20-S%20removexattr%20-F%20auid%3E%3D1000%20-F%20auid%21%3Dunset%20-F%20key%3Dperm_mod%0A-a%20always%2Cexit%20-F%20arch%3Db64%20-S%20removexattr%20-F%20auid%3E%3D1000%20-F%20auid%21%3Dunset%20-F%20key%3Dperm_mod%0A mode: 0644 path: /etc/audit/rules.d/75-removexattr_dac_modification.rules overwrite: true - contents: source: data:,-a%20always%2Cexit%20-F%20arch%3Db32%20-S%20setxattr%20-F%20auid%3E%3D1000%20-F%20auid%21%3Dunset%20-F%20key%3Dperm_mod%0A-a%20always%2Cexit%20-F%20arch%3Db64%20-S%20setxattr%20-F%20auid%3E%3D1000%20-F%20auid%21%3Dunset%20-F%20key%3Dperm_mod%0A mode: 0644 path: /etc/audit/rules.d/75-setxattr_dac_modification.rules overwrite: true - contents: source: data:,-a%20always%2Cexit%20-F%20arch%3Db32%20-S%20umount2%20-F%20auid%3E%3D1000%20-F%20auid%21%3Dunset%20-F%20key%3Dperm_mod%0A-a%20always%2Cexit%20-F%20arch%3Db64%20-S%20umount%20-F%20auid%3E%3D1000%20-F%20auid%21%3Dunset%20-F%20key%3Dperm_mod%0A mode: 0644 path: /etc/audit/rules.d/75-umount_dac_modification.rules overwrite: true - contents: source: data:,-a%20always%2Cexit%20-F%20arch%3Db32%20-S%20umount2%20-F%20auid%3E%3D1000%20-F%20auid%21%3Dunset%20-F%20key%3Dperm_mod%0A-a%20always%2Cexit%20-F%20arch%3Db64%20-S%20umount2%20-F%20auid%3E%3D1000%20-F%20auid%21%3Dunset%20-F%20key%3Dperm_mod%0A mode: 0644 path: /etc/audit/rules.d/75-umount2_dac_modification.rules overwrite: true - contents: source: data:,-a%20always%2Cexit%20-F%20path%3D/usr/sbin/usermod%20-F%20auid%3E%3D1000%20-F%20auid%21%3Dunset%20-F%20key%3Dprivileged%0A mode: 0644 path: /etc/audit/rules.d/75-usr_sbin_usermod_execution.rules overwrite: true - contents: source: data:,-a%20always%2Cexit%20-F%20path%3D/usr/sbin/unix_update%20-F%20auid%3E%3D1000%20-F%20auid%21%3Dunset%20-F%20key%3Dprivileged%0A mode: 0644 path: /etc/audit/rules.d/75-usr_sbin_unix_update_execution.rules overwrite: true - contents: source: data:,-a%20always%2Cexit%20-F%20path%3D/usr/bin/kmod%20-F%20auid%3E%3D1000%20-F%20auid%21%3Dunset%20-F%20key%3Dprivileged%0A mode: 0644 path: /etc/audit/rules.d/75-usr_bin_kmod_execution.rules overwrite: true - contents: source: data:,-a%20always%2Cexit%20-F%20path%3D/usr/bin/setfacl%20-F%20auid%3E%3D1000%20-F%20auid%21%3Dunset%20-F%20key%3Dprivileged%0A mode: 0644 path: /etc/audit/rules.d/75-usr_bin_setfacl_execution.rules overwrite: true - contents: source: data:,-a%20always%2Cexit%20-F%20path%3D/usr/bin/chacl%20-F%20auid%3E%3D1000%20-F%20auid%21%3Dunset%20-F%20key%3Dprivileged%0A mode: 0644 path: /etc/audit/rules.d/75-usr_bin_chacl_execution.rules overwrite: true - contents: source: data:,-a%20always%2Cexit%20-F%20path%3D/usr/bin/chcon%20-F%20auid%3E%3D1000%20-F%20auid%21%3Dunset%20-F%20key%3Dprivileged%0A mode: 0644 path: /etc/audit/rules.d/75-usr_bin_chcon_execution.rules overwrite: true - contents: source: data:,-a%20always%2Cexit%20-F%20path%3D/usr/sbin/semanage%20-F%20auid%3E%3D1000%20-F%20auid%21%3Dunset%20-F%20key%3Dprivileged%0A mode: 0644 path: /etc/audit/rules.d/75-usr_sbin_semanage_execution.rules overwrite: true - contents: source: data:,-a%20always%2Cexit%20-F%20path%3D/usr/sbin/setfiles%20-F%20auid%3E%3D1000%20-F%20auid%21%3Dunset%20-F%20key%3Dprivileged%0A mode: 0644 path: /etc/audit/rules.d/75-usr_sbin_setfiles_execution.rules overwrite: true - contents: source: data:,-a%20always%2Cexit%20-F%20path%3D/usr/sbin/setsebool%20-F%20auid%3E%3D1000%20-F%20auid%21%3Dunset%20-F%20key%3Dprivileged%0A mode: 0644 path: /etc/audit/rules.d/75-usr_sbin_setsebool_execution.rules overwrite: true - contents: source: data:,-a%20always%2Cexit%20-F%20arch%3Db32%20-S%20rename%20-F%20auid%3E%3D1000%20-F%20auid%21%3Dunset%20-F%20key%3Ddelete%0A-a%20always%2Cexit%20-F%20arch%3Db64%20-S%20rename%20-F%20auid%3E%3D1000%20-F%20auid%21%3Dunset%20-F%20key%3Ddelete%0A mode: 0644 path: /etc/audit/rules.d/75-rename-file-deletion-events.rules overwrite: true - contents: source: data:,-a%20always%2Cexit%20-F%20arch%3Db32%20-S%20renameat%20-F%20auid%3E%3D1000%20-F%20auid%21%3Dunset%20-F%20key%3Ddelete%0A-a%20always%2Cexit%20-F%20arch%3Db64%20-S%20renameat%20-F%20auid%3E%3D1000%20-F%20auid%21%3Dunset%20-F%20key%3Ddelete%0A mode: 0644 path: /etc/audit/rules.d/75-renameat-file-deletion-events.rules overwrite: true - contents: source: data:,-a%20always%2Cexit%20-F%20arch%3Db32%20-S%20rmdir%20-F%20auid%3E%3D1000%20-F%20auid%21%3Dunset%20-F%20key%3Ddelete%0A-a%20always%2Cexit%20-F%20arch%3Db64%20-S%20rmdir%20-F%20auid%3E%3D1000%20-F%20auid%21%3Dunset%20-F%20key%3Ddelete%0A mode: 0644 path: /etc/audit/rules.d/75-rmdir-file-deletion-events.rules overwrite: true - contents: source: data:,-a%20always%2Cexit%20-F%20arch%3Db32%20-S%20unlink%20-F%20auid%3E%3D1000%20-F%20auid%21%3Dunset%20-F%20key%3Ddelete%0A-a%20always%2Cexit%20-F%20arch%3Db64%20-S%20unlink%20-F%20auid%3E%3D1000%20-F%20auid%21%3Dunset%20-F%20key%3Ddelete%0A mode: 0644 path: /etc/audit/rules.d/75-unlink-file-deletion-events.rules overwrite: true - contents: source: data:,-a%20always%2Cexit%20-F%20arch%3Db32%20-S%20unlinkat%20-F%20auid%3E%3D1000%20-F%20auid%21%3Dunset%20-F%20key%3Ddelete%0A-a%20always%2Cexit%20-F%20arch%3Db64%20-S%20unlinkat%20-F%20auid%3E%3D1000%20-F%20auid%21%3Dunset%20-F%20key%3Ddelete%0A mode: 0644 path: /etc/audit/rules.d/75-unlinkat-file-deletion-events.rules overwrite: true - contents: source: data:,-a%20always%2Cexit%20-F%20arch%3Db32%20-S%20delete_module%20-k%20module-change%0A-a%20always%2Cexit%20-F%20arch%3Db64%20-S%20delete_module%20-k%20module-change%0A mode: 0644 path: /etc/audit/rules.d/75-kernel-module-loading-delete.rules overwrite: true - contents: source: data:,-a%20always%2Cexit%20-F%20arch%3Db32%20-S%20finit_module%20-k%20module-change%0A-a%20always%2Cexit%20-F%20arch%3Db64%20-S%20finit_module%20-k%20module-change%0A mode: 0644 path: /etc/audit/rules.d/75-kernel-module-loading-finit.rules overwrite: true - contents: source: data:,-a%20always%2Cexit%20-F%20arch%3Db32%20-S%20init_module%20-k%20module-change%0A-a%20always%2Cexit%20-F%20arch%3Db64%20-S%20init_module%20-k%20module-change%0A mode: 0644 path: /etc/audit/rules.d/75-kernel-module-loading-init.rules overwrite: true - contents: source: data:,-w%20/var/log/lastlog%20-p%20wa%20-k%20logins%0A mode: 0644 path: /etc/audit/rules.d/75-lastlog_login_events.rules overwrite: true - contents: source: data:,-a%20always%2Cexit%20-F%20arch%3Db32%20-S%20mount%20-F%20auid%3E%3D1000%20-F%20auid%21%3Dunset%20-F%20key%3Dperm_mod%0A-a%20always%2Cexit%20-F%20arch%3Db64%20-S%20mount%20-F%20auid%3E%3D1000%20-F%20auid%21%3Dunset%20-F%20key%3Dperm_mod%0A mode: 0644 path: /etc/audit/rules.d/75-mount_dac_modification.rules overwrite: true - contents: source: data:,-a%20always%2Cexit%20-F%20path%3D/usr/bin/chage%20-F%20auid%3E%3D1000%20-F%20auid%21%3Dunset%20-F%20key%3Dprivileged%0A mode: 0644 path: /etc/audit/rules.d/75-usr_bin_chage_execution.rules overwrite: true - contents: source: data:,-a%20always%2Cexit%20-F%20path%3D/usr/bin/chsh%20-F%20auid%3E%3D1000%20-F%20auid%21%3Dunset%20-F%20key%3Dprivileged%0A mode: 0644 path: /etc/audit/rules.d/75-usr_bin_chsh_execution.rules overwrite: true - contents: source: data:,-a%20always%2Cexit%20-F%20path%3D/usr/bin/crontab%20-F%20auid%3E%3D1000%20-F%20auid%21%3Dunset%20-F%20key%3Dprivileged%0A mode: 0644 path: /etc/audit/rules.d/75-usr_bin_crontab_execution.rules overwrite: true - contents: source: data:,-a%20always%2Cexit%20-F%20path%3D/usr/bin/gpasswd%20-F%20auid%3E%3D1000%20-F%20auid%21%3Dunset%20-F%20key%3Dprivileged%0A mode: 0644 path: /etc/audit/rules.d/75-usr_bin_gpasswd_execution.rules overwrite: true - contents: source: data:,-a%20always%2Cexit%20-F%20path%3D/usr/bin/newgrp%20-F%20auid%3E%3D1000%20-F%20auid%21%3Dunset%20-F%20key%3Dprivileged%0A mode: 0644 path: /etc/audit/rules.d/75-usr_bin_newgrp_execution.rules overwrite: true - contents: source: data:,-a%20always%2Cexit%20-F%20path%3D/usr/sbin/pam_timestamp_check%20-F%20auid%3E%3D1000%20-F%20auid%21%3Dunset%20-F%20key%3Dprivileged%0A mode: 0644 path: /etc/audit/rules.d/75-usr_sbin_pam_timestamp_check_execution.rules overwrite: true - contents: source: data:,-a%20always%2Cexit%20-F%20path%3D/usr/bin/passwd%20-F%20auid%3E%3D1000%20-F%20auid%21%3Dunset%20-F%20key%3Dprivileged%0A mode: 0644 path: /etc/audit/rules.d/75-usr_bin_passwd_execution.rules overwrite: true - contents: source: data:,-a%20always%2Cexit%20-F%20path%3D/usr/libexec/openssh/ssh-keysign%20-F%20auid%3E%3D1000%20-F%20auid%21%3Dunset%20-F%20key%3Dprivileged%0A mode: 0644 path: /etc/audit/rules.d/75-usr_libexec_openssh_ssh-keysign_execution.rules overwrite: true - contents: source: data:,-a%20always%2Cexit%20-F%20path%3D/usr/bin/su%20-F%20auid%3E%3D1000%20-F%20auid%21%3Dunset%20-F%20key%3Dprivileged%0A mode: 0644 path: /etc/audit/rules.d/75-usr_bin_su_execution.rules overwrite: true - contents: source: data:,-a%20always%2Cexit%20-F%20path%3D/usr/bin/sudo%20-F%20auid%3E%3D1000%20-F%20auid%21%3Dunset%20-F%20key%3Dprivileged%0A mode: 0644 path: /etc/audit/rules.d/75-usr_bin_sudo_execution.rules overwrite: true - contents: source: data:,-a%20always%2Cexit%20-F%20path%3D/usr/bin/sudoedit%20-F%20auid%3E%3D1000%20-F%20auid%21%3Dunset%20-F%20key%3Dprivileged%0A mode: 0644 path: /etc/audit/rules.d/75-usr_bin_sudoedit_execution.rules overwrite: true - contents: source: data:,-a%20always%2Cexit%20-F%20path%3D/usr/sbin/unix_chkpwd%20-F%20auid%3E%3D1000%20-F%20auid%21%3Dunset%20-F%20key%3Dprivileged%0A mode: 0644 path: /etc/audit/rules.d/75-usr_sbin_unix_chkpwd_execution.rules overwrite: true - contents: source: data:,-a%20always%2Cexit%20-F%20path%3D/usr/sbin/userhelper%20-F%20auid%3E%3D1000%20-F%20auid%21%3Dunset%20-F%20key%3Dprivileged%0A mode: 0644 path: /etc/audit/rules.d/75-usr_sbin_userhelper_execution.rules overwrite: true - contents: source: data:,-w%20/etc/sudoers.d/%20-p%20wa%20-k%20actions%0A-w%20/etc/sudoers%20-p%20wa%20-k%20actions%0A mode: 0644 path: /etc/audit/rules.d/75-audit-sysadmin-actions.rules overwrite: true - contents: source: data:,%23%23%20This%20content%20is%20a%20section%20of%20an%20Audit%20config%20snapshot%20recommended%20for%20Red%2520Hat%2520Enterprise%2520Linux%2520CoreOS%25204%20systems%20that%20target%20OSPP%20compliance.%0A%23%23%20The%20following%20content%20has%20been%20retreived%20on%202019-03-11%20from%3A%20https%3A//github.com/linux-audit/audit-userspace/blob/master/rules/30-ospp-v42.rules%0A%0A%23%23%20The%20purpose%20of%20these%20rules%20is%20to%20meet%20the%20requirements%20for%20Operating%0A%23%23%20System%20Protection%20Profile%20%28OSPP%29v4.2.%20These%20rules%20depends%20on%20having%0A%23%23%2010-base-config.rules%2C%2011-loginuid.rules%2C%20and%2043-module-load.rules%20installed.%0A%0A%23%23%20Unsuccessful%20file%20creation%20%28open%20with%20O_CREAT%29%0A-a%20always%2Cexit%20-F%20arch%3Db32%20-S%20openat%2Copen_by_handle_at%20-F%20a2%260100%20-F%20exit%3D-EACCES%20-F%20auid%3E%3D1000%20-F%20auid%21%3Dunset%20-F%20key%3Dunsuccessful-create%0A-a%20always%2Cexit%20-F%20arch%3Db64%20-S%20openat%2Copen_by_handle_at%20-F%20a2%260100%20-F%20exit%3D-EACCES%20-F%20auid%3E%3D1000%20-F%20auid%21%3Dunset%20-F%20key%3Dunsuccessful-create%0A-a%20always%2Cexit%20-F%20arch%3Db32%20-S%20open%20-F%20a1%260100%20-F%20exit%3D-EACCES%20-F%20auid%3E%3D1000%20-F%20auid%21%3Dunset%20-F%20key%3Dunsuccessful-create%0A-a%20always%2Cexit%20-F%20arch%3Db64%20-S%20open%20-F%20a1%260100%20-F%20exit%3D-EACCES%20-F%20auid%3E%3D1000%20-F%20auid%21%3Dunset%20-F%20key%3Dunsuccessful-create%0A-a%20always%2Cexit%20-F%20arch%3Db32%20-S%20openat%2Copen_by_handle_at%20-F%20a2%260100%20-F%20exit%3D-EPERM%20-F%20auid%3E%3D1000%20-F%20auid%21%3Dunset%20-F%20key%3Dunsuccessful-create%0A-a%20always%2Cexit%20-F%20arch%3Db64%20-S%20openat%2Copen_by_handle_at%20-F%20a2%260100%20-F%20exit%3D-EPERM%20-F%20auid%3E%3D1000%20-F%20auid%21%3Dunset%20-F%20key%3Dunsuccessful-create%0A-a%20always%2Cexit%20-F%20arch%3Db32%20-S%20open%20-F%20a1%260100%20-F%20exit%3D-EPERM%20-F%20auid%3E%3D1000%20-F%20auid%21%3Dunset%20-F%20key%3Dunsuccessful-create%0A-a%20always%2Cexit%20-F%20arch%3Db64%20-S%20open%20-F%20a1%260100%20-F%20exit%3D-EPERM%20-F%20auid%3E%3D1000%20-F%20auid%21%3Dunset%20-F%20key%3Dunsuccessful-create%0A-a%20always%2Cexit%20-F%20arch%3Db32%20-S%20creat%20-F%20exit%3D-EACCES%20-F%20auid%3E%3D1000%20-F%20auid%21%3Dunset%20-F%20key%3Dunsuccessful-create%0A-a%20always%2Cexit%20-F%20arch%3Db64%20-S%20creat%20-F%20exit%3D-EACCES%20-F%20auid%3E%3D1000%20-F%20auid%21%3Dunset%20-F%20key%3Dunsuccessful-create%0A-a%20always%2Cexit%20-F%20arch%3Db32%20-S%20creat%20-F%20exit%3D-EPERM%20-F%20auid%3E%3D1000%20-F%20auid%21%3Dunset%20-F%20key%3Dunsuccessful-create%0A-a%20always%2Cexit%20-F%20arch%3Db64%20-S%20creat%20-F%20exit%3D-EPERM%20-F%20auid%3E%3D1000%20-F%20auid%21%3Dunset%20-F%20key%3Dunsuccessful-create%0A%0A%23%23%20Unsuccessful%20file%20modifications%20%28open%20for%20write%20or%20truncate%29%0A-a%20always%2Cexit%20-F%20arch%3Db32%20-S%20openat%2Copen_by_handle_at%20-F%20a2%2601003%20-F%20exit%3D-EACCES%20-F%20auid%3E%3D1000%20-F%20auid%21%3Dunset%20-F%20key%3Dunsuccessful-modification%0A-a%20always%2Cexit%20-F%20arch%3Db64%20-S%20openat%2Copen_by_handle_at%20-F%20a2%2601003%20-F%20exit%3D-EACCES%20-F%20auid%3E%3D1000%20-F%20auid%21%3Dunset%20-F%20key%3Dunsuccessful-modification%0A-a%20always%2Cexit%20-F%20arch%3Db32%20-S%20open%20-F%20a1%2601003%20-F%20exit%3D-EACCES%20-F%20auid%3E%3D1000%20-F%20auid%21%3Dunset%20-F%20key%3Dunsuccessful-modification%0A-a%20always%2Cexit%20-F%20arch%3Db64%20-S%20open%20-F%20a1%2601003%20-F%20exit%3D-EACCES%20-F%20auid%3E%3D1000%20-F%20auid%21%3Dunset%20-F%20key%3Dunsuccessful-modification%0A-a%20always%2Cexit%20-F%20arch%3Db32%20-S%20openat%2Copen_by_handle_at%20-F%20a2%2601003%20-F%20exit%3D-EPERM%20-F%20auid%3E%3D1000%20-F%20auid%21%3Dunset%20-F%20key%3Dunsuccessful-modification%0A-a%20always%2Cexit%20-F%20arch%3Db64%20-S%20openat%2Copen_by_handle_at%20-F%20a2%2601003%20-F%20exit%3D-EPERM%20-F%20auid%3E%3D1000%20-F%20auid%21%3Dunset%20-F%20key%3Dunsuccessful-modification%0A-a%20always%2Cexit%20-F%20arch%3Db32%20-S%20open%20-F%20a1%2601003%20-F%20exit%3D-EPERM%20-F%20auid%3E%3D1000%20-F%20auid%21%3Dunset%20-F%20key%3Dunsuccessful-modification%0A-a%20always%2Cexit%20-F%20arch%3Db64%20-S%20open%20-F%20a1%2601003%20-F%20exit%3D-EPERM%20-F%20auid%3E%3D1000%20-F%20auid%21%3Dunset%20-F%20key%3Dunsuccessful-modification%0A-a%20always%2Cexit%20-F%20arch%3Db32%20-S%20truncate%2Cftruncate%20-F%20exit%3D-EACCES%20-F%20auid%3E%3D1000%20-F%20auid%21%3Dunset%20-F%20key%3Dunsuccessful-modification%0A-a%20always%2Cexit%20-F%20arch%3Db64%20-S%20truncate%2Cftruncate%20-F%20exit%3D-EACCES%20-F%20auid%3E%3D1000%20-F%20auid%21%3Dunset%20-F%20key%3Dunsuccessful-modification%0A-a%20always%2Cexit%20-F%20arch%3Db32%20-S%20truncate%2Cftruncate%20-F%20exit%3D-EPERM%20-F%20auid%3E%3D1000%20-F%20auid%21%3Dunset%20-F%20key%3Dunsuccessful-modification%0A-a%20always%2Cexit%20-F%20arch%3Db64%20-S%20truncate%2Cftruncate%20-F%20exit%3D-EPERM%20-F%20auid%3E%3D1000%20-F%20auid%21%3Dunset%20-F%20key%3Dunsuccessful-modification%0A%0A%23%23%20Unsuccessful%20file%20access%20%28any%20other%20opens%29%20This%20has%20to%20go%20last.%0A-a%20always%2Cexit%20-F%20arch%3Db32%20-S%20open%2Ccreat%2Ctruncate%2Cftruncate%2Copenat%2Copen_by_handle_at%20-F%20exit%3D-EACCES%20-F%20auid%3E%3D1000%20-F%20auid%21%3Dunset%20-F%20key%3Dunsuccessful-access%0A-a%20always%2Cexit%20-F%20arch%3Db64%20-S%20open%2Ccreat%2Ctruncate%2Cftruncate%2Copenat%2Copen_by_handle_at%20-F%20exit%3D-EACCES%20-F%20auid%3E%3D1000%20-F%20auid%21%3Dunset%20-F%20key%3Dunsuccessful-access%0A-a%20always%2Cexit%20-F%20arch%3Db32%20-S%20open%2Ccreat%2Ctruncate%2Cftruncate%2Copenat%2Copen_by_handle_at%20-F%20exit%3D-EPERM%20-F%20auid%3E%3D1000%20-F%20auid%21%3Dunset%20-F%20key%3Dunsuccessful-access%0A-a%20always%2Cexit%20-F%20arch%3Db64%20-S%20open%2Ccreat%2Ctruncate%2Cftruncate%2Copenat%2Copen_by_handle_at%20-F%20exit%3D-EPERM%20-F%20auid%3E%3D1000%20-F%20auid%21%3Dunset%20-F%20key%3Dunsuccessful-access%0A mode: 0644 path: /etc/audit/rules.d/30-ospp-v42-remediation.rules overwrite: true - contents: source: data:,-w%20/etc/group%20-p%20wa%20-k%20audit_rules_usergroup_modification%0A mode: 0644 path: /etc/audit/rules.d/30-etc_group_usergroup_modification.rules overwrite: true - contents: source: data:,-w%20/etc/gshadow%20-p%20wa%20-k%20audit_rules_usergroup_modification%0A mode: 0644 path: /etc/audit/rules.d/30-etc_gshadow_usergroup_modification.rules overwrite: true - contents: source: data:,-w%20/etc/security/opasswd%20-p%20wa%20-k%20audit_rules_usergroup_modification%0A mode: 0644 path: /etc/audit/rules.d/30-etc_security_opasswd_usergroup_modification.rules overwrite: true - contents: source: data:,-w%20/etc/passwd%20-p%20wa%20-k%20audit_rules_usergroup_modification%0A mode: 0644 path: /etc/audit/rules.d/30-etc_passwd_usergroup_modification.rules overwrite: true - contents: source: data:,-w%20/etc/shadow%20-p%20wa%20-k%20audit_rules_usergroup_modification%0A mode: 0644 path: /etc/audit/rules.d/30-etc_shadow_usergroup_modification.rules overwrite: true " | oc apply -f - done
Verify the Red Hat Enterprise Linux CoreOS (RHCOS) is configured to generate audit records when successful/unsuccessful attempts to modify security categories or objects occur by executing the following: for node in $(oc get node -oname); do oc debug $node -- chroot /host /bin/bash -c 'echo -n "$HOSTNAME "; grep -e "key=privileged" -e "key=perm_mod" /etc/audit/audit.rules' 2>/dev/null; done Confirm the following rules exist on each node: -a always,exit -F arch=b64 -S fremovexattr -F auid>=1000 -F auid!=unset -F key=perm_mod -a always,exit -F arch=b32 -S fsetxattr -F auid>=1000 -F auid!=unset -F key=perm_mod -a always,exit -F arch=b64 -S fsetxattr -F auid>=1000 -F auid!=unset -F key=perm_mod -a always,exit -F arch=b32 -S lremovexattr -F auid>=1000 -F auid!=unset -F key=perm_mod -a always,exit -F arch=b64 -S lremovexattr -F auid>=1000 -F auid!=unset -F key=perm_mod -a always,exit -F arch=b32 -S lsetxattr -F auid>=1000 -F auid!=unset -F key=perm_mod -a always,exit -F arch=b64 -S lsetxattr -F auid>=1000 -F auid!=unset -F key=perm_mod -a always,exit -F arch=b32 -S removexattr -F auid>=1000 -F auid!=unset -F key=perm_mod -a always,exit -F arch=b64 -S removexattr -F auid>=1000 -F auid!=unset -F key=perm_mod -a always,exit -F path=/usr/bin/chcon -F auid>=1000 -F auid!=unset -F key=privileged -a always,exit -F path=/usr/sbin/restorecon -F auid>=1000 -F auid!=unset -F key=privileged -a always,exit -F path=/usr/sbin/semanage -F auid>=1000 -F auid!=unset -F key=privileged -a always,exit -F path=/usr/sbin/setfiles -F auid>=1000 -F auid!=unset -F key=privileged -a always,exit -F path=/usr/sbin/setsebool -F auid>=1000 -F auid!=unset -F key=privileged If the above rules are not listed on each node, this is a finding.
Apply the machine config to configure modification audit records by executing the following: for mcpool in $(oc get mcp -oname | sed "s:.*/::" ); do echo "apiVersion: machineconfiguration.openshift.io/v1 kind: MachineConfig metadata: name: 75-modify-categories-secobjects-rules-$mcpool labels: machineconfiguration.openshift.io/role: $mcpool spec: config: ignition: version: 3.1.0 storage: files: - contents: source: data:,-a%20always%2Cexit%20-F%20arch%3Db32%20-S%20fremovexattr%20-F%20auid%3E%3D1000%20-F%20auid%21%3Dunset%20-F%20key%3Dperm_mod%0A-a%20always%2Cexit%20-F%20arch%3Db64%20-S%20fremovexattr%20-F%20auid%3E%3D1000%20-F%20auid%21%3Dunset%20-F%20key%3Dperm_mod%0A mode: 0644 path: /etc/audit/rules.d/75-fremovexattr_dac_modification.rules overwrite: true - contents: source: data:,-a%20always%2Cexit%20-F%20arch%3Db32%20-S%20fsetxattr%20-F%20auid%3E%3D1000%20-F%20auid%21%3Dunset%20-F%20key%3Dperm_mod%0A-a%20always%2Cexit%20-F%20arch%3Db64%20-S%20fsetxattr%20-F%20auid%3E%3D1000%20-F%20auid%21%3Dunset%20-F%20key%3Dperm_mod%0A mode: 0644 path: /etc/audit/rules.d/75-fsetxattr_dac_modification.rules overwrite: true - contents: source: data:,-a%20always%2Cexit%20-F%20arch%3Db32%20-S%20lremovexattr%20-F%20auid%3E%3D1000%20-F%20auid%21%3Dunset%20-F%20key%3Dperm_mod%0A-a%20always%2Cexit%20-F%20arch%3Db64%20-S%20lremovexattr%20-F%20auid%3E%3D1000%20-F%20auid%21%3Dunset%20-F%20key%3Dperm_mod%0A mode: 0644 path: /etc/audit/rules.d/75-lremovexattr_dac_modification.rules overwrite: true - contents: source: data:,-a%20always%2Cexit%20-F%20arch%3Db32%20-S%20lsetxattr%20-F%20auid%3E%3D1000%20-F%20auid%21%3Dunset%20-F%20key%3Dperm_mod%0A-a%20always%2Cexit%20-F%20arch%3Db64%20-S%20lsetxattr%20-F%20auid%3E%3D1000%20-F%20auid%21%3Dunset%20-F%20key%3Dperm_mod%0A mode: 0644 path: /etc/audit/rules.d/75-lsetxattr_dac_modification.rules overwrite: true - contents: source: data:,-a%20always%2Cexit%20-F%20arch%3Db32%20-S%20removexattr%20-F%20auid%3E%3D1000%20-F%20auid%21%3Dunset%20-F%20key%3Dperm_mod%0A-a%20always%2Cexit%20-F%20arch%3Db64%20-S%20removexattr%20-F%20auid%3E%3D1000%20-F%20auid%21%3Dunset%20-F%20key%3Dperm_mod%0A mode: 0644 path: /etc/audit/rules.d/75-removexattr_dac_modification.rules overwrite: true - contents: source: data:,-a%20always%2Cexit%20-F%20path%3D/usr/bin/chcon%20-F%20auid%3E%3D1000%20-F%20auid%21%3Dunset%20-F%20key%3Dprivileged%0A mode: 0644 path: /etc/audit/rules.d/75-usr_bin_chcon_execution.rules overwrite: true - contents: source: data:,-a%20always%2Cexit%20-F%20path%3D/usr/sbin/restorecon%20-F%20auid%3E%3D1000%20-F%20auid%21%3Dunset%20-F%20key%3Dprivileged%0A mode: 0644 path: /etc/audit/rules.d/75-usr_sbin_restorecon_execution.rules overwrite: true - contents: source: data:,-a%20always%2Cexit%20-F%20path%3D/usr/sbin/semanage%20-F%20auid%3E%3D1000%20-F%20auid%21%3Dunset%20-F%20key%3Dprivileged%0A mode: 0644 path: /etc/audit/rules.d/75-usr_sbin_semanage_execution.rules overwrite: true - contents: source: data:,-a%20always%2Cexit%20-F%20path%3D/usr/sbin/setfiles%20-F%20auid%3E%3D1000%20-F%20auid%21%3Dunset%20-F%20key%3Dprivileged%0A mode: 0644 path: /etc/audit/rules.d/75-usr_sbin_setfiles_execution.rules overwrite: true - contents: source: data:,-a%20always%2Cexit%20-F%20path%3D/usr/sbin/setsebool%20-F%20auid%3E%3D1000%20-F%20auid%21%3Dunset%20-F%20key%3Dprivileged%0A mode: 0644 path: /etc/audit/rules.d/75-usr_sbin_setsebool_execution.rules overwrite: true " | oc apply -f - done
Verify OpenShift is configured to generate audit records when successful/unsuccessful attempts to delete security privileges occur by executing the following: for node in $(oc get node -oname); do oc debug $node -- chroot /host /bin/bash -c 'echo -n "$HOSTNAME "; grep -e "key=delete" -e "key=perm_mod" -e "key=privileged" -e "audit_rules_usergroup_modification" /etc/audit/audit.rules' 2>/dev/null; done Confirm the following rules exist on each node: -w /etc/group -p wa -k audit_rules_usergroup_modification -w /etc/gshadow -p wa -k audit_rules_usergroup_modification -w /etc/passwd -p wa -k audit_rules_usergroup_modification -w /etc/security/opasswd -p wa -k audit_rules_usergroup_modification -w /etc/shadow -p wa -k audit_rules_usergroup_modification -a always,exit -F arch=b32 -S chmod -F auid>=1000 -F auid!=unset -F key=perm_mod -a always,exit -F arch=b64 -S chmod -F auid>=1000 -F auid!=unset -F key=perm_mod -a always,exit -F arch=b32 -S chown -F auid>=1000 -F auid!=unset -F key=perm_mod -a always,exit -F arch=b64 -S chown -F auid>=1000 -F auid!=unset -F key=perm_mod -a always,exit -F arch=b32 -S fchmodat -F auid>=1000 -F auid!=unset -F key=perm_mod -a always,exit -F arch=b64 -S fchmodat -F auid>=1000 -F auid!=unset -F key=perm_mod -a always,exit -F arch=b32 -S fchmod -F auid>=1000 -F auid!=unset -F key=perm_mod -a always,exit -F arch=b64 -S fchmod -F auid>=1000 -F auid!=unset -F key=perm_mod -a always,exit -F arch=b32 -S fchownat -F auid>=1000 -F auid!=unset -F key=perm_mod -a always,exit -F arch=b64 -S fchownat -F auid>=1000 -F auid!=unset -F key=perm_mod -a always,exit -F arch=b32 -S fchown -F auid>=1000 -F auid!=unset -F key=perm_mod -a always,exit -F arch=b64 -S fchown -F auid>=1000 -F auid!=unset -F key=perm_mod -a always,exit -F arch=b32 -S fremovexattr -F auid>=1000 -F auid!=unset -F key=perm_mod -a always,exit -F arch=b64 -S fremovexattr -F auid>=1000 -F auid!=unset -F key=perm_mod -a always,exit -F arch=b32 -S fsetxattr -F auid>=1000 -F auid!=unset -F key=perm_mod -a always,exit -F arch=b64 -S fsetxattr -F auid>=1000 -F auid!=unset -F key=perm_mod -a always,exit -F arch=b32 -S lchown -F auid>=1000 -F auid!=unset -F key=perm_mod -a always,exit -F arch=b64 -S lchown -F auid>=1000 -F auid!=unset -F key=perm_mod -a always,exit -F arch=b32 -S lremovexattr -F auid>=1000 -F auid!=unset -F key=perm_mod -a always,exit -F arch=b64 -S lremovexattr -F auid>=1000 -F auid!=unset -F key=perm_mod -a always,exit -F arch=b32 -S lsetxattr -F auid>=1000 -F auid!=unset -F key=perm_mod -a always,exit -F arch=b64 -S lsetxattr -F auid>=1000 -F auid!=unset -F key=perm_mod -a always,exit -F arch=b32 -S mount -F auid>=1000 -F auid!=unset -F key=perm_mod -a always,exit -F arch=b64 -S mount -F auid>=1000 -F auid!=unset -F key=perm_mod -a always,exit -F arch=b32 -S removexattr -F auid>=1000 -F auid!=unset -F key=perm_mod -a always,exit -F arch=b64 -S removexattr -F auid>=1000 -F auid!=unset -F key=perm_mod -a always,exit -F arch=b32 -S renameat -F auid>=1000 -F auid!=unset -F key=delete -a always,exit -F arch=b64 -S renameat -F auid>=1000 -F auid!=unset -F key=delete -a always,exit -F arch=b32 -S rename -F auid>=1000 -F auid!=unset -F key=delete -a always,exit -F arch=b64 -S rename -F auid>=1000 -F auid!=unset -F key=delete -a always,exit -F arch=b32 -S rmdir -F auid>=1000 -F auid!=unset -F key=delete -a always,exit -F arch=b64 -S rmdir -F auid>=1000 -F auid!=unset -F key=delete -a always,exit -F arch=b32 -S setxattr -F auid>=1000 -F auid!=unset -F key=perm_mod -a always,exit -F arch=b64 -S setxattr -F auid>=1000 -F auid!=unset -F key=perm_mod -a always,exit -F arch=b32 -S umount2 -F auid>=1000 -F auid!=unset -F key=perm_mod -a always,exit -F arch=b64 -S umount2 -F auid>=1000 -F auid!=unset -F key=perm_mod -a always,exit -F arch=b32 -S unlinkat -F auid>=1000 -F auid!=unset -F key=delete -a always,exit -F arch=b64 -S unlinkat -F auid>=1000 -F auid!=unset -F key=delete -a always,exit -F arch=b32 -S unlink -F auid>=1000 -F auid!=unset -F key=delete -a always,exit -F arch=b64 -S unlink -F auid>=1000 -F auid!=unset -F key=delete -a always,exit -F path=/usr/bin/chage -F auid>=1000 -F auid!=unset -F key=privileged -a always,exit -F path=/usr/bin/chcon -F auid>=1000 -F auid!=unset -F key=privileged -a always,exit -F path=/usr/bin/chsh -F auid>=1000 -F auid!=unset -F key=privileged -a always,exit -F path=/usr/bin/crontab -F auid>=1000 -F auid!=unset -F key=privileged -a always,exit -F path=/usr/bin/gpasswd -F auid>=1000 -F auid!=unset -F key=privileged -a always,exit -F path=/usr/bin/newgrp -F auid>=1000 -F auid!=unset -F key=privileged -a always,exit -F path=/usr/bin/passwd -F auid>=1000 -F auid!=unset -F key=privileged -a always,exit -F path=/usr/bin/sudoedit -F auid>=1000 -F auid!=unset -F key=privileged -a always,exit -F path=/usr/bin/sudo -F auid>=1000 -F auid!=unset -F key=privileged -a always,exit -F path=/usr/bin/su -F auid>=1000 -F auid!=unset -F key=privileged -a always,exit -F path=/usr/bin/umount -F auid>=1000 -F auid!=unset -F key=privileged -a always,exit -F path=/usr/libexec/openssh/ssh-keysign -F auid>=1000 -F auid!=unset -F key=privileged -a always,exit -F path=/usr/libexec/pt_chown -F auid>=1000 -F auid!=unset -F key=privileged -a always,exit -F path=/usr/sbin/pam_timestamp_check -F auid>=1000 -F auid!=unset -F key=privileged -a always,exit -F path=/usr/sbin/postdrop -F auid>=1000 -F auid!=unset -F key=privileged -a always,exit -F path=/usr/sbin/postqueue -F auid>=1000 -F auid!=unset -F key=privileged -a always,exit -F path=/usr/sbin/semanage -F auid>=1000 -F auid!=unset -F key=privileged -a always,exit -F path=/usr/sbin/setfiles -F auid>=1000 -F auid!=unset -F key=privileged -a always,exit -F path=/usr/sbin/setsebool -F auid>=1000 -F auid!=unset -F key=privileged -a always,exit -F path=/usr/sbin/unix_chkpwd -F auid>=1000 -F auid!=unset -F key=privileged -a always,exit -F path=/usr/sbin/userhelper -F auid>=1000 -F auid!=unset -F key=privileged If the above rules are not listed on each node, this is a finding.
Apply the machine config to generate audit records when successful/unsuccessful attempts to delete security privileges by executing the following: for mcpool in $(oc get mcp -oname | sed "s:.*/::" ); do echo "apiVersion: machineconfiguration.openshift.io/v1 kind: MachineConfig metadata: name: 75-delete-privileges-rules-$mcpool labels: machineconfiguration.openshift.io/role: $mcpool spec: config: ignition: version: 3.1.0 storage: files: - contents: source: data:,-a%20always%2Cexit%20-F%20arch%3Db32%20-S%20chmod%20-F%20auid%3E%3D1000%20-F%20auid%21%3Dunset%20-F%20key%3Dperm_mod%0A-a%20always%2Cexit%20-F%20arch%3Db64%20-S%20chmod%20-F%20auid%3E%3D1000%20-F%20auid%21%3Dunset%20-F%20key%3Dperm_mod%0A mode: 0644 path: /etc/audit/rules.d/75-chmod_dac_modification.rules overwrite: true - contents: source: data:,-a%20always%2Cexit%20-F%20arch%3Db32%20-S%20chown%20-F%20auid%3E%3D1000%20-F%20auid%21%3Dunset%20-F%20key%3Dperm_mod%0A-a%20always%2Cexit%20-F%20arch%3Db64%20-S%20chown%20-F%20auid%3E%3D1000%20-F%20auid%21%3Dunset%20-F%20key%3Dperm_mod%0A mode: 0644 path: /etc/audit/rules.d/75-chown_dac_modification.rules overwrite: true - contents: source: data:,-a%20always%2Cexit%20-F%20arch%3Db32%20-S%20fchmod%20-F%20auid%3E%3D1000%20-F%20auid%21%3Dunset%20-F%20key%3Dperm_mod%0A-a%20always%2Cexit%20-F%20arch%3Db64%20-S%20fchmod%20-F%20auid%3E%3D1000%20-F%20auid%21%3Dunset%20-F%20key%3Dperm_mod%0A mode: 0644 path: /etc/audit/rules.d/75-fchmod_dac_modification.rules overwrite: true - contents: source: data:,-a%20always%2Cexit%20-F%20arch%3Db32%20-S%20fchmodat%20-F%20auid%3E%3D1000%20-F%20auid%21%3Dunset%20-F%20key%3Dperm_mod%0A-a%20always%2Cexit%20-F%20arch%3Db64%20-S%20fchmodat%20-F%20auid%3E%3D1000%20-F%20auid%21%3Dunset%20-F%20key%3Dperm_mod%0A mode: 0644 path: /etc/audit/rules.d/75-fchmodat_dac_modification.rules overwrite: true - contents: source: data:,-a%20always%2Cexit%20-F%20arch%3Db32%20-S%20fchown%20-F%20auid%3E%3D1000%20-F%20auid%21%3Dunset%20-F%20key%3Dperm_mod%0A-a%20always%2Cexit%20-F%20arch%3Db64%20-S%20fchown%20-F%20auid%3E%3D1000%20-F%20auid%21%3Dunset%20-F%20key%3Dperm_mod%0A mode: 0644 path: /etc/audit/rules.d/75-fchown_dac_modification.rules overwrite: true - contents: source: data:,-a%20always%2Cexit%20-F%20arch%3Db32%20-S%20fchownat%20-F%20auid%3E%3D1000%20-F%20auid%21%3Dunset%20-F%20key%3Dperm_mod%0A-a%20always%2Cexit%20-F%20arch%3Db64%20-S%20fchownat%20-F%20auid%3E%3D1000%20-F%20auid%21%3Dunset%20-F%20key%3Dperm_mod%0A mode: 0644 path: /etc/audit/rules.d/75-fchownat_dac_modification.rules overwrite: true - contents: source: data:,-a%20always%2Cexit%20-F%20arch%3Db32%20-S%20fremovexattr%20-F%20auid%3E%3D1000%20-F%20auid%21%3Dunset%20-F%20key%3Dperm_mod%0A-a%20always%2Cexit%20-F%20arch%3Db64%20-S%20fremovexattr%20-F%20auid%3E%3D1000%20-F%20auid%21%3Dunset%20-F%20key%3Dperm_mod%0A mode: 0644 path: /etc/audit/rules.d/75-fremovexattr_dac_modification.rules overwrite: true - contents: source: data:,-a%20always%2Cexit%20-F%20arch%3Db32%20-S%20lchown%20-F%20auid%3E%3D1000%20-F%20auid%21%3Dunset%20-F%20key%3Dperm_mod%0A-a%20always%2Cexit%20-F%20arch%3Db64%20-S%20lchown%20-F%20auid%3E%3D1000%20-F%20auid%21%3Dunset%20-F%20key%3Dperm_mod%0A mode: 0644 path: /etc/audit/rules.d/75-lchown_dac_modification.rules overwrite: true - contents: source: data:,-a%20always%2Cexit%20-F%20arch%3Db32%20-S%20lremovexattr%20-F%20auid%3E%3D1000%20-F%20auid%21%3Dunset%20-F%20key%3Dperm_mod%0A-a%20always%2Cexit%20-F%20arch%3Db64%20-S%20lremovexattr%20-F%20auid%3E%3D1000%20-F%20auid%21%3Dunset%20-F%20key%3Dperm_mod%0A mode: 0644 path: /etc/audit/rules.d/75-lremovexattr_dac_modification.rules overwrite: true - contents: source: data:,-a%20always%2Cexit%20-F%20arch%3Db32%20-S%20removexattr%20-F%20auid%3E%3D1000%20-F%20auid%21%3Dunset%20-F%20key%3Dperm_mod%0A-a%20always%2Cexit%20-F%20arch%3Db64%20-S%20removexattr%20-F%20auid%3E%3D1000%20-F%20auid%21%3Dunset%20-F%20key%3Dperm_mod%0A mode: 0644 path: /etc/audit/rules.d/75-removexattr_dac_modification.rules overwrite: true - contents: source: data:,-a%20always%2Cexit%20-F%20arch%3Db32%20-S%20rename%20-F%20auid%3E%3D1000%20-F%20auid%21%3Dunset%20-F%20key%3Ddelete%0A-a%20always%2Cexit%20-F%20arch%3Db64%20-S%20rename%20-F%20auid%3E%3D1000%20-F%20auid%21%3Dunset%20-F%20key%3Ddelete%0A mode: 0644 path: /etc/audit/rules.d/75-rename-file-deletion-events.rules overwrite: true - contents: source: data:,-a%20always%2Cexit%20-F%20arch%3Db32%20-S%20renameat%20-F%20auid%3E%3D1000%20-F%20auid%21%3Dunset%20-F%20key%3Ddelete%0A-a%20always%2Cexit%20-F%20arch%3Db64%20-S%20renameat%20-F%20auid%3E%3D1000%20-F%20auid%21%3Dunset%20-F%20key%3Ddelete%0A mode: 0644 path: /etc/audit/rules.d/75-renameat-file-deletion-events.rules overwrite: true - contents: source: data:,-a%20always%2Cexit%20-F%20arch%3Db32%20-S%20rmdir%20-F%20auid%3E%3D1000%20-F%20auid%21%3Dunset%20-F%20key%3Ddelete%0A-a%20always%2Cexit%20-F%20arch%3Db64%20-S%20rmdir%20-F%20auid%3E%3D1000%20-F%20auid%21%3Dunset%20-F%20key%3Ddelete%0A mode: 0644 path: /etc/audit/rules.d/75-rmdir-file-deletion-events.rules overwrite: true - contents: source: data:,-a%20always%2Cexit%20-F%20arch%3Db32%20-S%20unlink%20-F%20auid%3E%3D1000%20-F%20auid%21%3Dunset%20-F%20key%3Ddelete%0A-a%20always%2Cexit%20-F%20arch%3Db64%20-S%20unlink%20-F%20auid%3E%3D1000%20-F%20auid%21%3Dunset%20-F%20key%3Ddelete%0A mode: 0644 path: /etc/audit/rules.d/75-unlink-file-deletion-events.rules overwrite: true - contents: source: data:,-a%20always%2Cexit%20-F%20arch%3Db32%20-S%20unlinkat%20-F%20auid%3E%3D1000%20-F%20auid%21%3Dunset%20-F%20key%3Ddelete%0A-a%20always%2Cexit%20-F%20arch%3Db64%20-S%20unlinkat%20-F%20auid%3E%3D1000%20-F%20auid%21%3Dunset%20-F%20key%3Ddelete%0A mode: 0644 path: /etc/audit/rules.d/75-unlinkat-file-deletion-events.rules overwrite: true - contents: source: data:,-a%20always%2Cexit%20-F%20path%3D/usr/bin/su%20-F%20auid%3E%3D1000%20-F%20auid%21%3Dunset%20-F%20key%3Dprivileged%0A mode: 0644 path: /etc/audit/rules.d/75-usr_bin_su_execution.rules overwrite: true - contents: source: data:,-a%20always%2Cexit%20-F%20path%3D/usr/bin/sudo%20-F%20auid%3E%3D1000%20-F%20auid%21%3Dunset%20-F%20key%3Dprivileged%0A mode: 0644 path: /etc/audit/rules.d/75-usr_bin_sudo_execution.rules overwrite: true - contents: source: data:,-w%20/etc/sudoers.d/%20-p%20wa%20-k%20actions%0A-w%20/etc/sudoers%20-p%20wa%20-k%20actions%0A mode: 0644 path: /etc/audit/rules.d/75-audit-sysadmin-actions.rules overwrite: true - contents: source: data:,-w%20/etc/group%20-p%20wa%20-k%20audit_rules_usergroup_modification%0A mode: 0644 path: /etc/audit/rules.d/30-etc_group_usergroup_modification.rules overwrite: true - contents: source: data:,-w%20/etc/gshadow%20-p%20wa%20-k%20audit_rules_usergroup_modification%0A mode: 0644 path: /etc/audit/rules.d/30-etc_gshadow_usergroup_modification.rules overwrite: true - contents: source: data:,-w%20/etc/passwd%20-p%20wa%20-k%20audit_rules_usergroup_modification%0A mode: 0644 path: /etc/audit/rules.d/30-etc_passwd_usergroup_modification.rules overwrite: true - contents: source: data:,-w%20/etc/shadow%20-p%20wa%20-k%20audit_rules_usergroup_modification%0A mode: 0644 path: /etc/audit/rules.d/30-etc_shadow_usergroup_modification.rules overwrite: true " | oc apply -f - done
Verify the Red Hat Enterprise Linux CoreOS (RHCOS) is configured to generate audit records when successful/unsuccessful attempts to delete security objects or categories of information occur by executing the following: for node in $(oc get node -oname); do oc debug $node -- chroot /host /bin/bash -c 'echo -n "$HOSTNAME "; grep -e "key=access" -e "key=delete" -e "key=unsuccessful-delete" -e "key=privileged" -e "key=perm_mod" /etc/audit/audit.rules' 2>/dev/null; done Confirm the following rules exist on each node: -a always,exit -F arch=b32 -S unlink,unlinkat,rename,renameat -F exit=-EACCES -F auid>=1000 -F auid!=unset -F key=unsuccessful-delete -a always,exit -F arch=b64 -S unlink,unlinkat,rename,renameat -F exit=-EACCES -F auid>=1000 -F auid!=unset -F key=unsuccessful-delete -a always,exit -F arch=b32 -S unlink,unlinkat,rename,renameat -F exit=-EPERM -F auid>=1000 -F auid!=unset -F key=unsuccessful-delete -a always,exit -F arch=b64 -S unlink,unlinkat,rename,renameat -F exit=-EPERM -F auid>=1000 -F auid!=unset -F key=unsuccessful-delete -a always,exit -F arch=b32 -S chmod -F auid>=1000 -F auid!=unset -F key=perm_mod -a always,exit -F arch=b64 -S chmod -F auid>=1000 -F auid!=unset -F key=perm_mod -a always,exit -F arch=b32 -S chown -F auid>=1000 -F auid!=unset -F key=perm_mod -a always,exit -F arch=b64 -S chown -F auid>=1000 -F auid!=unset -F key=perm_mod -a always,exit -F arch=b32 -S fchmodat -F auid>=1000 -F auid!=unset -F key=perm_mod -a always,exit -F arch=b64 -S fchmodat -F auid>=1000 -F auid!=unset -F key=perm_mod -a always,exit -F arch=b32 -S fchmod -F auid>=1000 -F auid!=unset -F key=perm_mod -a always,exit -F arch=b64 -S fchmod -F auid>=1000 -F auid!=unset -F key=perm_mod -a always,exit -F arch=b32 -S fchownat -F auid>=1000 -F auid!=unset -F key=perm_mod -a always,exit -F arch=b64 -S fchownat -F auid>=1000 -F auid!=unset -F key=perm_mod -a always,exit -F arch=b32 -S fchown -F auid>=1000 -F auid!=unset -F key=perm_mod -a always,exit -F arch=b64 -S fchown -F auid>=1000 -F auid!=unset -F key=perm_mod -a always,exit -F arch=b32 -S fremovexattr -F auid>=1000 -F auid!=unset -F key=perm_mod -a always,exit -F arch=b64 -S fremovexattr -F auid>=1000 -F auid!=unset -F key=perm_mod -a always,exit -F arch=b32 -S fsetxattr -F auid>=1000 -F auid!=unset -F key=perm_mod -a always,exit -F arch=b64 -S fsetxattr -F auid>=1000 -F auid!=unset -F key=perm_mod -a always,exit -F arch=b32 -S lchown -F auid>=1000 -F auid!=unset -F key=perm_mod -a always,exit -F arch=b64 -S lchown -F auid>=1000 -F auid!=unset -F key=perm_mod -a always,exit -F arch=b32 -S lremovexattr -F auid>=1000 -F auid!=unset -F key=perm_mod -a always,exit -F arch=b64 -S lremovexattr -F auid>=1000 -F auid!=unset -F key=perm_mod -a always,exit -F arch=b32 -S lsetxattr -F auid>=1000 -F auid!=unset -F key=perm_mod -a always,exit -F arch=b64 -S lsetxattr -F auid>=1000 -F auid!=unset -F key=perm_mod -a always,exit -F arch=b32 -S mount -F auid>=1000 -F auid!=unset -F key=perm_mod -a always,exit -F arch=b64 -S mount -F auid>=1000 -F auid!=unset -F key=perm_mod -a always,exit -F arch=b32 -S removexattr -F auid>=1000 -F auid!=unset -F key=perm_mod -a always,exit -F arch=b64 -S removexattr -F auid>=1000 -F auid!=unset -F key=perm_mod -a always,exit -F arch=b32 -S renameat -F auid>=1000 -F auid!=unset -F key=delete -a always,exit -F arch=b64 -S renameat -F auid>=1000 -F auid!=unset -F key=delete -a always,exit -F arch=b64 -S renameat -F exit=-EACCES -F auid>=1000 -F auid!=unset -F key=access -a always,exit -F arch=b64 -S renameat -F exit=-EPERM -F auid>=1000 -F auid!=unset -F key=access -a always,exit -F arch=b32 -S renameat -F exit=-EACCES -F auid>=1000 -F auid!=unset -F key=access -a always,exit -F arch=b32 -S renameat -F exit=-EPERM -F auid>=1000 -F auid!=unset -F key=access -a always,exit -F arch=b32 -S rename -F auid>=1000 -F auid!=unset -F key=delete -a always,exit -F arch=b64 -S rename -F auid>=1000 -F auid!=unset -F key=delete -a always,exit -F arch=b64 -S rename -F exit=-EACCES -F auid>=1000 -F auid!=unset -F key=access -a always,exit -F arch=b64 -S rename -F exit=-EPERM -F auid>=1000 -F auid!=unset -F key=access -a always,exit -F arch=b32 -S rename -F exit=-EACCES -F auid>=1000 -F auid!=unset -F key=access -a always,exit -F arch=b32 -S rename -F exit=-EPERM -F auid>=1000 -F auid!=unset -F key=access -a always,exit -F arch=b32 -S rmdir -F auid>=1000 -F auid!=unset -F key=delete -a always,exit -F arch=b64 -S rmdir -F auid>=1000 -F auid!=unset -F key=delete -a always,exit -F arch=b32 -S setxattr -F auid>=1000 -F auid!=unset -F key=perm_mod -a always,exit -F arch=b64 -S setxattr -F auid>=1000 -F auid!=unset -F key=perm_mod -a always,exit -F arch=b32 -S umount2 -F auid>=1000 -F auid!=unset -F key=perm_mod -a always,exit -F arch=b64 -S umount2 -F auid>=1000 -F auid!=unset -F key=perm_mod -a always,exit -F arch=b32 -S unlinkat -F auid>=1000 -F auid!=unset -F key=delete -a always,exit -F arch=b64 -S unlinkat -F auid>=1000 -F auid!=unset -F key=delete -a always,exit -F arch=b64 -S unlinkat -F exit=-EACCES -F auid>=1000 -F auid!=unset -F key=access -a always,exit -F arch=b64 -S unlinkat -F exit=-EPERM -F auid>=1000 -F auid!=unset -F key=access -a always,exit -F arch=b32 -S unlinkat -F exit=-EACCES -F auid>=1000 -F auid!=unset -F key=access -a always,exit -F arch=b32 -S unlinkat -F exit=-EPERM -F auid>=1000 -F auid!=unset -F key=access -a always,exit -F arch=b32 -S unlink -F auid>=1000 -F auid!=unset -F key=delete -a always,exit -F arch=b64 -S unlink -F auid>=1000 -F auid!=unset -F key=delete -a always,exit -F arch=b64 -S unlink -F exit=-EACCES -F auid>=1000 -F auid!=unset -F key=access -a always,exit -F arch=b64 -S unlink -F exit=-EPERM -F auid>=1000 -F auid!=unset -F key=access -a always,exit -F arch=b32 -S unlink -F exit=-EACCES -F auid>=1000 -F auid!=unset -F key=access -a always,exit -F arch=b32 -S unlink -F exit=-EPERM -F auid>=1000 -F auid!=unset -F key=access -a always,exit -F path=/usr/bin/chage -F auid>=1000 -F auid!=unset -F key=privileged -a always,exit -F path=/usr/bin/chcon -F auid>=1000 -F auid!=unset -F key=privileged -a always,exit -F path=/usr/bin/chsh -F auid>=1000 -F auid!=unset -F key=privileged -a always,exit -F path=/usr/bin/crontab -F auid>=1000 -F auid!=unset -F key=privileged -a always,exit -F path=/usr/bin/gpasswd -F auid>=1000 -F auid!=unset -F key=privileged -a always,exit -F path=/usr/bin/newgrp -F auid>=1000 -F auid!=unset -F key=privileged -a always,exit -F path=/usr/bin/passwd -F auid>=1000 -F auid!=unset -F key=privileged -a always,exit -F path=/usr/bin/sudoedit -F auid>=1000 -F auid!=unset -F key=privileged -a always,exit -F path=/usr/bin/sudo -F auid>=1000 -F auid!=unset -F key=privileged -a always,exit -F path=/usr/bin/su -F auid>=1000 -F auid!=unset -F key=privileged -a always,exit -F path=/usr/bin/umount -F auid>=1000 -F auid!=unset -F key=privileged -a always,exit -F path=/usr/libexec/openssh/ssh-keysign -F auid>=1000 -F auid!=unset -F key=privileged -a always,exit -F path=/usr/libexec/pt_chown -F auid>=1000 -F auid!=unset -F key=privileged -a always,exit -F path=/usr/sbin/pam_timestamp_check -F auid>=1000 -F auid!=unset -F key=privileged -a always,exit -F path=/usr/sbin/postdrop -F auid>=1000 -F auid!=unset -F key=privileged -a always,exit -F path=/usr/sbin/postqueue -F auid>=1000 -F auid!=unset -F key=privileged -a always,exit -F path=/usr/sbin/semanage -F auid>=1000 -F auid!=unset -F key=privileged -a always,exit -F path=/usr/sbin/setfiles -F auid>=1000 -F auid!=unset -F key=privileged -a always,exit -F path=/usr/sbin/setsebool -F auid>=1000 -F auid!=unset -F key=privileged -a always,exit -F path=/usr/sbin/unix_chkpwd -F auid>=1000 -F auid!=unset -F key=privileged -a always,exit -F path=/usr/sbin/userhelper -F auid>=1000 -F auid!=unset -F key=privileged If the above rules are not listed on each node, this is a finding.
Apply the machine config to generate audit records when security objects or categories are deleted by executing the following: for mcpool in $(oc get mcp -oname | sed "s:.*/::" ); do echo "apiVersion: machineconfiguration.openshift.io/v1 kind: MachineConfig metadata: name: 75-delete-sec-objects-levels-rules-$mcpool labels: machineconfiguration.openshift.io/role: $mcpool spec: config: ignition: version: 3.1.0 storage: files: - contents: source: data:,%23%23%20Unsuccessful%20file%20delete%0A-a%20always%2Cexit%20-F%20arch%3Db32%20-S%20unlink%2Cunlinkat%2Crename%2Crenameat%20-F%20exit%3D-EACCES%20-F%20auid%3E%3D1000%20-F%20auid%21%3Dunset%20-F%20key%3Dunsuccessful-delete%0A-a%20always%2Cexit%20-F%20arch%3Db64%20-S%20unlink%2Cunlinkat%2Crename%2Crenameat%20-F%20exit%3D-EACCES%20-F%20auid%3E%3D1000%20-F%20auid%21%3Dunset%20-F%20key%3Dunsuccessful-delete%0A-a%20always%2Cexit%20-F%20arch%3Db32%20-S%20unlink%2Cunlinkat%2Crename%2Crenameat%20-F%20exit%3D-EPERM%20-F%20auid%3E%3D1000%20-F%20auid%21%3Dunset%20-F%20key%3Dunsuccessful-delete%0A-a%20always%2Cexit%20-F%20arch%3Db64%20-S%20unlink%2Cunlinkat%2Crename%2Crenameat%20-F%20exit%3D-EPERM%20-F%20auid%3E%3D1000%20-F%20auid%21%3Dunset%20-F%20key%3Dunsuccessful-delete%0A mode: 0644 path: /etc/audit/rules.d/30-ospp-v42-4-delete-failed.rules overwrite: true - contents: source: data:,-a%20always%2Cexit%20-F%20arch%3Db32%20-S%20fsetxattr%20-F%20auid%3E%3D1000%20-F%20auid%21%3Dunset%20-F%20key%3Dperm_mod%0A-a%20always%2Cexit%20-F%20arch%3Db64%20-S%20fsetxattr%20-F%20auid%3E%3D1000%20-F%20auid%21%3Dunset%20-F%20key%3Dperm_mod%0A mode: 0644 path: /etc/audit/rules.d/75-fsetxattr_dac_modification.rules overwrite: true - contents: source: data:,-a%20always%2Cexit%20-F%20arch%3Db32%20-S%20lremovexattr%20-F%20auid%3E%3D1000%20-F%20auid%21%3Dunset%20-F%20key%3Dperm_mod%0A-a%20always%2Cexit%20-F%20arch%3Db64%20-S%20lremovexattr%20-F%20auid%3E%3D1000%20-F%20auid%21%3Dunset%20-F%20key%3Dperm_mod%0A mode: 0644 path: /etc/audit/rules.d/75-lremovexattr_dac_modification.rules overwrite: true - contents: source: data:,-a%20always%2Cexit%20-F%20arch%3Db32%20-S%20lsetxattr%20-F%20auid%3E%3D1000%20-F%20auid%21%3Dunset%20-F%20key%3Dperm_mod%0A-a%20always%2Cexit%20-F%20arch%3Db64%20-S%20lsetxattr%20-F%20auid%3E%3D1000%20-F%20auid%21%3Dunset%20-F%20key%3Dperm_mod%0A mode: 0644 path: /etc/audit/rules.d/75-lsetxattr_dac_modification.rules overwrite: true - contents: source: data:,-a%20always%2Cexit%20-F%20arch%3Db32%20-S%20removexattr%20-F%20auid%3E%3D1000%20-F%20auid%21%3Dunset%20-F%20key%3Dperm_mod%0A-a%20always%2Cexit%20-F%20arch%3Db64%20-S%20removexattr%20-F%20auid%3E%3D1000%20-F%20auid%21%3Dunset%20-F%20key%3Dperm_mod%0A mode: 0644 path: /etc/audit/rules.d/75-removexattr_dac_modification.rules overwrite: true - contents: source: data:,-a%20always%2Cexit%20-F%20path%3D/usr/bin/chcon%20-F%20auid%3E%3D1000%20-F%20auid%21%3Dunset%20-F%20key%3Dprivileged%0A mode: 0644 path: /etc/audit/rules.d/75-usr_bin_chcon_execution.rules overwrite: true - contents: source: data:,-a%20always%2Cexit%20-F%20arch%3Db32%20-S%20rename%20-F%20auid%3E%3D1000%20-F%20auid%21%3Dunset%20-F%20key%3Ddelete%0A-a%20always%2Cexit%20-F%20arch%3Db64%20-S%20rename%20-F%20auid%3E%3D1000%20-F%20auid%21%3Dunset%20-F%20key%3Ddelete%0A mode: 0644 path: /etc/audit/rules.d/75-rename-file-deletion-events.rules overwrite: true - contents: source: data:,-a%20always%2Cexit%20-F%20arch%3Db32%20-S%20renameat%20-F%20auid%3E%3D1000%20-F%20auid%21%3Dunset%20-F%20key%3Ddelete%0A-a%20always%2Cexit%20-F%20arch%3Db64%20-S%20renameat%20-F%20auid%3E%3D1000%20-F%20auid%21%3Dunset%20-F%20key%3Ddelete%0A mode: 0644 path: /etc/audit/rules.d/75-renameat-file-deletion-events.rules overwrite: true - contents: source: data:,-a%20always%2Cexit%20-F%20arch%3Db32%20-S%20rmdir%20-F%20auid%3E%3D1000%20-F%20auid%21%3Dunset%20-F%20key%3Ddelete%0A-a%20always%2Cexit%20-F%20arch%3Db64%20-S%20rmdir%20-F%20auid%3E%3D1000%20-F%20auid%21%3Dunset%20-F%20key%3Ddelete%0A mode: 0644 path: /etc/audit/rules.d/75-rmdir-file-deletion-events.rules overwrite: true - contents: source: data:,-a%20always%2Cexit%20-F%20arch%3Db32%20-S%20unlink%20-F%20auid%3E%3D1000%20-F%20auid%21%3Dunset%20-F%20key%3Ddelete%0A-a%20always%2Cexit%20-F%20arch%3Db64%20-S%20unlink%20-F%20auid%3E%3D1000%20-F%20auid%21%3Dunset%20-F%20key%3Ddelete%0A mode: 0644 path: /etc/audit/rules.d/75-unlink-file-deletion-events.rules overwrite: true - contents: source: data:,-a%20always%2Cexit%20-F%20arch%3Db32%20-S%20unlinkat%20-F%20auid%3E%3D1000%20-F%20auid%21%3Dunset%20-F%20key%3Ddelete%0A-a%20always%2Cexit%20-F%20arch%3Db64%20-S%20unlinkat%20-F%20auid%3E%3D1000%20-F%20auid%21%3Dunset%20-F%20key%3Ddelete%0A mode: 0644 path: /etc/audit/rules.d/75-unlinkat-file-deletion-events.rules overwrite: true - contents: source: data:,-a%20always%2Cexit%20-F%20path%3D/usr/bin/chage%20-F%20auid%3E%3D1000%20-F%20auid%21%3Dunset%20-F%20key%3Dprivileged%0A mode: 0644 path: /etc/audit/rules.d/75-usr_bin_chage_execution.rules overwrite: true " ; done | oc apply -f -
Verify that logons are audited by executing the following: for node in $(oc get node -oname); do oc debug $node -- chroot /host /bin/bash -c 'echo -n ""$HOSTNAME ""; grep ""logins"" /etc/audit/audit.rules /etc/audit/rules.d/*' 2>/dev/null; done The output will look similar to: node-name /etc/audit/<file>:-w /var/run/faillock -p wa -k logins /etc/audit/<file>:-w /var/log/lastlog -p wa -k logins If the two rules above are not found on each node, this is a finding.
Apply the machine config to audit logons by executing the following: for mcpool in $(oc get mcp -oname | sed "s:.*/::" ); do echo "apiVersion: machineconfiguration.openshift.io/v1 kind: MachineConfig metadata: name: 75-logon-attempts-rules-$mcpool labels: machineconfiguration.openshift.io/role: $mcpool spec: config: ignition: version: 3.1.0 storage: files: - contents: source: data:,-w%20/var/run/faillock%20-p%20wa%20-k%20logins%0A mode: 0644 path: /etc/audit/rules.d/75-faillock_login_events.rules overwrite: true - contents: source: data:,-w%20/var/log/lastlog%20-p%20wa%20-k%20logins%0A mode: 0644 path: /etc/audit/rules.d/75-lastlog_login_events.rules overwrite: true - contents: source: data:,-w%20/etc/sudoers.d/%20-p%20wa%20-k%20actions%0A-w%20/etc/sudoers%20-p%20wa%20-k%20actions%0A mode: 0644 path: /etc/audit/rules.d/75-audit-sysadmin-actions.rules overwrite: true - contents: source: data:,-w%20/etc/group%20-p%20wa%20-k%20audit_rules_usergroup_modification%0A mode: 0644 path: /etc/audit/rules.d/30-etc_group_usergroup_modification.rules overwrite: true - contents: source: data:,-w%20/etc/gshadow%20-p%20wa%20-k%20audit_rules_usergroup_modification%0A mode: 0644 path: /etc/audit/rules.d/30-etc_gshadow_usergroup_modification.rules overwrite: true - contents: source: data:,-w%20/etc/security/opasswd%20-p%20wa%20-k%20audit_rules_usergroup_modification%0A mode: 0644 path: /etc/audit/rules.d/30-etc_security_opasswd_usergroup_modification.rules overwrite: true - contents: source: data:,-w%20/etc/passwd%20-p%20wa%20-k%20audit_rules_usergroup_modification%0A mode: 0644 path: /etc/audit/rules.d/30-etc_passwd_usergroup_modification.rules overwrite: true - contents: source: data:,-w%20/etc/shadow%20-p%20wa%20-k%20audit_rules_usergroup_modification%0A mode: 0644 path: /etc/audit/rules.d/30-etc_shadow_usergroup_modification.rules overwrite: true " | oc apply -f - done
Verify the audit rules capture loading and unloading of kernel modules by executing the following: for node in $(oc get node -oname); do oc debug $node -- chroot /host /bin/bash -c 'echo -n "$HOSTNAME "; grep -e module-load -e module-unload -e module-change /etc/audit/rules.d/* /etc/audit/audit.rules' 2>/dev/null; done Confirm the following rules exist on each node. -a always,exit -F arch=b32 -S init_module,finit_module -F key=module-load -a always,exit -F arch=b64 -S init_module,finit_module -F key=module-load -a always,exit -F arch=b32 -S delete_module -F key=module-unload -a always,exit -F arch=b64 -S delete_module -F key=module-unload -a always,exit -F arch=b32 -S delete_module -k module-change -a always,exit -F arch=b64 -S delete_module -k module-change -a always,exit -F arch=b32 -S finit_module -k module-change -a always,exit -F arch=b64 -S finit_module -k module-change -a always,exit -F arch=b32 -S init_module -k module-change -a always,exit -F arch=b64 -S init_module -k module-change If the above rules are not listed for each node, this is a finding.
Apply the machine config for audit rules capture by executing the following: for mcpool in $(oc get mcp -oname | sed "s:.*/::" ); do echo "apiVersion: machineconfiguration.openshift.io/v1 kind: MachineConfig metadata: name: 75-kernel-modules-rules-$mcpool labels: machineconfiguration.openshift.io/role: $mcpool spec: config: ignition: version: 3.1.0 storage: files: - contents: source: data:,%23%23%20These%20rules%20watch%20for%20kernel%20module%20insertion.%20By%20monitoring%0A%23%23%20the%20syscall%2C%20we%20do%20not%20need%20any%20watches%20on%20programs.%0A-a%20always%2Cexit%20-F%20arch%3Db32%20-S%20init_module%2Cfinit_module%20-F%20key%3Dmodule-load%0A-a%20always%2Cexit%20-F%20arch%3Db64%20-S%20init_module%2Cfinit_module%20-F%20key%3Dmodule-load%0A-a%20always%2Cexit%20-F%20arch%3Db32%20-S%20delete_module%20-F%20key%3Dmodule-unload%0A-a%20always%2Cexit%20-F%20arch%3Db64%20-S%20delete_module%20-F%20key%3Dmodule-unload%0A mode: 0644 path: /etc/audit/rules.d/43-module-load.rules overwrite: true - contents: source: data:,-a%20always%2Cexit%20-F%20arch%3Db32%20-S%20delete_module%20-k%20module-change%0A-a%20always%2Cexit%20-F%20arch%3Db64%20-S%20delete_module%20-k%20module-change%0A mode: 0644 path: /etc/audit/rules.d/75-kernel-module-loading-delete.rules overwrite: true - contents: source: data:,-a%20always%2Cexit%20-F%20arch%3Db32%20-S%20finit_module%20-k%20module-change%0A-a%20always%2Cexit%20-F%20arch%3Db64%20-S%20finit_module%20-k%20module-change%0A mode: 0644 path: /etc/audit/rules.d/75-kernel-module-loading-finit.rules overwrite: true - contents: source: data:,-a%20always%2Cexit%20-F%20arch%3Db32%20-S%20init_module%20-k%20module-change%0A-a%20always%2Cexit%20-F%20arch%3Db64%20-S%20init_module%20-k%20module-change%0A mode: 0644 path: /etc/audit/rules.d/75-kernel-module-loading-init.rules overwrite: true " | oc apply -f - done
Verify the Red Hat Enterprise Linux CoreOS (RHCOS) is configured to generate audit records showing starting and ending times for user access by executing the following: for node in $(oc get node -oname); do oc debug $node -- chroot /host /bin/bash -c 'echo -n "$HOSTNAME "; grep -e "-k session" /etc/audit/audit.rules' 2>/dev/null; done Confirm the following rules exist on each node: -w /var/log/btmp -p wa -k session -w /var/log/utmp -p wa -k session If the above rules are not listed on each node, this is a finding.
Apply the machine config for user access times by executing the following: for mcpool in $(oc get mcp -oname | sed "s:.*/::" ); do echo "apiVersion: machineconfiguration.openshift.io/v1 kind: MachineConfig metadata: name: 75-session-start-end-time-$mcpool labels: machineconfiguration.openshift.io/role: $mcpool spec: config: ignition: version: 3.1.0 storage: files: - contents: source: data:,-w%20/var/log/btmp%20-p%20wa%20-k%20session%0A mode: 0644 path: /etc/audit/rules.d/75-var_log_btmp_write_events.rules overwrite: true - contents: source: data:,-w%20/var/log/utmp%20-p%20wa%20-k%20session%0A mode: 0644 path: /etc/audit/rules.d/75-var_log_utmp_write_events.rules overwrite: true " | oc apply -f - done
Verify that concurrent logons are audited by executing the following: for node in $(oc get node -oname); do oc debug $node -- chroot /host /bin/bash -c 'echo -n "$HOSTNAME "; grep "logins" /etc/audit/audit.rules /etc/audit/rules.d/*' 2>/dev/null; done The output will look similar to: node-name /etc/audit/<file>:-w /var/run/faillock -p wa -k logins /etc/audit/<file>:-w /var/log/lastlog -p wa -k logins If the two rules above are not found on each node, this is a finding.
Apply the machine config so concurrent logons are audited by executing the following: for mcpool in $(oc get mcp -oname | sed "s:.*/::" ); do echo "apiVersion: machineconfiguration.openshift.io/v1 kind: MachineConfig metadata: name: 75-concurrent-logons-rules labels: machineconfiguration.openshift.io/role: $mcpool spec: config: ignition: version: 3.1.0 storage: files: - contents: source: data:,-w%20/var/run/faillock%20-p%20wa%20-k%20logins%0A mode: 0644 path: /etc/audit/rules.d/75-faillock_login_events.rules overwrite: true - contents: source: data:,-w%20/var/log/lastlog%20-p%20wa%20-k%20logins%0A mode: 0644 path: /etc/audit/rules.d/75-lastlog_login_events.rules overwrite: true " | oc apply -f - done
Verify the SSHD service is inactive and disabled by executing the following: for node in $(oc get node -oname); do oc debug $node -- chroot /host /bin/bash -c 'echo -n "$HOSTNAME "; systemctl is-enabled sshd.service; systemctl is-active sshd.service' 2>/dev/null; done If the SSHD service is either active or enabled this is a finding.
Apply the machine config to disable SSHD service by executing following: for mcpool in $(oc get mcp -oname | sed "s:.*/::" ); do echo "apiVersion: machineconfiguration.openshift.io/v1 kind: MachineConfig metadata: name: 80-sshd-service-disable-$mcpool labels: machineconfiguration.openshift.io/role: $mcpool spec: config: ignition: version: 3.1.0 systemd: units: - name: sshd.service enabled: false " | oc apply -f - done
Verify the operating system disables the ability to load the USB Storage kernel module by executing the following: for node in $(oc get node -oname); do oc debug $node -- chroot /host /bin/bash -c 'echo -n "$HOSTNAME "; grep -r usb-storage /etc/modprobe.d/* | grep -i "/bin/true"' 2>/dev/null; done install usb-storage /bin/true If the command does not return any output, or the line is commented out, and use of USB Storage is not documented with the Information System Security Officer (ISSO) as an operational requirement, this is a finding.
Apply the machine config to disable USB Storage to load USB Storage kernel module by executing the following: for mcpool in $(oc get mcp -oname | sed "s:.*/::" ); do echo "apiVersion: machineconfiguration.openshift.io/v1 kind: MachineConfig metadata: name: 80-kernmod-usb-storage-disable-$mcpool labels: machineconfiguration.openshift.io/role: $mcpool spec: config: ignition: version: 3.1.0 storage: files: - contents: source: data:,install%20usb-storage%20/bin/true%0A mode: 0644 path: /etc/modprobe.d/75-kernel_module_usb-storage_disabled.conf overwrite: true " | oc apply -f - done
1. Determine if the host devices include a USB Controller by executing the following: for node in $(oc get node -oname); do oc debug $node -- chroot /host /bin/bash -c 'echo -n "$HOSTNAME "; lspci' 2>/dev/null; done If there is not a USB Controller, then this requirement is Not Applicable. 2. Verify the USBGuard service is installed by executing the following: for node in $(oc get node -oname); do oc debug $node -- chroot /host /bin/bash -c 'echo -n "$HOSTNAME "; rpm -q usbguard' 2>/dev/null; done If the output returns "package usbguard is not installed", this is a finding. 3. Verify that USBGuard is set up to log into the Linux audit log. for node in $(oc get node -oname); do oc debug $node -- chroot /host /bin/bash -c 'echo -n "$HOSTNAME "; grep -r AuditBackend /etc/usbguard/usbguard-daemon.conf' 2>/dev/null; done The output should return: "AuditBackend=LinuxAudit". If it does not, this is a finding. 4. Verify the USBGuard has a policy configured with by executing the following: for node in $(oc get node -oname); do oc debug $node -- chroot /host /bin/bash -c 'echo -n "$HOSTNAME "; usbguard list-rules' 2>/dev/null; done If USBGuard is not found or the results do not match the organizationally defined rules, this is a finding.
If there is not a USB Controller, this requirement is Not Applicable. 1. Install the service by executing the following: for mcpool in $(oc get mcp -oname | sed "s:.*/::" ); do echo "apiVersion: machineconfiguration.openshift.io/v1 kind: MachineConfig metadata: name: 80-usbguard-extensions-$mcpool labels: machineconfiguration.openshift.io/role: $mcpool spec: config: ignition: version: 3.1.0 extensions: - usbguard " | oc apply -f - done 2. Wait for the nodes to reboot. Note: (>oc get mcp) None of the pools should say Updating=true when the update is done. 3. Enable the service by executing the following: for mcpool in $(oc get mcp -oname | sed "s:.*/::" ); do echo "apiVersion: machineconfiguration.openshift.io/v1 kind: MachineConfig metadata: name: 80-usbguard-service-enable-$mcpool labels: machineconfiguration.openshift.io/role: $mcpool spec: config: ignition: version: 3.1.0 systemd: units: - name: usbguard.service enabled: true " | oc apply -f - done 4. Configure USBGuard to log to the audit log: for mcpool in $(oc get mcp -oname | sed "s:.*/::" ); do echo "apiVersion: machineconfiguration.openshift.io/v1 kind: MachineConfig metadata: name: 80-usbguard-daemon-conf-$mcpool labels: machineconfiguration.openshift.io/role: $mcpool spec: config: ignition: version: 3.1.0 storage: files: - contents: source: data:,%23%0A%23%20Rule%20set%20file%20path.%0A%23%0A%23%20The%20USBGuard%20daemon%20will%20use%20this%20file%20to%20load%20the%20policy%0A%23%20rule%20set%20from%20it%20and%20to%20write%20new%20rules%20received%20via%20the%0A%23%20IPC%20interface.%0A%23%0A%23%20RuleFile%3D%2Fpath%2Fto%2Frules.conf%0A%23%0ARuleFile%3D%2Fetc%2Fusbguard%2Frules.conf%0A%0A%23%0A%23%20Rule%20set%20folder%20path.%0A%23%0A%23%20The%20USBGuard%20daemon%20will%20use%20this%20folder%20to%20load%20the%20policy%0A%23%20rule%20set%20from%20it%20and%20to%20write%20new%20rules%20received%20via%20the%0A%23%20IPC%20interface.%20Usually%2C%20we%20set%20the%20option%20to%0A%23%20%2Fetc%2Fusbguard%2Frules.d%2F.%20The%20USBGuard%20daemon%20is%20supposed%20to%0A%23%20behave%20like%20any%20other%20standard%20Linux%20daemon%20therefore%20it%0A%23%20loads%20rule%20files%20in%20alpha-numeric%20order.%20File%20names%20inside%0A%23%20RuleFolder%20directory%20should%20start%20with%20a%20two-digit%20number%0A%23%20prefix%20indicating%20the%20position%2C%20in%20which%20the%20rules%20are%0A%23%20scanned%20by%20the%20daemon.%0A%23%0A%23%20RuleFolder%3D%2Fpath%2Fto%2Frulesfolder%2F%0A%23%0ARuleFolder%3D%2Fetc%2Fusbguard%2Frules.d%2F%0A%0A%23%0A%23%20Implicit%20policy%20target.%0A%23%0A%23%20How%20to%20treat%20devices%20that%20don%27t%20match%20any%20rule%20in%20the%0A%23%20policy.%20One%20of%3A%0A%23%0A%23%20%2A%20allow%20%20-%20authorize%20the%20device%0A%23%20%2A%20block%20%20-%20block%20the%20device%0A%23%20%2A%20reject%20-%20remove%20the%20device%0A%23%0AImplicitPolicyTarget%3Dblock%0A%0A%23%0A%23%20Present%20device%20policy.%0A%23%0A%23%20How%20to%20treat%20devices%20that%20are%20already%20connected%20when%20the%0A%23%20daemon%20starts.%20One%20of%3A%0A%23%0A%23%20%2A%20allow%20%20%20%20%20%20%20%20-%20authorize%20every%20present%20device%0A%23%20%2A%20block%20%20%20%20%20%20%20%20-%20deauthorize%20every%20present%20device%0A%23%20%2A%20reject%20%20%20%20%20%20%20-%20remove%20every%20present%20device%0A%23%20%2A%20keep%20%20%20%20%20%20%20%20%20-%20just%20sync%20the%20internal%20state%20and%20leave%20it%0A%23%20%2A%20apply-policy%20-%20evaluate%20the%20ruleset%20for%20every%20present%0A%23%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20device%0A%23%0APresentDevicePolicy%3Dapply-policy%0A%0A%23%0A%23%20Present%20controller%20policy.%0A%23%0A%23%20How%20to%20treat%20USB%20controllers%20that%20are%20already%20connected%0A%23%20when%20the%20daemon%20starts.%20One%20of%3A%0A%23%0A%23%20%2A%20allow%20%20%20%20%20%20%20%20-%20authorize%20every%20present%20device%0A%23%20%2A%20block%20%20%20%20%20%20%20%20-%20deauthorize%20every%20present%20device%0A%23%20%2A%20reject%20%20%20%20%20%20%20-%20remove%20every%20present%20device%0A%23%20%2A%20keep%20%20%20%20%20%20%20%20%20-%20just%20sync%20the%20internal%20state%20and%20leave%20it%0A%23%20%2A%20apply-policy%20-%20evaluate%20the%20ruleset%20for%20every%20present%0A%23%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20device%0A%23%0APresentControllerPolicy%3Dkeep%0A%0A%23%0A%23%20Inserted%20device%20policy.%0A%23%0A%23%20How%20to%20treat%20USB%20devices%20that%20are%20already%20connected%0A%23%20%2Aafter%2A%20the%20daemon%20starts.%20One%20of%3A%0A%23%0A%23%20%2A%20block%20%20%20%20%20%20%20%20-%20deauthorize%20every%20present%20device%0A%23%20%2A%20reject%20%20%20%20%20%20%20-%20remove%20every%20present%20device%0A%23%20%2A%20apply-policy%20-%20evaluate%20the%20ruleset%20for%20every%20present%0A%23%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20device%0A%23%0AInsertedDevicePolicy%3Dapply-policy%0A%0A%23%0A%23%20Control%20which%20devices%20are%20authorized%20by%20default.%0A%23%0A%23%20The%20USBGuard%20daemon%20modifies%20some%20the%20default%20authorization%20state%20attributes%0A%23%20of%20controller%20devices.%20This%20setting%2C%20enables%20you%20to%20define%20what%20value%20the%0A%23%20default%20authorization%20is%20set%20to.%0A%23%0A%23%20%2A%20keep%20%20%20%20%20%20%20%20%20-%20do%20not%20change%20the%20authorization%20state%0A%23%20%2A%20none%20%20%20%20%20%20%20%20%20-%20every%20new%20device%20starts%20out%20deauthorized%0A%23%20%2A%20all%20%20%20%20%20%20%20%20%20%20-%20every%20new%20device%20starts%20out%20authorized%0A%23%20%2A%20internal%20%20%20%20%20-%20internal%20devices%20start%20out%20authorized%2C%20external%20devices%20start%0A%23%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20out%20deauthorized%20%28this%20requires%20the%20ACPI%20tables%20to%20properly%0A%23%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20label%20internal%20devices%2C%20and%20kernel%20support%29%0A%23%0A%23AuthorizedDefault%3Dnone%0A%0A%23%0A%23%20Restore%20controller%20device%20state.%0A%23%0A%23%20The%20USBGuard%20daemon%20modifies%20some%20attributes%20of%20controller%0A%23%20devices%20like%20the%20default%20authorization%20state%20of%20new%20child%20device%0A%23%20instances.%20Using%20this%20setting%2C%20you%20can%20control%20whether%20the%0A%23%20daemon%20will%20try%20to%20restore%20the%20attribute%20values%20to%20the%20state%0A%23%20before%20modification%20on%20shutdown.%0A%23%0A%23%20SECURITY%20CONSIDERATIONS%3A%20If%20set%20to%20true%2C%20the%20USB%20authorization%0A%23%20policy%20could%20be%20bypassed%20by%20performing%20some%20sort%20of%20attack%20on%20the%0A%23%20daemon%20%28via%20a%20local%20exploit%20or%20via%20a%20USB%20device%29%20to%20make%20it%20shutdown%0A%23%20and%20restore%20to%20the%20operating-system%20default%20state%20%28known%20to%20be%20permissive%29.%0A%23%0ARestoreControllerDeviceState%3Dfalse%0A%0A%23%0A%23%20Device%20manager%20backend%0A%23%0A%23%20Which%20device%20manager%20backend%20implementation%20to%20use.%20One%20of%3A%0A%23%0A%23%20%2A%20uevent%20%20%20-%20Netlink%20based%20implementation%20which%20uses%20sysfs%20to%20scan%20for%20present%0A%23%20%20%20%20%20%20%20%20%20%20%20%20%20%20devices%20and%20an%20uevent%20netlink%20socket%20for%20receiving%20USB%20device%0A%23%20%20%20%20%20%20%20%20%20%20%20%20%20%20related%20events.%0A%23%20%2A%20umockdev%20-%20umockdev%20based%20device%20manager%20capable%20of%20simulating%20devices%20based%0A%23%20%20%20%20%20%20%20%20%20%20%20%20%20%20on%20umockdev-record%20files.%20Useful%20for%20testing.%0A%23%0ADeviceManagerBackend%3Duevent%0A%0A%23%21%21%21%20WARNING%3A%20It%27s%20good%20practice%20to%20set%20at%20least%20one%20of%20the%20%21%21%21%0A%23%21%21%21%20%20%20%20%20%20%20%20%20%20two%20options%20bellow.%20If%20none%20of%20them%20are%20set%2C%20%20%21%21%21%0A%23%21%21%21%20%20%20%20%20%20%20%20%20%20the%20daemon%20will%20accept%20IPC%20connections%20from%20%20%20%21%21%21%0A%23%21%21%21%20%20%20%20%20%20%20%20%20%20anyone%2C%20thus%20allowing%20anyone%20to%20modify%20the%20%20%20%20%21%21%21%0A%23%21%21%21%20%20%20%20%20%20%20%20%20%20rule%20set%20and%20%28de%29authorize%20USB%20devices.%20%20%20%20%20%20%20%21%21%21%0A%0A%23%0A%23%20Users%20allowed%20to%20use%20the%20IPC%20interface.%0A%23%0A%23%20A%20space%20delimited%20list%20of%20usernames%20that%20the%20daemon%20will%0A%23%20accept%20IPC%20connections%20from.%0A%23%0A%23%20IPCAllowedUsers%3Dusername1%20username2%20...%0A%23%0AIPCAllowedUsers%3Droot%0A%0A%23%0A%23%20Groups%20allowed%20to%20use%20the%20IPC%20interface.%0A%23%0A%23%20A%20space%20delimited%20list%20of%20groupnames%20that%20the%20daemon%20will%0A%23%20accept%20IPC%20connections%20from.%0A%23%0A%23%20IPCAllowedGroups%3Dgroupname1%20groupname2%20...%0A%23%0AIPCAllowedGroups%3Dwheel%0A%0A%23%0A%23%20IPC%20access%20control%20definition%20files%20path.%0A%23%0A%23%20The%20files%20at%20this%20location%20will%20be%20interpreted%20by%20the%20daemon%0A%23%20as%20access%20control%20definition%20files.%20The%20%28base%29name%20of%20a%20file%0A%23%20should%20be%20in%20the%20form%3A%0A%23%0A%23%20%20%20%5Buser%5D%5B%3A%3Cgroup%3E%5D%0A%23%0A%23%20and%20should%20contain%20lines%20in%20the%20form%3A%0A%23%0A%23%20%20%20%3Csection%3E%3D%5Bprivilege%5D%20...%0A%23%0A%23%20This%20way%20each%20file%20defines%20who%20is%20able%20to%20connect%20to%20the%20IPC%0A%23%20bus%20and%20what%20privileges%20he%20has.%0A%23%0AIPCAccessControlFiles%3D%2Fetc%2Fusbguard%2FIPCAccessControl.d%2F%0A%0A%23%0A%23%20Generate%20device%20specific%20rules%20including%20the%20%22via-port%22%0A%23%20attribute.%0A%23%0A%23%20This%20option%20modifies%20the%20behavior%20of%20the%20allowDevice%0A%23%20action.%20When%20instructed%20to%20generate%20a%20permanent%20rule%2C%0A%23%20the%20action%20can%20generate%20a%20port%20specific%20rule.%20Because%0A%23%20some%20systems%20have%20unstable%20port%20numbering%2C%20the%20generated%0A%23%20rule%20might%20not%20match%20the%20device%20after%20rebooting%20the%20system.%0A%23%0A%23%20If%20set%20to%20false%2C%20the%20generated%20rule%20will%20still%20contain%0A%23%20the%20%22parent-hash%22%20attribute%20which%20also%20defines%20an%20association%0A%23%20to%20the%20parent%20device.%20See%20usbguard-rules.conf%285%29%20for%20more%0A%23%20details.%0A%23%0ADeviceRulesWithPort%3Dfalse%0A%0A%23%0A%23%20USBGuard%20Audit%20events%20log%20backend%0A%23%0A%23%20One%20of%3A%0A%23%0A%23%20%2A%20FileAudit%20-%20Log%20audit%20events%20into%20a%20file%20specified%20by%0A%23%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20AuditFilePath%20setting%20%28see%20below%29%0A%23%20%2A%20LinuxAudit%20-%20Log%20audit%20events%20using%20the%20Linux%20Audit%0A%23%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20subsystem%20%28using%20audit_log_user_message%29%0A%23%0AAuditBackend%3DLinuxAudit%0A%0A%23%0A%23%20USBGuard%20audit%20events%20log%20file%20path.%0A%23%0A%23AuditFilePath%3D%2Fvar%2Flog%2Fusbguard%2Fusbguard-audit.log%0A%0A%23%0A%23%20Hides%20personally%20identifiable%20information%20such%20as%20device%20serial%20numbers%20and%0A%23%20hashes%20of%20descriptors%20%28which%20include%20the%20serial%20number%29%20from%20audit%20entries.%0A%23%0A%23HidePII%3Dfalse mode: 0600 path: /etc/usbguard/usbguard-daemon.conf overwrite: true " | oc apply -f - done 5. Create a USBGuard policy: Below is an example policy. Replace the string in files.contents.source.data with an organizationally approved policy: for mcpool in $(oc get mcp -oname | sed "s:.*/::" ); do echo "apiVersion: machineconfiguration.openshift.io/v1 kind: MachineConfig metadata: name: 80-usbguard-rules-conf-$mcpool labels: machineconfiguration.openshift.io/role: $mcpool spec: config: ignition: version: 3.1.0 storage: files: - contents: source: data:,allow%20with-interface%20one-of%20%7B%2003%3A00%3A01%2003%3A01%3A01%20%7D%20if%20%21allowed-matches%28with-interface%20one-of%20%7B%2003%3A00%3A01%2003%3A01%3A01%20%7D%29 mode: 0600 path: /etc/usbguard/rules.conf overwrite: true " | oc apply -f - done
To check if the Container Security Operator is running, execute the following: oc get deploy -n openshift-operators container-security-operator -ojsonpath='{.status.readyReplicas}' If this command returns an error or the number 0, and a separate tool is not being used to perform continuous vulnerability scans of components, containers, and container images, this is a finding.
Vulnerability scanning can be performed by the Container Security Operator, Red Hat Advanced Cluster Security (formerly StackRox) or by external applications. Follow instructions from the application vendor if using external tool for vulnerability scanning. To install the Container Security Operator into the cluster, run the following: oc apply -f - << 'EOF' --- apiVersion: operators.coreos.com/v1alpha1 kind: Subscription metadata: labels: operators.coreos.com/container-security-operator.openshift-operators: '' name: container-security-operator namespace: openshift-operators spec: channel: stable-3.8 installPlanApproval: Automatic name: container-security-operator source: redhat-operators sourceNamespace: openshift-marketplace EOF
Verify the use of a FIPS-compliant hash function for digital signature generation and validation, by executing and reviewing the following commands: update-crypto-policies --show If the return is not "FIPS", this is a finding. Verify the crypto-policies by executing the following: openssl x509 -in /etc/kubernetes/kubelet-ca.crt -noout -text | grep Algorithm openssl x509 -in /etc/kubernetes/ca.crt -noout -text | grep Algorithm If any of the crypto-policies listed are not FIPS compliant, this is a finding. Details of algorithms can be reviewed at the following knowledge base article: https://access.redhat.com/articles/3642912
Reinstall the OpenShift cluster in FIPS mode. The file install-config.yaml has a top-level key that enables FIPS mode for all nodes and the cluster platform layer. If the install-config.yaml was not backed up prior to consumption as part of the installation, it must be recreated. An example install-config.yaml with some sections trimmed out for brevity, and the "fips: true" key applied at the top level is shown below: apiVersion: v1 baseDomain: example.com controlPlane: name: master platform: aws: [...] replicas: 3 compute: - name: worker platform: aws: replicas: 3 metadata: name: fips-cluster networking: [...] platform: aws: [...] sshKey: ssh-ed25519 AAAA... pullSecret: '{"auths": ...}' fips: true After saving the install-config.yaml with the corresponding correct information, run the installer to create a cluster that uses FIPS-validated Modules in Process cryptographic libraries. The command to install a cluster and consume the install-config.yaml is: > ./openshift-install create cluster --dir=<installation_directory> --log-level=info Where <installation_directory> is the directory that contains install-config.yaml Additional details can be found here: https://docs.openshift.com/container-platform/4.8/installing/installing-fips.html