-
Notifications
You must be signed in to change notification settings - Fork 231
USHIFT-6973 Add CIS Level2 Smoke Testing #7041
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
openshift-merge-bot
merged 6 commits into
openshift:main
from
copejon:ushift-6973-cis-testing
Jul 22, 2026
Merged
Changes from all commits
Commits
Show all changes
6 commits
Select commit
Hold shift + click to select a range
156cedf
Add CIS Level 2 hardening playbooks and ansible role requirements
copejon ba58f7b
Add CIS Level 2 delta test for MicroShift on RHEL 9 and 10
copejon eaed9ee
Add CIS Level 2 hardening guide for MicroShift
copejon 027f084
Apply CodeRabbit suggestions from PR #7041
copejon 3403c0f
Fix robocop lint violations in CIS test suite
copejon b943da2
Address reviewer feedback on CIS hardening docs and test assets
copejon File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,107 @@ | ||
| # CIS Level 2 Hardening for MicroShift | ||
|
|
||
| This guide describes how to run MicroShift on a CIS Level 2 hardened RHEL system. It covers which CIS rules MicroShift affects, the required hardening playbook overrides, and how to verify compliance. | ||
|
|
||
| ## MicroShift's CIS Impact | ||
|
|
||
| MicroShift introduces changes to a hardened system in three categories. These rules will fail on any system running Kubernetes containers and cannot be avoided without disabling core functionality. | ||
|
|
||
| ### IP Forwarding | ||
|
|
||
| OVN-Kubernetes requires IP forwarding for pod networking. MicroShift enables `net.ipv4.ip_forward` and `net.ipv6.conf.all.forwarding` at startup. | ||
|
|
||
| | Rule ID | RHEL 9 | RHEL 10 | | ||
| |:--------|:------:|:-------:| | ||
| | `sysctl_net_ipv4_ip_forward` | x | x | | ||
| | `sysctl_net_ipv6_conf_all_forwarding` | x | x | | ||
| | `sysctl_net_ipv4_conf_all_forwarding` | | x | | ||
| | `sysctl_net_ipv4_conf_default_forwarding` | | x | | ||
| | `sysctl_net_ipv6_conf_default_forwarding` | | x | | ||
|
|
||
| ### Container File Ownership | ||
|
|
||
| Container images contain files owned by UIDs and GIDs that do not exist in the host's `/etc/passwd` and `/etc/group`. These are stored in `/var/lib/containers/storage/overlay/` and are an inherent characteristic of any container runtime. | ||
|
|
||
| | Rule ID | RHEL 9 | RHEL 10 | | ||
| |:--------|:------:|:-------:| | ||
| | `file_permissions_ungroupowned` | x | | | ||
| | `no_files_unowned_by_user` | x | | | ||
| | `no_files_or_dirs_ungroupowned` | | x | | ||
| | `no_files_or_dirs_unowned_by_user` | | x | | ||
|
|
||
| ### Kubelet Volume Permissions | ||
|
|
||
| Kubelet creates 0777 directories for ConfigMap and EmptyDir volumes so that pods running as any UID can access their projected configuration. It also creates 0666 container termination log files. | ||
|
|
||
| | Rule ID | RHEL 9 | RHEL 10 | | ||
| |:--------|:------:|:-------:| | ||
| | `dir_perms_world_writable_sticky_bits` | x | x | | ||
| | `file_permissions_unauthorized_world_writable` | x | x | | ||
|
|
||
| ### Audit Rules | ||
|
|
||
| CIS requires audit rules for all setuid/setgid binaries. If MicroShift is installed after running the CIS hardening role, the audit rules will not cover binaries added by MicroShift RPMs. | ||
|
|
||
| | Rule ID | RHEL 9 | RHEL 10 | | ||
| |:--------|:------:|:-------:| | ||
| | `audit_rules_privileged_commands` | x | x | | ||
|
|
||
| This rule can be resolved by regenerating audit rules after installing MicroShift: | ||
|
|
||
| ```bash | ||
| sudo find / -xdev \( -perm -4000 -o -perm -2000 \) -type f 2>/dev/null | \ | ||
| awk '{print "-a always,exit -F path=" $1 " -F perm=x -F auid>=1000 -F auid!=unset -k privileged"}' | \ | ||
| sudo tee /etc/audit/rules.d/99-privileged-post-install.rules > /dev/null | ||
| sudo augenrules --load | ||
| ``` | ||
|
|
||
| ## Hardening Playbook Overrides | ||
|
|
||
| When using the RedHatOfficial CIS ansible roles, the hardening playbook must override the IP forwarding variables to prevent the role from disabling forwarding before MicroShift starts. | ||
|
|
||
| For RHEL 9: | ||
|
|
||
| ```yaml | ||
| --- | ||
| - name: Apply CIS Level 2 hardening | ||
| hosts: localhost | ||
| connection: local | ||
| become: true | ||
| roles: | ||
| - role: ansible-role-rhel9-cis | ||
| vars: | ||
| sysctl_net_ipv4_ip_forward: false | ||
| sysctl_net_ipv6_conf_all_forwarding: false | ||
| ``` | ||
|
|
||
| For RHEL 10, the CIS benchmark adds per-interface forwarding checks: | ||
|
|
||
| ```yaml | ||
| --- | ||
| - name: Apply CIS Level 2 hardening | ||
| hosts: localhost | ||
| connection: local | ||
| become: true | ||
| roles: | ||
| - role: ansible-role-rhel10-cis | ||
| vars: | ||
| sysctl_net_ipv4_ip_forward: false | ||
| sysctl_net_ipv4_conf_all_forwarding: false | ||
| sysctl_net_ipv4_conf_default_forwarding: false | ||
| sysctl_net_ipv6_conf_all_forwarding: false | ||
| sysctl_net_ipv6_conf_default_forwarding: false | ||
| ``` | ||
|
|
||
| > Each variable is set to `false` to tell the role **not** to disable forwarding. This does not enable forwarding — MicroShift does that at startup. | ||
|
|
||
| ## Firewall Configuration | ||
|
|
||
| CIS hardening enables `firewalld` and locks down all traffic. MicroShift requires several ports and trusted network sources to be opened as described in [Firewall Configuration](howto_firewall.md). | ||
|
|
||
| ## References | ||
|
|
||
| - [RedHatOfficial ansible-role-rhel9-cis](https://github.com/RedHatOfficial/ansible-role-rhel9-cis) | ||
| - [RedHatOfficial ansible-role-rhel10-cis](https://github.com/RedHatOfficial/ansible-role-rhel10-cis) | ||
| - [OpenSCAP Project](https://www.open-scap.org/) | ||
| - [CIS Benchmarks](https://www.cisecurity.org/cis-benchmarks) | ||
| - [Firewall Configuration](howto_firewall.md) | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,16 @@ | ||
| --- | ||
| - name: Apply CIS Level 2 hardening | ||
| hosts: localhost | ||
| connection: local | ||
| become: true | ||
| roles: | ||
| - role: ansible-role-rhel10-cis | ||
| vars: | ||
| # MicroShift OVN networking requires IP forwarding | ||
| sysctl_net_ipv4_ip_forward: false | ||
| sysctl_net_ipv4_conf_all_forwarding: false | ||
| sysctl_net_ipv4_conf_default_forwarding: false | ||
| sysctl_net_ipv6_conf_all_forwarding: false | ||
| sysctl_net_ipv6_conf_default_forwarding: false | ||
| # CI requires passwordless sudo | ||
| sudo_remove_nopasswd: false |
|
copejon marked this conversation as resolved.
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,13 @@ | ||
| --- | ||
| - name: Apply CIS Level 2 hardening | ||
| hosts: localhost | ||
| connection: local | ||
| become: true | ||
| roles: | ||
| - role: ansible-role-rhel9-cis | ||
| vars: | ||
| # MicroShift OVN networking requires IP forwarding | ||
| sysctl_net_ipv4_ip_forward: false | ||
| sysctl_net_ipv6_conf_all_forwarding: false | ||
| # CI requires passwordless sudo | ||
| sudo_remove_nopasswd: false |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,7 @@ | ||
| roles: | ||
| - name: ansible-role-rhel10-cis | ||
| src: https://github.com/RedHatOfficial/ansible-role-rhel10-cis | ||
| version: "0.1.80" | ||
| collections: | ||
| - community.general | ||
| - ansible.posix |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,7 @@ | ||
| roles: | ||
| - name: ansible-role-rhel9-cis | ||
| src: https://github.com/RedHatOfficial/ansible-role-rhel9-cis | ||
|
ggiguash marked this conversation as resolved.
|
||
| version: "0.1.80" | ||
| collections: | ||
| - community.general | ||
| - ansible.posix | ||
154 changes: 154 additions & 0 deletions
154
test/scenarios-bootc/el10/periodics/el102-src@cis-lvl2.sh
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,154 @@ | ||
| #!/bin/bash | ||
|
|
||
| # Sourced from scenario.sh and uses functions defined there. | ||
|
|
||
| # CIS hardening runs inside the Robot suite and takes ~20 minutes | ||
| # shellcheck disable=SC2034 # used elsewhere | ||
| TEST_EXECUTION_TIMEOUT=60m | ||
|
|
||
| # The RPM-based image used to create the VM for this test does not | ||
| # include MicroShift or greenboot, so tell the framework not to wait | ||
| # for greenboot to finish when creating the VM. | ||
| export SKIP_GREENBOOT=true | ||
|
coderabbitai[bot] marked this conversation as resolved.
|
||
|
|
||
| configure_microshift_mirror() { | ||
| local -r repo=$1 | ||
|
|
||
| if [[ -z "${repo}" ]] ; then | ||
| return | ||
| fi | ||
|
|
||
| if [[ ! "${repo}" =~ ^http ]]; then | ||
| return | ||
| fi | ||
|
|
||
| local -r tmp_file=$(mktemp) | ||
| tee "${tmp_file}" >/dev/null <<EOF | ||
| [microshift-mirror-rpms] | ||
| name=MicroShift Mirror | ||
| baseurl=${repo} | ||
| enabled=1 | ||
| gpgcheck=0 | ||
| skip_if_unavailable=0 | ||
| EOF | ||
| copy_file_to_vm host1 "${tmp_file}" "${tmp_file}" | ||
| run_command_on_vm host1 "sudo cp ${tmp_file} /etc/yum.repos.d/microshift-mirror-rpms.repo" | ||
| rm -f "${tmp_file}" | ||
| } | ||
|
|
||
| # On RHEL 10, rhocp and fast-datapath repos are not available via | ||
| # subscription-manager. Create repo files pointing to the RHEL 9 CDN | ||
| # using entitlement certificates as a workaround. | ||
| configure_cdn_repo() { | ||
| local -r repo_id=$1 | ||
| local -r repo_name=$2 | ||
| local -r baseurl=$3 | ||
|
|
||
| local -r cert=$(run_command_on_vm host1 "ls /etc/pki/entitlement/[0-9]*.pem | grep -v '\-key.pem' | head -n1") | ||
| local -r key=$(run_command_on_vm host1 "ls /etc/pki/entitlement/[0-9]*-key.pem | head -n1") | ||
| local -r tmp_file=$(mktemp) | ||
|
|
||
| tee "${tmp_file}" >/dev/null <<EOF | ||
| [${repo_id}] | ||
| name=${repo_name} | ||
| baseurl=${baseurl} | ||
| enabled=1 | ||
| gpgcheck=1 | ||
| gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-redhat-release | ||
| sslverify=1 | ||
| sslcacert=/etc/rhsm/ca/redhat-uep.pem | ||
| sslclientcert=${cert} | ||
| sslclientkey=${key} | ||
| EOF | ||
| copy_file_to_vm host1 "${tmp_file}" "${tmp_file}" | ||
| run_command_on_vm host1 "sudo cp ${tmp_file} /etc/yum.repos.d/${repo_id}.repo" | ||
| rm -f "${tmp_file}" | ||
| } | ||
|
|
||
| configure_rhocp_repo() { | ||
| local -r rhocp=$1 | ||
| local -r major=$2 | ||
| local -r minor=$3 | ||
| local -r arch=${4:-$(uname -m)} | ||
|
|
||
| if [[ -z "${rhocp}" ]] ; then | ||
| return | ||
| fi | ||
|
|
||
| if [[ "${rhocp}" =~ ^[0-9]{1,2}$ ]]; then | ||
| configure_cdn_repo \ | ||
| "rhocp-${major}.${rhocp}" \ | ||
| "Red Hat OpenShift ${major}.${rhocp} for RHEL 9" \ | ||
| "https://cdn.redhat.com/content/dist/layered/rhel9/${arch}/rhocp/${major}.${rhocp}/os" | ||
|
coderabbitai[bot] marked this conversation as resolved.
|
||
| elif [[ "${rhocp}" =~ ^http ]]; then | ||
| local -r ocp_repo_name="rhocp-${major}.${minor}-for-rhel-9-mirrorbeta-rpms" | ||
| local -r tmp_file=$(mktemp) | ||
|
|
||
| tee "${tmp_file}" >/dev/null <<EOF | ||
| [${ocp_repo_name}] | ||
| name=Beta rhocp RPMs for RHEL 9 | ||
| baseurl=${rhocp} | ||
| enabled=1 | ||
| gpgcheck=0 | ||
| skip_if_unavailable=0 | ||
| EOF | ||
| copy_file_to_vm host1 "${tmp_file}" "${tmp_file}" | ||
| run_command_on_vm host1 "sudo cp ${tmp_file} /etc/yum.repos.d/${ocp_repo_name}.repo" | ||
| rm -f "${tmp_file}" | ||
| fi | ||
| } | ||
|
|
||
| scenario_create_vms() { | ||
| prepare_kickstart host1 kickstart-liveimg.ks.template "" | ||
| launch_vm rhel102-installer | ||
|
|
||
| configure_vm_firewall host1 | ||
| subscription_manager_register host1 | ||
|
|
||
| # Configure repositories for MicroShift and its dependencies. | ||
| # MicroShift is NOT installed here — the Robot suite installs it | ||
| # after CIS hardening so the scan reveals what MicroShift changes. | ||
| local -r source_reponame=$(basename "${LOCAL_REPO}") | ||
| local -r source_repo_url="${WEB_SERVER_URL}/rpm-repos/${source_reponame}" | ||
| local -r arch=$(run_command_on_vm host1 "uname -m") | ||
|
|
||
| configure_rhocp_repo "${RHOCP_MINOR_Y}" "${MAJOR_VERSION}" "${MINOR_VERSION}" "${arch}" | ||
| configure_rhocp_repo "${RHOCP_MINOR_Y_BETA}" "${MAJOR_VERSION}" "${MINOR_VERSION}" "${arch}" | ||
| configure_rhocp_repo "${RHOCP_MINOR_Y1}" "${PREVIOUS_MAJOR_VERSION}" "${PREVIOUS_MINOR_VERSION}" "${arch}" | ||
| configure_rhocp_repo "${RHOCP_MINOR_Y1_BETA}" "${PREVIOUS_MAJOR_VERSION}" "${PREVIOUS_MINOR_VERSION}" "${arch}" | ||
| configure_microshift_mirror "${PREVIOUS_RELEASE_REPO}" | ||
| run_command_on_vm host1 "sudo subscription-manager release --set 10.2" | ||
| configure_cdn_repo \ | ||
| "fast-datapath" \ | ||
| "Red Hat Fast Datapath for RHEL 9" \ | ||
| "https://cdn.redhat.com/content/dist/layered/rhel9/${arch}/fast-datapath/os" | ||
|
|
||
| # Add the source RPM repo for locally-built MicroShift packages. | ||
| local -r tmp_file=$(mktemp) | ||
| tee "${tmp_file}" >/dev/null <<EOF | ||
| [microshift-local] | ||
| name=MicroShift Local | ||
| baseurl=${source_repo_url} | ||
| enabled=1 | ||
| gpgcheck=0 | ||
| skip_if_unavailable=0 | ||
| EOF | ||
| copy_file_to_vm host1 "${tmp_file}" "${tmp_file}" | ||
| run_command_on_vm host1 "sudo cp ${tmp_file} /etc/yum.repos.d/microshift-local.repo" | ||
| rm -f "${tmp_file}" | ||
|
|
||
| } | ||
|
|
||
| scenario_remove_vms() { | ||
| remove_vm host1 | ||
| } | ||
|
|
||
| scenario_run_tests() { | ||
| # shellcheck disable=SC2034 # used elsewhere | ||
| TEST_RANDOMIZATION=none | ||
| run_tests host1 \ | ||
| --variable "SCAP_DS_FILE:/usr/share/xml/scap/ssg/content/ssg-rhel10-ds.xml" \ | ||
| --variable "CIS_REQUIREMENTS_FILE:cis-requirements-el10.yml" \ | ||
| --variable "CIS_HARDEN_FILE:cis-harden-el10.yml" \ | ||
| suites/cis/ | ||
| } | ||
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.