aquasecurity / starboard

Moved to https://github.com/aquasecurity/trivy-operator
https://aquasecurity.github.io/starboard/
Apache License 2.0
1.35k stars 197 forks source link

Running kube-bench on OpenShift fails #580

Open danielpacak opened 3 years ago

danielpacak commented 3 years ago

What steps did you take and what happened:

$ starboard kube-bench -v 3
Command "kube-bench" is deprecated, please use 'scan ciskubebenchreports' instead
I0514 13:12:01.235777   17695 runner.go:79] Running task and waiting forever
I0514 13:12:01.235777   17695 runner.go:79] Running task and waiting forever
I0514 13:12:01.235804   17695 runner.go:79] Running task and waiting forever
I0514 13:12:01.235837   17695 runnable_job.go:76] Creating job "starboard/scan-cisbenchmark-674d99fcd5"
I0514 13:12:01.235837   17695 runnable_job.go:76] Creating job "starboard/scan-cisbenchmark-669d66bf68"
I0514 13:12:01.235843   17695 runner.go:79] Running task and waiting forever
I0514 13:12:01.235848   17695 runnable_job.go:76] Creating job "starboard/scan-cisbenchmark-7fd9c6d869"
I0514 13:12:01.235852   17695 runner.go:79] Running task and waiting forever
I0514 13:12:01.235850   17695 runnable_job.go:76] Creating job "starboard/scan-cisbenchmark-66f5cd65b6"
I0514 13:12:01.235860   17695 runnable_job.go:76] Creating job "starboard/scan-cisbenchmark-666cbdcb99"
I0514 13:12:02.162928   17695 runner.go:83] Stopping runner on task completion with error: warning event received: Error creating: pods "scan-cisbenchmark-674d99fcd5-" is forbidden: unable to validate against any security context constraint: [provider restricted: .spec.securityContext.hostPID: Invalid value: true: Host PID is not allowed to be used spec.volumes[0]: Invalid value: "hostPath": hostPath volumes are not allowed to be used spec.volumes[1]: Invalid value: "hostPath": hostPath volumes are not allowed to be used spec.volumes[2]: Invalid value: "hostPath": hostPath volumes are not allowed to be used spec.volumes[3]: Invalid value: "hostPath": hostPath volumes are not allowed to be used spec.volumes[4]: Invalid value: "hostPath": hostPath volumes are not allowed to be used spec.containers[0].securityContext.runAsUser: Invalid value: 0: must be in the ranges: [1000620000, 1000629999] spec.containers[0].securityContext.hostPID: Invalid value: true: Host PID is not allowed to be used] (FailedCreate)
E0514 13:12:02.162957   17695 scan_ciskubebench.go:91] Error while running kube-bench on node: ocp47vpool2453-6lwn4-master-1: running kube-bench job: warning event received: Error creating: pods "scan-cisbenchmark-674d99fcd5-" is forbidden: unable to validate against any security context constraint: [provider restricted: .spec.securityContext.hostPID: Invalid value: true: Host PID is not allowed to be used spec.volumes[0]: Invalid value: "hostPath": hostPath volumes are not allowed to be used spec.volumes[1]: Invalid value: "hostPath": hostPath volumes are not allowed to be used spec.volumes[2]: Invalid value: "hostPath": hostPath volumes are not allowed to be used spec.volumes[3]: Invalid value: "hostPath": hostPath volumes are not allowed to be used spec.volumes[4]: Invalid value: "hostPath": hostPath volumes are not allowed to be used spec.containers[0].securityContext.runAsUser: Invalid value: 0: must be in the ranges: [1000620000, 1000629999] spec.containers[0].securityContext.hostPID: Invalid value: true: Host PID is not allowed to be used] (FailedCreate)
...

What did you expect to happen:

CISKubeBenchReport instances created for each cluster node.

Anything else you would like to add:

N/A

Environment:

fengshunli commented 2 years ago

i want to fix error

mtcolman commented 2 years ago

Applicable to both #579 and this issue.

I've just installed

$ starboard version
Starboard Version: {Version:0.14.1 Commit:5672fd4a4d608d9b094802098f3e950ec396ff51 Date:2022-01-25T17:38:43Z}

I believe the reason for failure is due to the SCC the starboard service account (named: starboard) is permitted to use vs what it needs for the securityContext and host requirements in the jobs.

apiVersion: batch/v1
kind: Job
metadata:
  name: scan-kubehunterreports-7594df9b45
  namespace: starboard
spec:
  template:
    spec:
      containers:
        securityContext:
          allowPrivilegeEscalation: false
          capabilities:
            add:
            - NET_RAW
            drop:
            - all
          privileged: false
          readOnlyRootFilesystem: false
      hostPID: true
      securityContext:
        runAsGroup: 0
        runAsUser: 0
        seccompProfile:
          type: RuntimeDefault
      serviceAccount: starboard
      serviceAccountName: starboard
---
apiVersion: batch/v1
kind: Job
metadata:
  name: scan-cisbenchmark-586b9df6c
  namespace: starboard
spec:
  template:
    spec:
      containers:
        securityContext:
          allowPrivilegeEscalation: false
          capabilities:
            drop:
            - all
          privileged: false
          readOnlyRootFilesystem: true
      hostPID: true
      securityContext:
        runAsGroup: 0
        runAsUser: 0
        seccompProfile:
          type: RuntimeDefault
      serviceAccount: starboard
      serviceAccountName: starboard
---

Key requirements in both which aren't compatible with the default SCC, named restricted, are:

      hostPID: true
      securityContext:
        runAsGroup: 0
        runAsUser: 0
        seccompProfile:
          type: RuntimeDefault

Along with this setting In the kube-hunter job:

          capabilities:
            add:
            - NET_RAW

(Default capabilities in CRI-O are listed here, under "default_capabilities" - they are CHOWN, DAC_OVERRIDE, FSETID, FOWNER, SETGID, SETUID, SETPCAP, NET_BIND_SERVICE, KILL).

The restricted SCC only permits the default set, with a requirement to drop some of them, this means NET_RAW and restricted SCC aren't compatible, along with it being incompatible with the hostPID access, specification of a seccomp profile and the use of run user and/or group.

There is an SCC called hostaccess which allows access to the hostPID (and others):

$ oc get scc hostaccess -oyaml | grep allowHost
allowHostDirVolumePlugin: true
allowHostIPC: true
allowHostNetwork: true
allowHostPID: true
allowHostPorts: true

However permitted user and group IDs for the SCC must be from within the namespace range and thus it is incompatible with runAsUser:0 and runAsGroup: 0, it is also incompatible with the seccomp specification.

This means that of the opinionated SCCs provided by OpenShift; restricted, any of the host*, nonroot and anyuid are all incompatible against the securityContexts and host access required.

This leaves the most open SCC privileged which comes with the following warning from Red Hat "This is the most relaxed SCC and should be used only for cluster administration. Grant with caution." It really should only be used as a last resort. Instead, a bespoke SCC permitting the required securityContexts and host access should be created, and the serviceAccount starboard should be granted permission to use it via a clusterrolebinding (or use of oc adm add-scc-to-user -z starboard). Ideally, separate serviceAccounts should be created for kube-bench, kube-hunter and the other jobs, to ensure granularity of permission granting - i.e. only grant minimal privilege as required to the jobs/serviceAccounts.

SCC should be something like:

kind: SecurityContextConstraints
apiVersion: "security.openshift.io/v1"
metadata:
  name: starboard
allowHostDirVolumePlugin: false
allowHostIPC: false
allowHostNetwork: false
allowHostPID: true
allowHostPorts: false
allowPrivilegeEscalation: true
allowPrivilegedContainer: false
allowedCapabilities:
- NET_RAW
defaultAddCapabilities: null
requiredDropCapabilities:
- KILL
- MKNOD
- SETUID
- SETGID
runAsUser:   
  type: RunAsAny
seLinuxContext:
  type: MustRunAs
fsGroup:
  type: RunAsAny
readOnlyRootFilesystem: false
supplementalGroups:
  type: RunAsAny
seccompProfiles:
- '*'
volumes:
- configMap
- downwardAPI
- emptyDir
- persistentVolumeClaim
- projected
- secret

Then a clusterRole would be needed, for use in the clusterrolebinding, something like:

apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: scc-starboard
rules:
- apiGroups:
  - security.openshift.io
  resourceNames:
  - starboard
  resources:
  - securitycontextconstraints
  verbs:
  - use

And then bound with:

apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: scc-starboard
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: scc-starboard
subjects:
- kind: ServiceAccount
  name: starboard
  namespace: starboard