From e8c08b9a770301d00e913c0a2ab6ddfaf2fab4e3 Mon Sep 17 00:00:00 2001 From: Mark Stemm Date: Wed, 10 Apr 2019 14:16:56 -0700 Subject: [PATCH] Clean up privileged/sens mount container rules Previously, the exceptions for Launch Privileged Container/Launch Sensitive Mount Container came from a list of "trusted" images and/or a macro that defined "trusted" containers. We want more fine-grained control over the exceptions for these rules, so split them into exception lists/macros that are specific to each rule. This defines: - falco_privileged_images: only those images that are known to require privileged=true - falco_privileged_containers: uses privileged_images and (for now) still allows all openshift images - user_privileged_containers: allows user exceptions - falco_sensitive_mount_images: only thoe images that are known to perform sensitive mounts - falco_sensitive_mount_containers: uses sensitive_mount_images - user_sensitive_mount_containers: allows user exceptions For backwards compatibility purposes only, we keep the trusted_images list and user_trusted_containers macro and they are still used as exceptions for both rules. Comments recommend using the more fine-grained alternatives, though. While defining these lists, also do another survey to see if they still require these permissions and remove them if they didn't. Removed: - quay.io/coreos/flannel - consul Moved to sensitive mount only: - gcr.io/google_containers/hyperkube - datadog - gliderlabs/logspout Finally, get rid of the k8s audit-specific lists of privileged/sensitive mount images, relying on the ones in falco_rules.yaml. Signed-off-by: Mark Stemm --- rules/falco_rules.yaml | 89 ++++++++++++++++++++++++++++++-------- rules/k8s_audit_rules.yaml | 30 ++----------- 2 files changed, 76 insertions(+), 43 deletions(-) diff --git a/rules/falco_rules.yaml b/rules/falco_rules.yaml index 1a74bae8..9859fa6d 100644 --- a/rules/falco_rules.yaml +++ b/rules/falco_rules.yaml @@ -1665,40 +1665,95 @@ container.image.repository contains ose-docker-registry or container.image.repository contains image-inspector)) +# These images are allowed both to run with --privileged and to mount +# sensitive paths from the host filesystem. +# +# NOTE: This list is only provided for backwards compatibility with +# older local falco rules files that may have been appending to +# trusted_images. To make customizations, it's better to add images to +# either privileged_images or sensitive_mount_images. - list: trusted_images + items: [] + +# Add conditions to this macro (probably in a separate file, +# overwriting this macro) to specify additional containers that are +# trusted and therefore allowed to run privileged *and* with sensitive +# mounts. +# +# Like trusted_images, this is deprecated in favor of +# user_privileged_containers and user_sensitive_mount_containers and +# is only provided for backwards compatibility. +# +# In this file, it just takes one of the images in trusted_containers +# and repeats it. +- macro: user_trusted_containers + condition: (container.image.repository=sysdig/agent) + +- list: sematext_images + items: [sematext/sematext-agent-docker, sematext/agent, sematext/logagent, + registry.access.redhat.com/sematext/sematext-agent-docker, + registry.access.redhat.com/sematext/agent, + registry.access.redhat.com/sematext/logagent] + +# These container images are allowed to run with --privileged +- list: privileged_images items: [ - sysdig/agent, sysdig/falco, sysdig/sysdig, gcr.io/google_containers/hyperkube, - quay.io/coreos/flannel, gcr.io/google_containers/kube-proxy, calico/node, - rook/toolbox, cloudnativelabs/kube-router, consul, mesosphere/mesos-slave, - datadog/docker-dd-agent, datadog/agent, docker/ucp-agent, gliderlabs/logspout + sysdig/agent, sysdig/falco, sysdig/sysdig, + gcr.io/google_containers/kube-proxy, calico/node, + rook/toolbox, cloudnativelabs/kube-router, mesosphere/mesos-slave, + docker/ucp-agent, sematext_images ] -- macro: trusted_containers +- macro: privileged_containers condition: (openshift_image or + user_trusted_containers or container.image.repository in (trusted_images) or + container.image.repository in (privileged_images) or container.image.repository startswith istio/proxy_ or container.image.repository startswith quay.io/sysdig) +# Add conditions to this macro (probably in a separate file, +# overwriting this macro) to specify additional containers that are +# allowed to run privileged +# +# In this file, it just takes one of the images in privileged_images +# and repeats it. +- macro: user_privileged_containers + condition: (container.image.repository=sysdig/agent) + + - list: rancher_images items: [ rancher/network-manager, rancher/dns, rancher/agent, rancher/lb-service-haproxy, rancher/metadata, rancher/healthcheck ] -# Add conditions to this macro (probably in a separate file, -# overwriting this macro) to specify additional containers that are -# trusted and therefore allowed to run privileged. -# -# In this file, it just takes one of the images in trusted_containers -# and repeats it. -- macro: user_trusted_containers - condition: (container.image.repository=sysdig/agent) +# These container images are allowed to mount sensitive paths from the +# host filesystem. +- list: sensitive_mount_images + items: [ + sysdig/agent, sysdig/falco, sysdig/sysdig, + gcr.io/google_containers/hyperkube, + gcr.io/google_containers/kube-proxy, calico/node, + rook/toolbox, cloudnativelabs/kube-router, consul, + datadog/docker-dd-agent, datadog/agent, docker/ucp-agent, gliderlabs/logspout + ] + +- macro: sensitive_mount_containers + condition: (user_trusted_containers or + container.image.repository in (trusted_images) or + container.image.repository in (sensitive_mount_images) or + container.image.repository startswith quay.io/sysdig) + +# These container images are allowed to run with hostnetwork=true +- list: hostnetwork_images + items: [] # Add conditions to this macro (probably in a separate file, # overwriting this macro) to specify additional containers that are # allowed to perform sensitive mounts. # -# In this file, it just takes one of the images in trusted_containers +# In this file, it just takes one of the images in sensitive_mount_images # and repeats it. - macro: user_sensitive_mount_containers condition: (container.image.repository=sysdig/agent) @@ -1708,8 +1763,8 @@ condition: > container_started and container and container.privileged=true - and not trusted_containers - and not user_trusted_containers + and not privileged_containers + and not user_privileged_containers output: Privileged container started (user=%user.name command=%proc.cmdline %container.info image=%container.image.repository:%container.image.tag) priority: INFO tags: [container, cis, mitre_privilege_escalation, mitre_lateral_movement] @@ -1748,7 +1803,7 @@ condition: > container_started and container and sensitive_mount - and not trusted_containers + and not sensitive_mount_containers and not user_sensitive_mount_containers output: Container with sensitive mount started (user=%user.name command=%proc.cmdline %container.info image=%container.image.repository:%container.image.tag mounts=%container.mounts) priority: INFO diff --git a/rules/k8s_audit_rules.yaml b/rules/k8s_audit_rules.yaml index 046fcc7c..ae478f66 100644 --- a/rules/k8s_audit_rules.yaml +++ b/rules/k8s_audit_rules.yaml @@ -48,8 +48,7 @@ # explicitly enumerate the container images that you want to run in # your environment. In this main falco rules file, there isn't any way # to know all the containers that can run, so any container is -# alllowed, by using a filter that is guaranteed to evaluate to true -# (the event time existing). In the overridden macro, the condition +# allowed, by using the always_true macro. In the overridden macro, the condition # would look something like (ka.req.container.image.repository=my-repo/my-image) - macro: allowed_k8s_containers condition: (jevt.rawtime exists) @@ -108,31 +107,10 @@ source: k8s_audit tags: [k8s] -- list: trusted_k8s_containers - items: [sysdig/agent, sysdig/falco, quay.io/coreos/flannel, calico/node, rook/toolbox, - gcr.io/google_containers/hyperkube, gcr.io/google_containers/kube-proxy, - openshift3/ose-sti-builder, - registry.access.redhat.com/openshift3/logging-fluentd, - registry.access.redhat.com/openshift3/logging-elasticsearch, - registry.access.redhat.com/openshift3/metrics-cassandra, - registry.access.redhat.com/openshift3/ose-sti-builder, - registry.access.redhat.com/openshift3/ose-docker-builder, - registry.access.redhat.com/openshift3/image-inspector, - registry.access.redhat.com/sematext/sematext-agent-docker, - registry.access.redhat.com/sematext/agent, - registry.access.redhat.com/sematext/logagent, - cloudnativelabs/kube-router, istio/proxy, - datadog/docker-dd-agent, datadog/agent, - docker/ucp-agent, - gliderlabs/logspout - sematext/agent - sematext/logagent - sematext/sematext-agent-docker] - - rule: Create Privileged Pod desc: > Detect an attempt to start a pod with a privileged container - condition: kevt and pod and kcreate and ka.req.container.privileged=true and not ka.req.container.image.repository in (trusted_k8s_containers) + condition: kevt and pod and kcreate and ka.req.container.privileged=true and not ka.req.container.image.repository in (privileged_images) output: Pod started with privileged container (user=%ka.user.name pod=%ka.resp.name ns=%ka.target.namespace image=%ka.req.container.image) priority: WARNING source: k8s_audit @@ -150,7 +128,7 @@ desc: > Detect an attempt to start a pod with a volume from a sensitive host directory (i.e. /proc). Exceptions are made for known trusted images. - condition: kevt and pod and kcreate and sensitive_vol_mount and not ka.req.container.image.repository in (trusted_k8s_containers) + condition: kevt and pod and kcreate and sensitive_vol_mount and not ka.req.container.image.repository in (sensitive_mount_images) output: Pod started with sensitive mount (user=%ka.user.name pod=%ka.resp.name ns=%ka.target.namespace image=%ka.req.container.image mounts=%jevt.value[/requestObject/spec/volumes]) priority: WARNING source: k8s_audit @@ -159,7 +137,7 @@ # Corresponds to K8s CIS Benchmark 1.7.4 - rule: Create HostNetwork Pod desc: Detect an attempt to start a pod using the host network. - condition: kevt and pod and kcreate and ka.req.container.host_network=true and not ka.req.container.image.repository in (trusted_k8s_containers) + condition: kevt and pod and kcreate and ka.req.container.host_network=true and not ka.req.container.image.repository in (hostnetwork_images) output: Pod started using host network (user=%ka.user.name pod=%ka.resp.name ns=%ka.target.namespace image=%ka.req.container.image) priority: WARNING source: k8s_audit