Managing Compliance Operator result and remediation
You can review compliance scan results and apply remediations to resolve failing rules. Remediations are not applied automatically, so you can verify each change before applying it to your cluster.
Full remediation for Federal Information Processing Standards (FIPS) compliance requires enabling FIPS mode for the cluster. To enable FIPS mode, you must run the installation program from a Red Hat Enterprise Linux (RHEL) computer configured to operate in FIPS mode. For more information about configuring FIPS mode on RHEL, see Installing the system in FIPS mode.
FIPS mode is supported on the following architectures:
x86_64ppc64les390x
Filters for compliance check results
You can use the labels in the ComplianceCheckResult objects to query the checks and decide on the next steps after the results are generated.
List checks that belong to a specific suite:
$ oc get -n openshift-compliance compliancecheckresults \
-l compliance.openshift.io/suite=workers-compliancesuite
List checks that belong to a specific scan:
$ oc get -n openshift-compliance compliancecheckresults \
-l compliance.openshift.io/scan-name=workers-scan
Not all ComplianceCheckResult objects create ComplianceRemediation objects. Only ComplianceCheckResult objects that can be remediated automatically do. A ComplianceCheckResult object has a related remediation if it is labeled with the compliance.openshift.io/automated-remediation label. The name of the remediation is the same as the name of the check.
List all failing checks that can be remediated automatically:
$ oc get -n openshift-compliance compliancecheckresults \
-l 'compliance.openshift.io/check-status=FAIL,compliance.openshift.io/automated-remediation'
List all failing checks sorted by severity:
$ oc get compliancecheckresults -n openshift-compliance \
-l 'compliance.openshift.io/check-status=FAIL,compliance.openshift.io/check-severity=high'
NAME STATUS SEVERITY
nist-moderate-modified-master-configure-crypto-policy FAIL high
nist-moderate-modified-master-coreos-pti-kernel-argument FAIL high
nist-moderate-modified-master-disable-ctrlaltdel-burstaction FAIL high
nist-moderate-modified-master-disable-ctrlaltdel-reboot FAIL high
nist-moderate-modified-master-enable-fips-mode FAIL high
nist-moderate-modified-master-no-empty-passwords FAIL high
nist-moderate-modified-master-selinux-state FAIL high
nist-moderate-modified-worker-configure-crypto-policy FAIL high
nist-moderate-modified-worker-coreos-pti-kernel-argument FAIL high
nist-moderate-modified-worker-disable-ctrlaltdel-burstaction FAIL high
nist-moderate-modified-worker-disable-ctrlaltdel-reboot FAIL high
nist-moderate-modified-worker-enable-fips-mode FAIL high
nist-moderate-modified-worker-no-empty-passwords FAIL high
nist-moderate-modified-worker-selinux-state FAIL high
ocp4-moderate-configure-network-policies-namespaces FAIL high
ocp4-moderate-fips-mode-enabled-on-all-nodes FAIL high
List all failing checks that must be remediated manually:
$ oc get -n openshift-compliance compliancecheckresults \
-l 'compliance.openshift.io/check-status=FAIL,!compliance.openshift.io/automated-remediation'
The manual remediation steps are typically stored in the description attribute in the ComplianceCheckResult object.
ComplianceCheckResult Status
| ComplianceCheckResult Status | Description |
|---|---|
| PASS | Compliance check ran to completion and passed. |
| FAIL | Compliance check ran to completion and failed. |
| INFO | Compliance check ran to completion and found something not severe enough to be considered an error. |
| MANUAL | Compliance check does not have a way to automatically assess the success or failure and must be checked manually. |
| INCONSISTENT | Compliance check reports different results from different sources, typically cluster nodes. |
| ERROR | Compliance check ran, but could not complete properly. |
| NOT-APPLICABLE | Compliance check did not run because it is not applicable or not selected. |
Review a remediation
You can review a ComplianceRemediation object and the ComplianceCheckResult object to understand what a check verifies, its severity and security controls, and how the remediation fixes the issue. After the first scan, check for remediations with the state MissingDependencies.
The ComplianceCheckResult object includes human-readable descriptions of what the check does and what security hardening it enforces.
The remediation payload is stored in the spec.current attribute. The payload can be any Kubernetes object, but because this remediation was produced by a node scan, the remediation payload in the following example is a MachineConfig object. For Platform scans, the remediation payload is often a different kind of an object (for example, a ConfigMap or Secret object). Typically, applying that remediation is up to the administrator. Otherwise, the Compliance Operator would have required a very broad set of permissions to manipulate any generic Kubernetes object. An example of remediating a Platform check is provided later in the text.
To see exactly what the remediation does when applied, the MachineConfig object contents use the Ignition objects for the configuration. See the link to "Ignition specification" in Additional resources for further information about the format. In the following example, the spec.config.storage.files[0].path attribute specifies the file that is being created by this remediation (/etc/sysctl.d/75-sysctl_net_ipv4_conf_all_accept_redirects.conf) and the spec.config.storage.files[0].contents.source attribute specifies the contents of that file.
Procedure
-
Review the example of a check and a remediation called
sysctl-net-ipv4-conf-all-accept-redirects. This example is redacted to only showspecandstatusand omitsmetadata:spec:apply: falsecurrent:object:apiVersion: machineconfiguration.openshift.io/v1kind: MachineConfigspec:config:ignition:version: 3.2.0storage:files:- path: /etc/sysctl.d/75-sysctl_net_ipv4_conf_all_accept_redirects.confmode: 0644contents:source: data:,net.ipv4.conf.all.accept_redirects%3D0outdated: {}status:applicationState: NotApplied -
Use the following Python script to view the contents:
noteThe contents of the files are URL-encoded.
$ echo "net.ipv4.conf.all.accept_redirects%3D0" | python3 -c "import sys, urllib.parse; print(urllib.parse.unquote(''.join(sys.stdin.readlines())))"Example outputnet.ipv4.conf.all.accept_redirects=0warningThe Compliance Operator does not automatically resolve dependency issues that can occur between remediations. Users should perform a rescan after remediations are applied to ensure accurate results.
Apply remediation when using customized machine config pools
When you create a custom MachineConfigPool, add a label to the MachineConfigPool so that machineConfigPoolSelector present in the KubeletConfig can match the label with MachineConfigPool.
Do not set protectKernelDefaults: false in the KubeletConfig file, because the MachineConfigPool object might fail to unpause unexpectedly after the Compliance Operator finishes applying remediation.
Procedure
-
List the nodes.
$ oc get nodes -n openshift-complianceExample outputNAME STATUS ROLES AGE VERSIONip-10-0-128-92.us-east-2.compute.internal Ready master 5h21m v1.35.4ip-10-0-158-32.us-east-2.compute.internal Ready worker 5h17m v1.35.4ip-10-0-166-81.us-east-2.compute.internal Ready worker 5h17m v1.35.4ip-10-0-171-170.us-east-2.compute.internal Ready master 5h21m v1.35.4ip-10-0-197-35.us-east-2.compute.internal Ready master 5h22m v1.35.4 -
Add a label to nodes.
$ oc -n openshift-compliance \label node ip-10-0-166-81.us-east-2.compute.internal \node-role.kubernetes.io/<machine_config_pool_name>=Example outputnode/ip-10-0-166-81.us-east-2.compute.internal labeled -
Create custom
MachineConfigPoolCR.apiVersion: machineconfiguration.openshift.io/v1kind: MachineConfigPoolmetadata:name: <machine_config_pool_name>labels:pools.operator.machineconfiguration.openshift.io/<machine_config_pool_name>: ''spec:machineConfigSelector:matchExpressions:- {key: machineconfiguration.openshift.io/role, operator: In, values: [worker,<machine_config_pool_name>]}nodeSelector:matchLabels:node-role.kubernetes.io/<machine_config_pool_name>: ""where:
metadata.labels.pools.operator.machineconfiguration.openshift.io/<machine_config_pool_name>- The
labelsfield defines the label name to add for the machine config pool (MCP).
-
Verify MCP created successfully.
$ oc get mcp -w
Evaluate KubeletConfig rules against default configuration values
The Compliance Operator uses the Node/Proxy API to evaluate KubeletConfig object rules against actual node configurations, preventing inaccurate results caused by incomplete configuration files and default values for missing options.
OpenShift Container Platform infrastructure might contain incomplete configuration files at run time, and nodes assume default configuration values for missing configuration options. Some configuration options can be passed as command-line arguments. As a result, the Compliance Operator cannot verify if the configuration file on the node is complete because it might be missing options used in the rule checks.
To prevent false negative results where the default configuration value passes a check, the Compliance Operator uses the Node/Proxy API to fetch the configuration for each node in a node pool, then all configuration options that are consistent across nodes in the node pool are stored in a file that represents the configuration for all nodes within that node pool. This increases the accuracy of the scan results.
No additional configuration changes are required to use this feature with default master and worker node pools configurations.
Scan custom node pools
The Compliance Operator does not maintain a copy of each node pool configuration.
The Compliance Operator aggregates consistent configuration options for all nodes within a single node pool into one copy of the configuration file. The Compliance Operator then uses the configuration file for a particular node pool to evaluate rules against nodes within that pool.
Procedure
- Add the
examplerole to theScanSettingobject that will be stored in theScanSettingBindingCR:apiVersion: compliance.openshift.io/v1alpha1kind: ScanSettingmetadata:name: defaultnamespace: openshift-compliancerawResultStorage:rotation: 3size: 1Giroles:- worker- master- examplescanTolerations:- effect: NoSchedulekey: node-role.kubernetes.io/masteroperator: Existsschedule: '0 1 * * *' - Create a scan that uses the
ScanSettingBindingCR:apiVersion: compliance.openshift.io/v1alpha1kind: ScanSettingBindingmetadata:name: cisnamespace: openshift-complianceprofiles:- apiGroup: compliance.openshift.io/v1alpha1kind: Profilename: ocp4-cis- apiGroup: compliance.openshift.io/v1alpha1kind: Profilename: ocp4-cis-nodesettingsRef:apiGroup: compliance.openshift.io/v1alpha1kind: ScanSettingname: default
Verification
- The Platform KubeletConfig rules are checked through the
Node/Proxyobject. You can find those rules by running the following command:$ oc get rules -o json | jq '.items[] | select(.checkType == "Platform") | select(.metadata.name | contains("ocp4-kubelet-")) | .metadata.name'
Remediate KubeletConfig sub pools
You can apply KubeletConfig remediation labels to MachineConfigPool sub-pools.
Procedure
- Add a label to the sub-pool
MachineConfigPoolCR:$ oc label mcp <sub-pool-name> pools.operator.machineconfiguration.openshift.io/<sub-pool-name>=
Apply a remediation
The boolean attribute spec.apply controls whether the remediation should be applied by the Compliance Operator. You can apply the remediation by setting the attribute to true.
Procedure
-
Apply the remediation by setting the attribute to
true:$ oc -n openshift-compliance \patch complianceremediations/<scan-name>-sysctl-net-ipv4-conf-all-accept-redirects \--patch '{"spec":{"apply":true}}' --type=mergeAfter the Compliance Operator processes the applied remediation, the
status.ApplicationStateattribute would change to Applied or to Error if incorrect. When a machine config remediation is applied, that remediation along with all other applied remediations are rendered into aMachineConfigobject named75-$scan-name-$suite-name. ThatMachineConfigobject is subsequently rendered by the Machine Config Operator and finally applied to all the nodes in a machine config pool by an instance of the machine control daemon running on each node.Note that when the Machine Config Operator applies a new
MachineConfigobject to nodes in a pool, all the nodes belonging to the pool are rebooted. This might be inconvenient when applying multiple remediations, each of which re-renders the composite75-$scan-name-$suite-nameMachineConfigobject. To prevent applying the remediation immediately, you can pause the machine config pool by setting the.spec.pausedattribute of aMachineConfigPoolobject totrue. -
Optionally, the Compliance Operator can apply remediations automatically. Set
autoApplyRemediations: truein theScanSettingtop-level object.warningApplying remediations automatically should only be done with careful consideration.
warningThe Compliance Operator does not automatically resolve dependency issues that can occur between remediations. Users should perform a rescan after remediations are applied to ensure accurate results.
Remediate a platform check manually
You must manually remediate checks from Platform scans so you can fix findings that the Compliance Operator cannot apply automatically.
Manual remediations are necessary for the following reasons:
- It is not always possible to automatically determine the value that must be set. One of the checks requires that a list of allowed registries is provided, but the scanner has no way of knowing which registries the organization wants to allow.
- Different checks modify different API objects, requiring automated remediation to possess
rootor superuser access to modify objects in the cluster, which is not advised.
Procedure
-
The example below uses the
ocp4-ocp-allowed-registries-for-importrule, which would fail on a default OpenShift Container Platform installation. Inspect the ruleoc get rule.compliance/ocp4-ocp-allowed-registries-for-import -oyaml, the rule is to limit the registries the users are allowed to import images from by setting theallowedRegistriesForImportattribute, The warning attribute of the rule also shows the API object checked, so it can be modified and remediate the issue:$ oc edit image.config.openshift.io/clusterExample outputapiVersion: config.openshift.io/v1kind: Imagemetadata:annotations:release.openshift.io/create-only: "true"creationTimestamp: "2020-09-10T10:12:54Z"generation: 2name: clusterresourceVersion: "363096"selfLink: /apis/config.openshift.io/v1/images/clusteruid: 2dcb614e-2f8a-4a23-ba9a-8e33cd0ff77espec:allowedRegistriesForImport:- domainName: registry.redhat.iostatus:externalRegistryHostnames:- default-route-openshift-image-registry.apps.user-cluster-09-10-12-07.devcluster.openshift.cominternalRegistryHostname: image-registry.openshift-image-registry.svc:5000 -
Re-run the scan:
$ oc -n openshift-compliance \annotate compliancescans/rhcos4-e8-worker compliance.openshift.io/rescan=
Update remediations
When you update compliance content to a newer version, the Compliance Operator marks previously applied remediations as Outdated. Review these remediations and apply the updated versions to ensure your nodes use the latest configuration.
The previously applied remediation contents would then be stored in the spec.outdated attribute of a ComplianceRemediation object and the new updated contents would be stored in the spec.current attribute. After updating the content to a newer version, the administrator then needs to review the remediation. If the spec.outdated attribute exists, it would be used to render the resulting MachineConfig object. After the spec.outdated attribute is removed, the Compliance Operator re-renders the resulting MachineConfig object, which causes the Operator to push the configuration to the nodes.
The Compliance Operator does not automatically resolve dependency issues that can occur between remediations. Users should perform a rescan after remediations are applied to ensure accurate results.
Procedure
-
Search for any outdated remediations:
$ oc -n openshift-compliance get complianceremediations \-l complianceoperator.openshift.io/outdated-remediation=Example outputNAME STATEworkers-scan-no-empty-passwords OutdatednoteThe currently applied remediation is stored in the
Outdatedattribute and the new, unapplied remediation is stored in theCurrentattribute. If you are satisfied with the new version, remove theOutdatedfield. If you want to keep the updated content, remove theCurrentandOutdatedattributes. -
Apply the newer version of the remediation:
$ oc -n openshift-compliance patch complianceremediations workers-scan-no-empty-passwords \--type json -p '[{"op":"remove", "path":/spec/outdated}]' -
The remediation state will switch from
OutdatedtoApplied:$ oc get -n openshift-compliance complianceremediations workers-scan-no-empty-passwordsExample outputNAME STATEworkers-scan-no-empty-passwords Applied -
Verify that the nodes apply the newer remediation version and reboot.
Unapply a remediation
You can unapply a remediation that was previously applied to roll back a change when you need to revert it.
The Compliance Operator does not automatically resolve dependency issues that can occur between remediations. Users should perform a rescan after remediations are applied to ensure accurate results.
Procedure
-
Set the
applyflag tofalse:$ oc -n openshift-compliance \patch complianceremediations/rhcos4-moderate-worker-sysctl-net-ipv4-conf-all-accept-redirects \--patch '{"spec":{"apply":false}}' --type=merge -
Verify that the remediation status has changed to
NotAppliedand the compositeMachineConfigobject is re-rendered to not include the remediation.warningAll affected nodes with the remediation will be rebooted.
Remove a KubeletConfig remediation
KubeletConfig remediations are included in node-level profiles. To remove a KubeletConfig remediation, you must manually remove it from the KubeletConfig objects.
Procedure
-
Locate the
scan-nameand compliance check for theone-rule-tp-node-master-kubelet-eviction-thresholds-set-hard-imagefs-availableremediation:$ oc -n openshift-compliance get remediation \ one-rule-tp-node-master-kubelet-eviction-thresholds-set-hard-imagefs-available -o yamlExample outputapiVersion: compliance.openshift.io/v1alpha1kind: ComplianceRemediationmetadata:annotations:compliance.openshift.io/xccdf-value-used: var-kubelet-evictionhard-imagefs-availablecreationTimestamp: "2022-01-05T19:52:27Z"generation: 1labels:compliance.openshift.io/scan-name: one-rule-tp-node-mastercompliance.openshift.io/suite: one-rule-ssb-nodename: one-rule-tp-node-master-kubelet-eviction-thresholds-set-hard-imagefs-availablenamespace: openshift-complianceownerReferences:- apiVersion: compliance.openshift.io/v1alpha1blockOwnerDeletion: truecontroller: truekind: ComplianceCheckResultname: one-rule-tp-node-master-kubelet-eviction-thresholds-set-hard-imagefs-availableuid: fe8e1577-9060-4c59-95b2-3e2c51709adcresourceVersion: "84820"uid: 5339d21a-24d7-40cb-84d2-7a2ebb015355spec:apply: truecurrent:object:apiVersion: machineconfiguration.openshift.io/v1kind: KubeletConfigspec:kubeletConfig:evictionHard:imagefs.available: 10%outdated: {}type: Configurationstatus:applicationState: Appliedwhere:
-
metadata.labels.compliance.openshift.io/scan-namespecifies the scan name of the remediation. -
spec.current.object.spec.kubeletConfig.evictionHard.imagefs.availablespecifies the remediation that was added to theKubeletConfigobjects.noteIf the remediation invokes an
evictionHardkubelet configuration, you must specify all of theevictionHardparameters:memory.available,nodefs.available,nodefs.inodesFree,imagefs.available, andimagefs.inodesFree. If you do not specify all parameters, only the specified parameters are applied and the remediation will not function properly.
-
-
Remove the remediation:
-
Set
applyto false for the remediation object:$ oc -n openshift-compliance patch \complianceremediations/one-rule-tp-node-master-kubelet-eviction-thresholds-set-hard-imagefs-available \-p '{"spec":{"apply":false}}' --type=merge -
Using the
scan-name, find theKubeletConfigobject that the remediation was applied to:$ oc -n openshift-compliance get kubeletconfig \--selector compliance.openshift.io/scan-name=one-rule-tp-node-masterExample outputNAME AGEcompliance-operator-kubelet-master 2m34s -
Manually remove the remediation,
imagefs.available: 10%, from theKubeletConfigobject:$ oc edit -n openshift-compliance KubeletConfig compliance-operator-kubelet-masterwarningAll affected nodes with the remediation will be rebooted.
noteYou must also exclude the rule from any scheduled scans in your tailored profiles that auto-applies the remediation, otherwise, the remediation will be re-applied during the next scheduled scan.
-
Inconsistent ComplianceScan
The ScanSetting object lists the node roles that the compliance scans generated from the ScanSetting or ScanSettingBinding objects would scan. Each node role usually maps to a machine config pool.
All machines in a machine config pool are expected to be identical and all scan results from the nodes in a pool should be identical.
If a compliance scan results in an INCONSISTENT result, re-run the compliance scan to get a consistent result by annotating the scan with the compliance.openshift.io/rescan= option.
The ScanSetting object lists the node roles that the compliance scans generated from the ScanSetting or ScanSettingBinding objects would scan. Each node role usually maps to a machine config pool.
Because the number of machines in a pool might be quite large, the Compliance Operator attempts to find the most common state and list the nodes that differ from the common state. The most common state is stored in the compliance.openshift.io/most-common-status annotation and the annotation compliance.openshift.io/inconsistent-source contains pairs of hostname:status of check statuses that differ from the most common status. If no common state can be found, all the hostname:status pairs are listed in the compliance.openshift.io/inconsistent-source annotation.
If possible, a remediation is still created so that the cluster can converge to a compliant status. However, this might not always be possible and correcting the difference between nodes must be done manually.
Procedure
- Re-run the compliance scan to get a consistent result by annotating the scan with the
compliance.openshift.io/rescan=option:$ oc -n openshift-compliance \annotate compliancescans/rhcos4-e8-worker compliance.openshift.io/rescan=
Additional resources