Skip to content

Fix crypto policy check/remediation on RHCOS 10 (CMP-4632) - #15095

Open
yuumasato wants to merge 1 commit into
ComplianceAsCode:masterfrom
yuumasato:fix-cmp4632-crypto-policy-rhcos10
Open

Fix crypto policy check/remediation on RHCOS 10 (CMP-4632)#15095
yuumasato wants to merge 1 commit into
ComplianceAsCode:masterfrom
yuumasato:fix-cmp4632-crypto-policy-rhcos10

Conversation

@yuumasato

Copy link
Copy Markdown
Member

Description

On RHEL 10 the DEFAULT crypto policy already disables SHA-1, and the NO-SHA1 subpolicy module no longer exists. The rhcos4 e8 profile pins var_system_crypto_policy=DEFAULT:NO-SHA1, so on RHCOS 10 nodes:

  • the MachineConfig remediation runs update-crypto-policies --set DEFAULT:NO-SHA1, which fails with Unknown policy 'NO-SHA1': file 'NO-SHA1.pmod' not found, and
  • the OVAL check exact-matches DEFAULT:NO-SHA1 against the on-disk policy (which is DEFAULT),

leaving configure_crypto_policy stuck at FAIL after remediation.

The rhcos4 product spans RHEL8/9 and RHEL10 nodes under one profile, so the expected value cannot be set per-node via the profile variable. This fixes it at scan time, scoped to rhcos4.

Changes

  • configure_crypto_policy/kubernetes/shared.yml — the MachineConfig ExecStart now detects the RHEL base from /etc/os-release and strips a trailing :NO-SHA1 on VERSION_ID >= 10 before applying the policy. Functional no-op on RHEL8/9 and on the rhel/fedora datastreams (their profiles never request :NO-SHA1).
  • configure_crypto_policy/oval/rhcos4.xml (new) — product-specific OVAL override that keeps the exact DEFAULT:NO-SHA1 match on RHEL8/9-based nodes and, on RHEL10-based nodes (gated by installed_OS_is_rhcos4_rhel10), compares the on-disk policy against the :NO-SHA1-stripped effective value. The shared OVAL is untouched, so rhel9/rhel10 datastreams are unchanged.

bash and ansible remediations are left as-is — RHCOS applies only the MachineConfig remediation.

Rationale

This mirrors the existing enable_fips_mode/oval/rhcos4.xml product-override precedent and reuses the already-present installed_OS_is_rhcos4_rhel10 inventory check. It keeps RHEL8/9 rhcos4 behavior byte-identical and leaves the rhel9/rhel10 products entirely unchanged.

Verification

Build:

  • ./build_product rhcos4 --rule-id configure_crypto_policy and ./build_product rhel10 --rule-id configure_crypto_policy build clean.
  • rhcos4 datastream gains the OR/two-branch OVAL, the regex_capture effective-value variable, and the version-detecting ExecStart; rhel10 OVAL is unchanged and its k8s fix is a functional no-op.

On a live OCP 5.0.0 / RHCOS 10.2 cluster with the Compliance Operator:

  • Reproduced the bug on a node: update-crypto-policies --set DEFAULT:NO-SHA1 → exit 1 (Unknown policy 'NO-SHA1').
  • Fixed remediation logic on the node: strips to DEFAULTupdate-crypto-policies --set DEFAULT → exit 0.
  • A/B scan on the same nodes: shipped rhcos4-e8FAIL (master & worker); fixed content → PASS (master & worker).

🤖 Generated with Claude Code

On RHEL 10 the DEFAULT crypto policy already disables SHA-1, and the
NO-SHA1 subpolicy module no longer exists. On RHCOS 10 nodes the e8
profile pins var_system_crypto_policy=DEFAULT:NO-SHA1, so:

- the MachineConfig remediation runs
  "update-crypto-policies --set DEFAULT:NO-SHA1", which fails with
  "Unknown policy NO-SHA1", and
- the OVAL check exact-matches DEFAULT:NO-SHA1 against the on-disk
  policy, which is DEFAULT,

leaving configure_crypto_policy stuck at FAIL after remediation.

The rhcos4 product spans RHEL8/9 and RHEL10 nodes under one profile, so
the expected value cannot be set per-node via the profile variable. Fix
it scan-time, scoped to rhcos4:

- kubernetes/shared.yml: the MachineConfig ExecStart now detects the
  RHEL base from /etc/os-release and strips a trailing :NO-SHA1 on
  VERSION_ID >= 10 before applying the policy. No-op on RHEL8/9 and on
  rhel/fedora datastreams (their profiles never request :NO-SHA1).
- oval/rhcos4.xml (new): product-specific OVAL override that keeps the
  exact DEFAULT:NO-SHA1 match on RHEL8/9-based nodes and, on
  RHEL10-based nodes (gated by installed_OS_is_rhcos4_rhel10), compares
  the on-disk policy against the :NO-SHA1-stripped effective value. The
  shared OVAL is untouched, so rhel9/rhel10 datastreams are unchanged.

bash and ansible remediations are left as-is (RHCOS applies only the
MachineConfig remediation).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@github-actions

github-actions Bot commented Sep 4, 2026

Copy link
Copy Markdown
Contributor

This datastream diff is auto generated by the check Compare DS/Generate Diff

Click here to see the full diff
kubernetes remediation for rule 'xccdf_org.ssgproject.content_rule_configure_crypto_policy' differs.
--- xccdf_org.ssgproject.content_rule_configure_crypto_policy
+++ xccdf_org.ssgproject.content_rule_configure_crypto_policy
@@ -14,7 +14,7 @@
             Before=kubelet.service
             [Service]
             Type=oneshot
-            ExecStart=update-crypto-policies --set {{.var_system_crypto_policy}}
+            ExecStart=/bin/bash -c 'source /etc/os-release; policy="{{.var_system_crypto_policy}}"; if [ "${VERSION_ID%%.*}" -ge 10 ]; then policy="${policy%%:NO-SHA1}"; fi; update-crypto-policies --set "$policy"'
             RemainAfterExit=yes
             [Install]
             WantedBy=multi-user.target

@yuumasato

Copy link
Copy Markdown
Member Author

Additional verification — RHCOS 9 regression (OCP 4.22 / RHCOS 9.8)

Re-ran the same A/B on a RHEL9-based cluster to confirm the fix is a no-op on el9 and that the el10 relaxation does not leak.

On-node (RHCOS 9.8): VERSION_ID=9.8, major 9no stripupdate-crypto-policies --set DEFAULT:NO-SHA1 → exit 0 (NO-SHA1 still exists on RHEL9). Remediation unchanged on el9.

Operator A/B, all nodes at DEFAULT:

Content master worker
shipped rhcos4-e8 (expects DEFAULT:NO-SHA1) FAIL FAIL
fixed cmp4632-rhcos4-e8 FAIL FAIL

Identical results — fixed behaves exactly like shipped on el9, and plain DEFAULT is still correctly rejected (the relaxed comparison is gated behind installed_OS_is_rhcos4_rhel10).

This is the intended contrast with the el10 run:

  • el10, node=DEFAULT → fixed PASS (:NO-SHA1 dropped)
  • el9, node=DEFAULT → fixed FAIL (:NO-SHA1 still required)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant