fix-policies.sh 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173
  1. #!/bin/bash
  2. #
  3. # Generate modified policies. Patch existing modified policies to disable them.
  4. #
  5. # Need files:
  6. # policyexport (a dump of all policies)
  7. # roxctl-token (api auth token)
  8. #
  9. E=central-rhacs.apps.ocp4.example.com
  10. T=$(cat roxctl-token)
  11. DISABLED_POLICY_LIST=(
  12. "ADD Command used instead of COPY"
  13. "Container using read-write root filesystem"
  14. "Curl in Image"
  15. "Docker CIS 4.4: Ensure images are scanned and rebuilt to include security patches"
  16. "Docker CIS 5.21: Ensure the default seccomp profile is not disabled"
  17. "Fixable CVSS >= 7"
  18. "Images with no scans"
  19. "Login Binaries"
  20. "Password Binaries"
  21. "Process with UID 0"
  22. "Required Annotation: Email"
  23. "Required Annotation: Owner/Team"
  24. "Required Image Label"
  25. "Required Label: Owner/Team"
  26. "Secret Mounted as Environment Variable"
  27. "SetUID Processes"
  28. "Shadow File Modification"
  29. "Shell Management"
  30. "Wget in Image"
  31. )
  32. ENABLED_POLICY_LIST=(
  33. "30-Day Scan Age"
  34. "Alpine Linux Package Manager Execution"
  35. "Apache Struts: CVE-2017-5638"
  36. "CAP_SYS_ADMIN capability added"
  37. "Compiler Tool Execution"
  38. "Cryptocurrency Mining Process Execution"
  39. "Docker CIS 4.7: Alert on Update Instruction"
  40. "Docker CIS 5.1 Ensure that, if applicable, an AppArmor Profile is enabled"
  41. "Docker CIS 5.19: Ensure mount propagation mode is not enabled"
  42. "Emergency Deployment Annotation"
  43. "Improper Usage of Orchestrator Secrets Volume"
  44. "Insecure specified in CMD"
  45. "Iptables Executed in Privileged Container"
  46. "Kubernetes Actions: Exec into Pod"
  47. "Kubernetes Actions: Port Forward to Pod"
  48. "Kubernetes Dashboard Deployed"
  49. "Latest tag"
  50. "Linux Group Add Execution"
  51. "Linux User Add Execution"
  52. "Log4Shell: log4j Remote Code Execution vulnerability"
  53. "Netcat Execution Detected"
  54. "Network Management Execution"
  55. "OpenShift: Advanced Cluster Security Central Admin Secret Accessed"
  56. "OpenShift: Kubeadmin Secret Accessed"
  57. "OpenShift: Kubernetes Secret Accessed by an Impersonated User"
  58. "Process Targeting Cluster Kubelet Endpoint"
  59. "Process Targeting Cluster Kubernetes Docker Stats Endpoint"
  60. "Process Targeting Kubernetes Service Endpoint"
  61. "Red Hat Package Manager Execution"
  62. "Remote File Copy Binary Execution"
  63. "Secure Shell (ssh) Port Exposed"
  64. "Secure Shell (ssh) Port Exposed in Image"
  65. "Secure Shell Server (sshd) Execution"
  66. "Shell Spawned by Java Application"
  67. "Ubuntu Package Manager Execution"
  68. "Ubuntu Package Manager in Image"
  69. "Unauthorized Network Flow"
  70. "Unauthorized Process Execution"
  71. "chkconfig Execution"
  72. "crontab Execution"
  73. "iptables Execution"
  74. "nmap Execution"
  75. "systemctl Execution"
  76. "systemd Execution"
  77. )
  78. FIX_POLICY_LIST=(
  79. "90-Day Image Age"
  80. "Alpine Linux Package Manager (apk) in Image"
  81. "Docker CIS 4.1: Ensure That a User for the Container Has Been Created"
  82. "Docker CIS 5.15: Ensure that the host's process namespace is not shared"
  83. "Docker CIS 5.16: Ensure that the host's IPC namespace is not shared"
  84. "Docker CIS 5.7: Ensure privileged ports are not mapped within containers"
  85. "Docker CIS 5.9 and 5.20: Ensure that the host's network namespace is not shared"
  86. "Environment Variable Contains Secret"
  87. "Fixable CVSS >= 6 and Privileged"
  88. "Fixable Severity at least Important"
  89. "Mount Container Runtime Socket"
  90. "Mounting Sensitive Host Directories"
  91. "No resource requests or limits specified"
  92. "Pod Service Account Token Automatically Mounted"
  93. "Privileged Container"
  94. "Red Hat Package Manager Execution"
  95. "Red Hat Package Manager in Image"
  96. )
  97. echo "Fixed policies: ${#FIX_POLICY_LIST[*]}"
  98. echo "Enabled policies: ${#ENABLED_POLICY_LIST[*]}"
  99. echo "Disabled policies: ${#DISABLED_POLICY_LIST[*]}"
  100. # Export current policies.
  101. # TODO: decide when to use backup and when to use current state
  102. # XXX: can't delete system policies anyway
  103. oldIFS="${IFS}"
  104. newIFS='
  105. '
  106. IFS="${newIFS}"
  107. for p in ${DISABLED_POLICY_LIST[*]}; do
  108. id="$(jq -r '.policies[] | select(.name == "'${p}'") | .id' < policyexport)"
  109. if [ -z "${id}" ]; then
  110. echo "ERROR: Could not look up ID of \"${p}\"!"
  111. continue
  112. fi
  113. echo -n "Disabling \"${p}\" ($id)... "
  114. curl -ks -XPATCH -H "Authorization: Bearer ${T}" -d '{"id": "'${id}'", "disabled": true}' https://${E}/v1/policies/${id}
  115. echo
  116. done
  117. for p in ${ENABLED_POLICY_LIST[*]}; do
  118. id="$(jq -r '.policies[] | select(.name == "'${p}'") | .id' < policyexport)"
  119. if [ -z "${id}" ]; then
  120. echo "ERROR: Could not look up ID of \"${p}\"!"
  121. continue
  122. fi
  123. echo -n "Enabling \"${p}\" ($id)... "
  124. curl -ks -XPATCH -H "Authorization: Bearer ${T}" -d '{"id": "'${id}'", "disabled": false}' https://${E}/v1/policies/${id}
  125. echo
  126. done
  127. for p in ${FIX_POLICY_LIST[*]}; do
  128. # find matching policies
  129. ids="$(jq -r '.policies[] | select(.name | test("(?i)^'${p//[()]/.}'")) | .id' < policyexport)"
  130. if [ -z "${ids}" ]; then
  131. echo "ERROR: Could not look up ID(s) of \"${p//[()]/.}\"!"
  132. continue
  133. fi
  134. # how many?
  135. nmatch=$(echo "${ids}" | wc -l | tr -d '[[:space:]]')
  136. echo "Found ${nmatch} policies matching \"${p}\"..."
  137. if [ ${nmatch} -gt 1 ]; then
  138. # delete the one(s) that are not an exact match
  139. id="$(jq -r '.policies[] | select(.name == "'${p}'") | .id' < policyexport)"
  140. if [ -z "${id}" ]; then
  141. echo "ERROR: Could not find exact match for \"${p}\"!"
  142. continue
  143. fi
  144. xtraids="$(echo "${ids}" | grep -v ${id})"
  145. for rmid in ${xtraids}; do
  146. echo -n " - removing: ${rmid}"
  147. curl -ks -XDELETE -H "Authorization: Bearer ${T}" https://${E}/v1/policies/${rmid}
  148. echo
  149. done
  150. else
  151. id="${ids}"
  152. fi
  153. echo " - keeping: ${id}"
  154. echo -n " disabling... "
  155. curl -ks -XPATCH -H "Authorization: Bearer ${T}" -d '{"id": "'${id}'", "disabled": true}' https://${E}/v1/policies/${id}
  156. echo
  157. echo -n " creating patched copy... "
  158. 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)"
  159. curl -ks -XPOST -H "Authorization: Bearer ${T}" -d "${PAYLOAD}" https://${E}/v1/policies
  160. echo
  161. done
  162. IFS="${oldIFS}"
  163. unset oldIFS newIFS