From a767327bc3859157fc2eabda0bdb04c588563a50 Mon Sep 17 00:00:00 2001 From: shaneboulden Date: Wed, 22 Jan 2025 09:03:38 +1030 Subject: [PATCH 1/2] add UBI version policy and reporting script --- policies/ubi-versions.json | 83 +++++++++++++++++++++++ util-scripts/ubi-versions/README.md | 21 ++++++ util-scripts/ubi-versions/ubi-versions.sh | 70 +++++++++++++++++++ 3 files changed, 174 insertions(+) create mode 100755 policies/ubi-versions.json create mode 100644 util-scripts/ubi-versions/README.md create mode 100755 util-scripts/ubi-versions/ubi-versions.sh diff --git a/policies/ubi-versions.json b/policies/ubi-versions.json new file mode 100755 index 0000000..5b9045f --- /dev/null +++ b/policies/ubi-versions.json @@ -0,0 +1,83 @@ +{ + "policies": [ + { + "id": "53e1d1fb-bc1e-4ef3-98c3-8df0dd5679b8", + "name": "UBI version compliance", + "description": "All images on the cluster using the Red Hat Universal Base Image (UBI) must use at least versions 8.5 or 9.3", + "rationale": "Using an older UBI image potentially exposes the workload to additional vulnerabilities", + "remediation": "Update the base image to at least UBI 8.5 or 9.3", + "disabled": true, + "categories": [ + "Package Management" + ], + "lifecycleStages": [ + "DEPLOY" + ], + "eventSource": "NOT_APPLICABLE", + "exclusions": [ + { + "name": "", + "deployment": { + "name": "", + "scope": { + "cluster": "", + "namespace": "openshift-*", + "label": null + } + }, + "image": null, + "expiration": null + }, + { + "name": "", + "deployment": { + "name": "", + "scope": { + "cluster": "", + "namespace": "stackrox", + "label": null + } + }, + "image": null, + "expiration": null + } + ], + "scope": [], + "severity": "MEDIUM_SEVERITY", + "enforcementActions": [], + "notifiers": [], + "SORTName": "", + "SORTLifecycleStage": "", + "SORTEnforcement": false, + "policyVersion": "1.1", + "policySections": [ + { + "sectionName": "Rule 1", + "policyGroups": [ + { + "fieldName": "Image Component", + "booleanOperator": "OR", + "negate": false, + "values": [ + { + "value": "redhat-release=8\\.[0-4]-[0-9]+(?:\\.[0-9]+)?\\.el8" + }, + { + "value": "redhat-release=9\\.[0-2]-[0-9]+(?:\\.[0-9]+)?\\.el9" + }, + { + "value": "redhat-release=[6-7].*" + } + ] + } + ] + } + ], + "mitreAttackVectors": [], + "criteriaLocked": false, + "mitreVectorsLocked": false, + "isDefault": false, + "source": "IMPERATIVE" + } + ] +} \ No newline at end of file diff --git a/util-scripts/ubi-versions/README.md b/util-scripts/ubi-versions/README.md new file mode 100644 index 0000000..33617e3 --- /dev/null +++ b/util-scripts/ubi-versions/README.md @@ -0,0 +1,21 @@ +# ubi-versions.sh +## Description +This script exports deployments that are using older Red Hat Universal Base Image (UBI) versions into a CSV file. + +Exported values for deployments include: +- Cluster name +- Namespace +- Deployment name +- Image +- Universal Base Image (UBI) version + +## Required environment vars +ROX_ENDPOINT - Host for StackRox central (central.example.com) + +ROX_API_TOKEN - Token data from StackRox API token [How to generate an API Token](https://docs.openshift.com/acs/4.6/configuration/configure-api-token.html) + +## Required policies +This policy relies on the 'UBI version compliance' policy having been imported to the cluster (also available in this repository) + +## Usage +Run the script ./ubi-versions results.csv to generate a file with all deployment information. diff --git a/util-scripts/ubi-versions/ubi-versions.sh b/util-scripts/ubi-versions/ubi-versions.sh new file mode 100755 index 0000000..a653c24 --- /dev/null +++ b/util-scripts/ubi-versions/ubi-versions.sh @@ -0,0 +1,70 @@ +#! /bin/bash +# This script is designed to report on container images that use a specific UBI version. It is designed to be used +# with a policy that creates violations for specific versions of the `redhat-release` package. + +# To use this image, set ROX_ENDPOINT to the ACS central instance and set ROX_API_TOKEN +# to an ACS 'admin' token created. + +# e.g. export ROX_ENDPOINT=central-acs-central.apps.cluster1.example.com:443 +# export ROX_API_TOKEN=eyJhbGciOiJSUzI1NiIsImtpZCI6Imp3dGsw... +# ./ubi-versions.sh images.csv + +set -e + +if [[ -z "${ROX_ENDPOINT}" ]]; then + echo >&2 "ROX_ENDPOINT must be set" + exit 1 +fi + +if [[ -z "${ROX_API_TOKEN}" ]]; then + echo >&2 "ROX_API_TOKEN must be set" + exit 1 +fi + +if [[ -z "$1" ]]; then + echo >&2 "usage: ubi-versions.sh " + exit 1 +fi + +output_file="$1" +echo '"Cluster Name", "Namespace", "Deployment", "Image", "UBI version"' > "${output_file}" + +function curl_central() { + curl -sk -H "Authorization: Bearer ${ROX_API_TOKEN}" "https://${ROX_ENDPOINT}/$1" +} + +# Collect all alerts +res="$(curl_central "v1/alerts?query=Policy%3AUBI%20version%20compliance")" + +# Iterate over all deployments and get the full deployment +for deployment_id in $(echo "${res}" | jq -r .alerts[].deployment.id); do + deployment_res="$(curl_central "v1/deployments/${deployment_id}")" + if [[ "$(echo "${deployment_res}" | jq -rc .name)" == null ]]; then + continue; + fi + + if [[ "$(echo "${deployment_res}" | jq '.containers | length')" == "0" ]]; then + continue; + fi + + export deployment_name="$(echo "${deployment_res}" | jq -rc .name)" + export namespace="$(echo "${deployment_res}" | jq -rc .namespace)" + export clusterName="$(echo "${deployment_res}" | jq -rc .clusterName)" + + # Iterate over all images within the deployment and render the CSV Lines + for image_id in $(echo "${deployment_res}" | jq -r 'select(.containers != null) | .containers[].image.id'); do + if [[ "${image_id}" != "" ]]; then + image_res="$(curl_central "v1/images/${image_id}" | jq -rc)" + if [[ "$(echo "${image_res}" | jq -rc .name)" == null ]]; then + continue; + fi + + image_name="$(echo "${image_res}" | jq -rc '.name.fullName')" + export image_name + + # find the redhat-release version and format lines + export ubi_version="$(echo "${image_res}" | jq '.scan.components[] | select(.name=="redhat-release") | .version'| grep -o '[0-9]\.[0-9]\+' | head -1 )" + echo "${clusterName},${namespace},${deployment_name},${image_name},${ubi_version}" >> "${output_file}" + fi + done + done From 1e82e6dfbe623254c8f336de73bd2ba8ec68edad Mon Sep 17 00:00:00 2001 From: shaneboulden Date: Wed, 22 Jan 2025 10:27:41 +1030 Subject: [PATCH 2/2] add support for build lifecycle and rhel7 --- policies/ubi-versions.json | 5 +++-- util-scripts/ubi-versions/ubi-versions.sh | 4 ++-- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/policies/ubi-versions.json b/policies/ubi-versions.json index 5b9045f..b23e100 100755 --- a/policies/ubi-versions.json +++ b/policies/ubi-versions.json @@ -3,7 +3,7 @@ { "id": "53e1d1fb-bc1e-4ef3-98c3-8df0dd5679b8", "name": "UBI version compliance", - "description": "All images on the cluster using the Red Hat Universal Base Image (UBI) must use at least versions 8.5 or 9.3", + "description": "All images on the cluster using the Red Hat Universal Base Image (UBI) must use at least versions 8.5 or 9.3", "rationale": "Using an older UBI image potentially exposes the workload to additional vulnerabilities", "remediation": "Update the base image to at least UBI 8.5 or 9.3", "disabled": true, @@ -11,6 +11,7 @@ "Package Management" ], "lifecycleStages": [ + "BUILD", "DEPLOY" ], "eventSource": "NOT_APPLICABLE", @@ -66,7 +67,7 @@ "value": "redhat-release=9\\.[0-2]-[0-9]+(?:\\.[0-9]+)?\\.el9" }, { - "value": "redhat-release=[6-7].*" + "value": "redhat-release-server=7.*" } ] } diff --git a/util-scripts/ubi-versions/ubi-versions.sh b/util-scripts/ubi-versions/ubi-versions.sh index a653c24..8b5d873 100755 --- a/util-scripts/ubi-versions/ubi-versions.sh +++ b/util-scripts/ubi-versions/ubi-versions.sh @@ -62,8 +62,8 @@ for deployment_id in $(echo "${res}" | jq -r .alerts[].deployment.id); do image_name="$(echo "${image_res}" | jq -rc '.name.fullName')" export image_name - # find the redhat-release version and format lines - export ubi_version="$(echo "${image_res}" | jq '.scan.components[] | select(.name=="redhat-release") | .version'| grep -o '[0-9]\.[0-9]\+' | head -1 )" + # find the redhat-release (UBI 8/9) or redhat-release-server (UBI 7) version and format lines + export ubi_version="$(echo "${image_res}" | jq '.scan.components[] | select(.name=="redhat-release" or .name=="redhat-release-server") | .version'| grep -o '[0-9]\.[0-9]\+' | head -1 )" echo "${clusterName},${namespace},${deployment_name},${image_name},${ubi_version}" >> "${output_file}" fi done