kubearmor / KubeArmor

Runtime Security Enforcement System. Workload hardening/sandboxing and implementing least-permissive policies made easy leveraging LSMs (BPF-LSM, AppArmor).
https://kubearmor.io/
Apache License 2.0
1.45k stars 335 forks source link

KubeArmor: Inconsistent Log Generation for Blocked Processes with Default Posture Block #1843

Open yeranosyanvahan opened 1 month ago

yeranosyanvahan commented 1 month ago

Description:

There is an issue with KubeArmor version 1.4.0 where logs are not generated for blocked processes when a namespace is configured with a default block posture. Logs are only generated after explicitly adding an Allow policy for the entrypoint process.

Steps to Reproduce:

  1. Install KubeArmor 1.4.0 in a Kubernetes cluster. (details of the system below)
  2. Apply the following block posture annotations on a namespace:
    apiVersion: v1
    kind: Namespace
    metadata:
      name: test-wordpress-block
      annotations:
        kubearmor-visibility: process,file,network
        kubearmor-file-posture: block
        kubearmor-network-posture: block
        kubearmor-capabilities-posture: block
  3. Deploy a pod within the namespace (e.g., a Bitnami WordPress container).
    apiVersion: helm.cattle.io/v1
    kind: HelmChart
    metadata:
    name: wordpress-testblock-release
    spec:
    chart: oci://registry-1.docker.io/bitnamicharts/wordpress
    targetNamespace: test-wordpress-block
    version: 23.1.1
    set:
    mariadb.enabled: "false"
    service.type: ClusterIP
    serviceAccount.create: "false"
    #    global.storageClass: host-storageclass
    valuesContent: |-
    replicaCount: 1
    wordpressSkipInstall: false
    persistence:
      enabled: true
      storageClass: local-path
      size: 900Mi
    podLabels:
      test-kubarmor-policy: test-wordpress-block
    startupProbe:
      enabled: true
      initialDelaySeconds: 600
      periodSeconds: 10
      timeoutSeconds: 5
      failureThreshold: 9
      successThreshold: 1
  4. Observe that no logs are generated for blocked processes by default. pod logs
    /bin/bash: /opt/bitnami/scripts/wordpress/entrypoint.sh: Permission denied

    Byt

    root@machine:~# karmor logs --namespace test-wordpress-block
    local port to be used for port forwarding kubearmor-relay-5b5458dfd8-99r8g: 32768
    Created a gRPC client (localhost:32768)
    Checked the liveness of the gRPC server
    Started to watch alerts
  5. Add an Allow policy for the entrypoint process:
    apiVersion: security.kubearmor.com/v1
    kind: KubeArmorPolicy
    metadata:
      name: test-wordpress-block
      namespace: test-wordpress-block
    spec:
      action: Allow
      message: "Permissive Allow test-wordpress-block Policy"
      selector:
        matchLabels:
          test-kubarmor-policy: test-wordpress-block
      process:
        matchPaths:
        - path: /opt/bitnami/apache/bin/httpd
        - path: /opt/bitnami/scripts/wordpress/entrypoint.sh
  6. Observe that logs start to be generated for blocked processes only after the Allow policy is added.
== Alert / 2024-08-13 16:42:20.234088 ==
ClusterName: default
HostName: machine
NamespaceName: test-wordpress-block
PodName: wordpress-testblock-release-74cc44cc9-wdzhr
ContainerName: 5dc3977894375ab65d87112821295505a0ca664c48e63bee248bf40e0d161091
ContainerID: 5dc3977894375ab65d87112821295505a0ca664c48e63bee248bf40e0d161091
Type: MatchedPolicy
PolicyName: DefaultPosture
Source: /opt/bitnami/scripts/wordpress/entrypoint.sh /opt/bitnami/scripts/apache/run.sh
Resource: /opt/bitnami/scripts/wordpress/entrypoint.sh
Operation: File
Action: Block
Data: syscall=SYS_OPENAT fd=-100 flags=O_RDONLY
Enforcer: eBPF Monitor
Result: Permission denied
Cwd: /
HostPID: 7535
HostPPID: 6746
Owner: map[Name:wordpress-testblock-release Namespace:test-wordpress-block Ref:Deployment]
PID: 1
PPID: 0
ParentProcessName: /var/lib/rancher/k3s/data/ad0d9298586ea865d9e35bf77eff7a64ab4d2b2fc0430eefb226e6c04b8b9bba/bin/containerd-shim-runc-v2
ProcessName: /usr/bin/bash
UID: 1001

** NOTE: This is the permission denied for a File, not a process, so we need to enable that as well

apiVersion: security.kubearmor.com/v1
kind: KubeArmorPolicy
metadata:
  name: test-wordpress-block
  namespace: test-wordpress-block
spec:
  action: Allow
  message: "Permissive Allow test-wordpress-block Policy"
  selector:
    matchLabels:
      test-kubarmor-policy: test-wordpress-block
  process:
    matchPaths:
    - path: /opt/bitnami/apache/bin/httpd
    - path: /opt/bitnami/scripts/wordpress/entrypoint.sh
  file:
    matchPaths:
    - path: /opt/bitnami/scripts/wordpress/entrypoint.sh

Now, kubearmor works as expected, because entrypoint is permitted

Expected Behavior:

KubeArmor should generate logs for blocked entrypoint process when a default block posture is applied to a namespace.

Actual Behavior:

Environment:

yeranosyanvahan commented 1 month ago

Full kubernetes yaml file


apiVersion: v1
kind: Namespace
metadata:
  name: kubearmor-operator
  labels:
    project: infra
    group: operator
---
apiVersion: helm.cattle.io/v1
kind: HelmChart
metadata:
  name: operator-kubearmor-release
spec:
  repo: https://kubearmor.github.io/charts
  chart: kubearmor-operator
  targetNamespace: kubearmor-operator
  version: 1.4.0
--- #kubectl apply -f https://raw.githubusercontent.com/kubearmor/KubeArmor/main/pkg/KubeArmorOperator/config/samples/sample-config.yml
apiVersion: operator.kubearmor.com/v1
kind: KubeArmorConfig
metadata:
  labels:
    app.kubernetes.io/name: kubearmorconfig
    app.kubernetes.io/instance: kubearmorconfig-sample
    app.kubernetes.io/part-of: kubearmoroperator
    app.kubernetes.io/managed-by: kustomize
    app.kubernetes.io/created-by: kubearmoroperator
  name: kubearmorconfig-default
  namespace: kubearmor-operator
spec:
  defaultCapabilitiesPosture: audit
  defaultFilePosture: audit
  defaultNetworkPosture: audit
  defaultVisibility: process,network
  enableStdOutLogs: false
  enableStdOutAlerts: false
  enableStdOutMsgs: false
  seccompEnabled: false
  alertThrottling: false
  maxAlertPerSec: 10
  throttleSec: 30
  kubearmorImage:
    image: kubearmor/kubearmor:stable
    imagePullPolicy: Always
  kubearmorInitImage:
    image: kubearmor/kubearmor-init:stable
    imagePullPolicy: Always
  kubearmorRelayImage:
    image: kubearmor/kubearmor-relay-server
    imagePullPolicy: Always
  kubearmorControllerImage:
    image: kubearmor/kubearmor-controller
    imagePullPolicy: Always

---
apiVersion: v1
kind: Namespace
metadata:
  name: test-wordpress-block
  annotations:
    kubearmor-visibility: process,file,network
    kubearmor-file-posture: block
    kubearmor-network-posture: block
    kubearmor-capabilities-posture: block
  labels:
    project: block
    group: wordpress
---
apiVersion: helm.cattle.io/v1
kind: HelmChart
metadata:
  name: wordpress-testblock-release
spec:
  chart: oci://registry-1.docker.io/bitnamicharts/wordpress
  targetNamespace: test-wordpress-block
  version: 23.1.1
  set:
    mariadb.enabled: "false"
    service.type: ClusterIP
    serviceAccount.create: "false"
#    global.storageClass: host-storageclass
  valuesContent: |-
    replicaCount: 1
    wordpressSkipInstall: false
    persistence:
      enabled: true
      storageClass: local-path
      size: 900Mi
    podLabels:
      test-kubarmor-policy: test-wordpress-block
    startupProbe:
      enabled: true
      initialDelaySeconds: 600
      periodSeconds: 10
      timeoutSeconds: 5
      failureThreshold: 9
      successThreshold: 1
---
apiVersion: v1
kind: Namespace
metadata:
  name: test-wordpress-block
  annotations:
    kubearmor-visibility: process,file,network
    kubearmor-file-posture: block
    kubearmor-network-posture: block
    kubearmor-capabilities-posture: block
  labels:
    project: block
    group: wordpress
---
apiVersion: security.kubearmor.com/v1
kind: KubeArmorPolicy
metadata:
  name: test-wordpress-block-nolog
  namespace: test-wordpress-block
spec:
  action: Allow
  message: "Doesn't generate any logs because entrypoint is blocked"
  selector:
    matchLabels:
      test-kubarmor-policy: test-wordpress-block
  process:
    matchPaths:
    - path: /opt/bitnami/apache/bin/httpd
---
apiVersion: security.kubearmor.com/v1
kind: KubeArmorPolicy
metadata:
  name: test-wordpress-block-worksgreat
  namespace: test-wordpress-block
spec:
  action: Allow
  message: "Generates logs because entrypoint is permitted"
  selector:
    matchLabels:
      test-kubarmor-policy: test-wordpress-block
  process:
    matchPaths:
    - path: /opt/bitnami/apache/bin/httpd
    - path: /opt/bitnami/scripts/wordpress/entrypoint.sh
  file:
    matchDirectories:
    - dir: /opt/bitnami/scripts/wordpress/entrypoint.sh