123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172 |
- #!/bin/bash
- #
- # Generate modified policies. Patch existing modified policies to disable them.
- #
- # Need files:
- # policyexport (a dump of all policies)
- # roxctl-token (api auth token)
- #
- E=central-rhacs.apps.ocp4.example.com
- T=$(cat roxctl-token)
- DISABLED_POLICY_LIST=(
- "ADD Command used instead of COPY"
- "Container using read-write root filesystem"
- "Curl in Image"
- "Docker CIS 4.4: Ensure images are scanned and rebuilt to include security patches"
- "Docker CIS 5.21: Ensure the default seccomp profile is not disabled"
- "Fixable CVSS >= 7"
- "Images with no scans"
- "Login Binaries"
- "Password Binaries"
- "Process with UID 0"
- "Required Annotation: Email"
- "Required Annotation: Owner/Team"
- "Required Image Label"
- "Required Label: Owner/Team"
- "Secret Mounted as Environment Variable"
- "SetUID Processes"
- "Shadow File Modification"
- "Shell Management"
- "Wget in Image"
- )
- ENABLED_POLICY_LIST=(
- "30-Day Scan Age"
- "Alpine Linux Package Manager Execution"
- "Apache Struts: CVE-2017-5638"
- "CAP_SYS_ADMIN capability added"
- "Compiler Tool Execution"
- "Cryptocurrency Mining Process Execution"
- "Docker CIS 4.7: Alert on Update Instruction"
- "Docker CIS 5.1 Ensure that, if applicable, an AppArmor Profile is enabled"
- "Docker CIS 5.19: Ensure mount propagation mode is not enabled"
- "Emergency Deployment Annotation"
- "Improper Usage of Orchestrator Secrets Volume"
- "Insecure specified in CMD"
- "Iptables Executed in Privileged Container"
- "Kubernetes Actions: Exec into Pod"
- "Kubernetes Actions: Port Forward to Pod"
- "Kubernetes Dashboard Deployed"
- "Latest tag"
- "Linux Group Add Execution"
- "Linux User Add Execution"
- "Log4Shell: log4j Remote Code Execution vulnerability"
- "Netcat Execution Detected"
- "Network Management Execution"
- "OpenShift: Advanced Cluster Security Central Admin Secret Accessed"
- "OpenShift: Kubeadmin Secret Accessed"
- "OpenShift: Kubernetes Secret Accessed by an Impersonated User"
- "Process Targeting Cluster Kubelet Endpoint"
- "Process Targeting Cluster Kubernetes Docker Stats Endpoint"
- "Process Targeting Kubernetes Service Endpoint"
- "Red Hat Package Manager Execution"
- "Remote File Copy Binary Execution"
- "Secure Shell (ssh) Port Exposed"
- "Secure Shell (ssh) Port Exposed in Image"
- "Secure Shell Server (sshd) Execution"
- "Shell Spawned by Java Application"
- "Ubuntu Package Manager Execution"
- "Ubuntu Package Manager in Image"
- "Unauthorized Network Flow"
- "Unauthorized Process Execution"
- "chkconfig Execution"
- "crontab Execution"
- "iptables Execution"
- "nmap Execution"
- "systemctl Execution"
- "systemd Execution"
- )
- FIX_POLICY_LIST=(
- "90-Day Image Age"
- "Alpine Linux Package Manager (apk) in Image"
- "Docker CIS 4.1: Ensure That a User for the Container Has Been Created"
- "Docker CIS 5.15: Ensure that the host's process namespace is not shared"
- "Docker CIS 5.16: Ensure that the host's IPC namespace is not shared"
- "Docker CIS 5.7: Ensure privileged ports are not mapped within containers"
- "Docker CIS 5.9 and 5.20: Ensure that the host's network namespace is not shared"
- "Environment Variable Contains Secret"
- "Fixable CVSS >= 6 and Privileged"
- "Fixable Severity at least Important"
- "Mount Container Runtime Socket"
- "Mounting Sensitive Host Directories"
- "No resource requests or limits specified"
- "Pod Service Account Token Automatically Mounted"
- "Privileged Container"
- "Red Hat Package Manager in Image"
- )
- echo "Fixed policies: ${#FIX_POLICY_LIST[*]}"
- echo "Enabled policies: ${#ENABLED_POLICY_LIST[*]}"
- echo "Disabled policies: ${#DISABLED_POLICY_LIST[*]}"
- # Export current policies.
- # TODO: decide when to use backup and when to use current state
- # XXX: can't delete system policies anyway
- oldIFS="${IFS}"
- newIFS='
- '
- IFS="${newIFS}"
- for p in ${DISABLED_POLICY_LIST[*]}; do
- id="$(jq -r '.policies[] | select(.name == "'${p}'") | .id' < policyexport)"
- if [ -z "${id}" ]; then
- echo "ERROR: Could not look up ID of \"${p}\"!"
- continue
- fi
- echo -n "Disabling \"${p}\" ($id)... "
- curl -ks -XPATCH -H "Authorization: Bearer ${T}" -d '{"id": "'${id}'", "disabled": true}' https://${E}/v1/policies/${id}
- echo
- done
- for p in ${ENABLED_POLICY_LIST[*]}; do
- id="$(jq -r '.policies[] | select(.name == "'${p}'") | .id' < policyexport)"
- if [ -z "${id}" ]; then
- echo "ERROR: Could not look up ID of \"${p}\"!"
- continue
- fi
- echo -n "Enabling \"${p}\" ($id)... "
- curl -ks -XPATCH -H "Authorization: Bearer ${T}" -d '{"id": "'${id}'", "disabled": false}' https://${E}/v1/policies/${id}
- echo
- done
- for p in ${FIX_POLICY_LIST[*]}; do
- # find matching policies
- ids="$(jq -r '.policies[] | select(.name | test("(?i)^'${p//[()]/.}'")) | .id' < policyexport)"
- if [ -z "${ids}" ]; then
- echo "ERROR: Could not look up ID(s) of \"${p//[()]/.}\"!"
- continue
- fi
- # how many?
- nmatch=$(echo "${ids}" | wc -l | tr -d '[[:space:]]')
- echo "Found ${nmatch} policies matching \"${p}\"..."
- if [ ${nmatch} -gt 1 ]; then
- # delete the one(s) that are not an exact match
- id="$(jq -r '.policies[] | select(.name == "'${p}'") | .id' < policyexport)"
- if [ -z "${id}" ]; then
- echo "ERROR: Could not find exact match for \"${p}\"!"
- continue
- fi
- xtraids="$(echo "${ids}" | grep -v ${id})"
- for rmid in ${xtraids}; do
- echo -n " - removing: ${rmid}"
- curl -ks -XDELETE -H "Authorization: Bearer ${T}" https://${E}/v1/policies/${rmid}
- echo
- done
- else
- id="${ids}"
- fi
- echo " - keeping: ${id}"
- echo -n " disabling... "
- curl -ks -XPATCH -H "Authorization: Bearer ${T}" -d '{"id": "'${id}'", "disabled": true}' https://${E}/v1/policies/${id}
- echo
- echo -n " creating patched copy... "
- PAYLOAD="$(jq '.policies[] | select(.id == "'${id}'") | .exclusions |= [ { "name": "Skip system namespaces", "deployment": { "name": "", "scope": { "cluster": "", "namespace": "^kube-.*|^openshift-.*|^istio-.*|^rhacs$|^stackrox$", "label": null } }, "image": null, "expiration": null } ] | .name |= . + " (non-system)" | .id |= "" | .disabled |= false' < policyexport)"
- curl -ks -XPOST -H "Authorization: Bearer ${T}" -d "${PAYLOAD}" https://${E}/v1/policies
- echo
- done
- IFS="${oldIFS}"
- unset oldIFS newIFS
|