Supporting DISA-STIG with the Compliance Operator on the Red Hat OpenShift Container Platform
Author: Kaushik Talathi
The Compliance Operator is an optional operator that allows an administrator to run compliance scans and recommends remediations to keep the cluster's compliance to compliance standards. The Compliance Operator runs a profile assess the platform’s nodes and Kubernetes API resources. Each check is described in OpenSCAP, a NIST-certified tool, and describes how to scan and enforce security policies. You can see the content as it is described in opensource.
This article describes how to use and work with the Red Hat DISA STIG profiles, and remediate the findings for ocp4-stig and ocp4-stig-node.
To install the Compliance Operator on your OpenShift Container Platform 4.17 or higher system, go to the OperatorHub:
-
Login with a user id that has cluster-admin user access
-
In the OpenShift Container Platform web console, navigate to Operators → OperatorHub.
-
Search for the Compliance Operator, then click Install.
-
Keep the default selection of Installation mode and namespace to ensure that the Operator will be installed to the openshift-compliance
namespace.
-
Click Install.
-
Verify the installation succeeded by inspecting the CSV file:
$ oc project openshift-compliance
Now using project "openshift-compliance" on server "https://****.****.****:6443".
$ oc get csv
NAME DISPLAY VERSION REPLACES PHASE
compliance-operator.v1.7.0 Compliance Operator 1.7.0 Succeeded
- Verify that the Compliance Operator is up and running
$ oc get deploy -n openshift-compliance
NAME READY UP-TO-DATE AVAILABLE AGE
compliance-operator 1/1 1 1 3m25s
ocp4-openshift-compliance-pp 1/1 1 1 2m49s
- Check the pods created for Compliance operator through the command line interface:
$ oc get pods
NAME READY STATUS RESTARTS AGE
compliance-operator-866488784f-pkr9m 1/1 Running 0 3m34s
ocp4-openshift-compliance-pp-6c747c677c-45kr4 1/1 Running 0 2m58s
- Verify DISA-STIG Profiles are installed
$ oc get -n openshift-compliance profiles.compliance
NAME AGE
ocp4-stig 6d1h
ocp4-stig-node 6d1h
ocp4-stig-v2r2 6d1h
ocp4-stig-node-v2r2 6d1h
As per above output you can see that DISA-STIG profiles are installed.
Run a DISA-STIG compliance Scan and Check the Scan Output
To make your OpenShift Cluster DISA-STIG Profile compliant, you need to check the status for all compliance check results and apply appropriate remediations.
To start scan, create ScanSettingBinding. Scan will be started immediately after creation.
-
Use OpenShift Container Platform web console to create a ScanSettingBinding
-
Add ocp4-stig and ocp4-stig-node for DISA-STIG compliance to ScanSettingBinding
apiVersion: compliance.openshift.io/v1alpha1
kind: ScanSettingBinding
metadata:
name: disa-stig
namespace: openshift-compliance
profiles:
- apiGroup: compliance.openshift.io/v1alpha1
kind: Profile
name: ocp4-stig
- apiGroup: compliance.openshift.io/v1alpha1
kind: Profile
name: ocp4-stig-node
settingsRef:
name: default
kind: ScanSetting
apiGroup: compliance.openshift.io/v1alpha1
- Use CLI to check the scan
$ oc get compliancescan -n openshift-compliance
NAME PHASE RESULT
ocp4-stig RUNNING NOT-AVAILABLE
ocp4-stig-node-master RUNNING NOT-AVAILABLE
ocp4-stig-node-worker LAUNCHING NOT-AVAILABLE
When compliance scan is completed, you'll see COMPLIANT or NON-COMPLIANT.
$ oc get compliancescan -n openshift-compliance
NAME PHASE RESULT
ocp4-stig Done NON-COMPLIANT
ocp4-stig-node-master Done NON-COMPLIANT
ocp4-stig-node-worker Done NON-COMPLIANT
- To check the compliance check results, run below command:
$ oc get compliancecheckresult -n openshift-compliance | grep stig
ocp4-stig-rbac-logging-mod MANUAL medium
...
ocp4-stig-oauth-logout-url-set FAIL medium
ocp4-stig-audit-profile-set PASS medium
- To check only the failed results, run below command:
$ oc get compliancecheckresult -n openshift-compliance | grep stig | grep FAIL
ocp4-stig-imagestream-sets-schedule FAIL medium
...
ocp4-stig-oauth-logout-url-set FAIL medium
ocp4-stig-ocp-allowed-registries FAIL medium
Remediating the failed results
You can run the auto-remediation script to fix a number of the results. Replace <scan-name>
with the actual scan name.
One by one run for all the scans. To get the list of scans, run below command
$ oc get compliancescan -n openshift-compliance
NAME PHASE RESULT
ocp4-stig Done NON-COMPLIANT
ocp4-stig-node-master Done NON-COMPLIANT
ocp4-stig-node-worker Done NON-COMPLIANT
for REMEDIATION in $(oc get compliancecheckresults.compliance -l 'compliance.openshift.io/scan-name in (<scan-name>)' --no-headers | grep -v PASS | awk '{print $1}'); do
echo "REMEDIATION ${REMEDIATION}"
FOUND=$((oc get complianceremediations ${REMEDIATION} 1>&2 && echo "0") || echo "1")
echo $FOUND
if [[ "${FOUND}" == "0" ]]
then
oc -n openshift-compliance patch complianceremediations/${REMEDIATION} --patch '{"spec":{"apply":true}}' --type=merge
fi
done
Once the auto-remediation if applied, the remaining results can be fixed manually:
- ocp4-stig-container-security-operator-exists
Install the 'Red Hat Quay Container Security Operator' with default settings from OperatorHub in RedHat Openshift Container Platform Console. To verify the installation, run following command:
$ oc get sub -nopenshift-operators container-security-operator -ojsonpath='{.status.installedCSV}'
container-security-operator.v3.12.3
- ocp4-stig-configure-network-policies-namespaces
Confirm the non-default / system namespaces have NetworkPolicies. The following script shows the ones which fail to have NetworkPolicies.
for NAMESPACE in $(oc get namespaces -o json | jq -r '.items[] | select((.metadata.name | startswith("openshift") | not) and (.metadata.name | startswith("kube-") | not) and .metadata.name != "default") | .metadata.name')
do
TOTAL_NETWORK_POLICIES=$(oc get -n ${NAMESPACE} networkpolicies -ojson | jq -r '.items[].metadata.name')
if [ -z "${TOTAL_NETWORK_POLICIES}" ]
then
echo "NAMESPACE: ${NAMESPACE}"
oc get -n ${NAMESPACE} networkpolicies -ojson | jq -r '.items[].metadata.name'
fi
done
You have to create the polices in non-defaults namespaces based on the instructions mentioned in the rule.
for NAMESPACE in $(oc get namespaces -o json | jq -r '.items[] | select((.metadata.name | startswith("openshift") | not) and (.metadata.name | startswith("kube-") | not) and .metadata.name != "default") | .metadata.name')
do
TOTAL_NETWORK_POLICIES=$(oc get -n ${NAMESPACE} networkpolicies -ojson | jq -r '.items[].metadata.name')
if [ -z "${TOTAL_NETWORK_POLICIES}" ]
then
echo "NAMESPACE: ${NAMESPACE}"
cat << EOF | oc apply -n ${NAMESPACE} -f -
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
status: {}
---
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-from-same-namespace
spec:
ingress:
- from:
- podSelector: {}
podSelector: {}
policyTypes:
- Ingress
status: {}
EOF
oc get -n ${NAMESPACE} networkpolicies -ojson | jq -r '.items[].metadata.name'
fi
done
- ocp4-stig-classification-banner
Add a banner to display to users before granting access to the system that provides privacy and security notices consistent with applicable federal laws Apply following to create a notification banner and customize text and location as per needs.
apiVersion: console.openshift.io/v1
kind: ConsoleNotification
metadata:
name: classification-banner
spec:
text: "This is an example legal notice. Please replace with actual notice as per use."
location: BannerTop
To verify if the notification banner is correctly configured run following command or refresh the Red Hat OpenShift web Console and see if the banner is displayed.
$ oc get consolenotifications -n openshift-logging
NAME TEXT LOCATION AGE
classification-banner This is an example legal notice. Please replace with actual notice as per use. BannerTop 26m
- ocp4-test-imagestream-sets-schedule
All configured ImageStreams are configured to periodically check for updates. The configuration imagestream.spec.tags.importPolicy.scheduled
determines whether the imagestream is configured to periodically check for updates. This is useful when working with an external container image registry, to periodically re-import an image, for example to get latest security updates. You can set the scheduled update by running following script.
for NAME_NAMESPACE in $(oc get imagestreams -A -ojson | jq -r '.items[] | select(.spec.tags[]?.importPolicy.scheduled != true) | "\(.metadata.name),\(.metadata.namespace)"' | sort | uniq); do
NAME=$(echo ${NAME_NAMESPACE} | awk -F',' '{print $1}')
NAMESPACE=$(echo ${NAME_NAMESPACE} | awk -F',' '{print $2}')
IDX=0
for TAG in $(oc get imagestream -n ${NAMESPACE} ${NAME} -ojson | jq -r '.spec.tags[].name'); do
STATUS=$(oc patch -n ${NAMESPACE} imagestream/${NAME} -p '[{"op": "replace", "path": "/spec/tags/'${IDX}'/importPolicy/scheduled", "value": true}]' --type=json 2>&1 | grep 'is invalid')
if [ ! -z "${STATUS}" ]; then
echo "FAILING: ${NAMESPACE},${NAME},${TAG}"
fi
(( IDX += 1 ))
done
done
- ocp4-stig-oauth-login-template-set
To verify that login template is properly set, run:
$ oc get oauth cluster -o jsonpath='{.spec.templates.login.name}'
login-template
If the login template is not set, follow steps given in: Customizing the login page for Red Hat OCP Console
- ocp4-stig-oauth-logout-url-set
To verify that the logout redirect is set, do the following:
$ oc get console.config.openshift.io cluster -o jsonpath='{.spec.authentication.logoutRedirect}{"\n"}'
https://example.com
Make sure that the command returns the expected logout URL. To set the logout url run following command:
oc patch console cluster --type merge -p '{"spec":{"authentication":{"logoutRedirect":"https://example.com"}}}'
Note: Replace the https://example.com
with actual url that you want to redirect to after logout.
- ocp4-stig-openshift-motd-exists
Display of a standardized and approved use notification before granting access to the system ensures privacy and security notification verbiage used is consistent with applicable federal laws, Executive Orders, directives, policies, regulations, standards, and guidance.
Configure motd with following script:
apiVersion: v1
kind: ConfigMap
metadata:
name: motd
namespace: openshift
data:
message: "A test MOTD"
Note: Replace the message
with relevant legal message for your organization.
To verify that the MOTD is properly set, run the following command:
$ oc get configmaps -n openshift motd -ojsonpath='{.data.message}'
A test MOTD
After remediating, you must should re-run the scan. Replace <scan-name>
with the actual scan name.
$ oc -n openshift-compliance annotate compliancescans/<scan-name> compliance.openshift.io/rescan=
compliancescan.compliance.openshift.io/<scan-name> annotated
$ oc get compliancescan -n openshift-compliance
NAME PHASE RESULT
ocp4-stig Done COMPLIANT
ocp4-stig-node-master Done COMPLIANT
ocp4-stig-node-worker Done COMPLIANT
Wait for the scanning to complete and check if the compliance check result are Passed
$ oc get compliancecheckresult -n openshift-compliance | grep stig
ocp4-stig-imagestream-sets-schedule PASS medium
...
ocp4-stig-oauth-logout-url-set PASS medium
ocp4-stig-ocp-allowed-registries PASS medium
At this point, you should review the MANUAL rules, and confirm you application and environment is compliant.
This post you’ve seen how to use and remediate findings for the Red Hat Openshift Container Platform DISA-STIG profiles. Thanks for reading! I hope you found this helpful!