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.49k stars 343 forks source link

Kubearmor does not enforce anything on pod's entrypoint or execs to kubernetes pods #1728

Open alexeysofin opened 6 months ago

alexeysofin commented 6 months ago

Bug Report

General Information

To Reproduce

  1. Apply policy
apiVersion: security.kubearmor.com/v1
kind: KubeArmorPolicy
metadata:
  name: allow-exec-binaries
  namespace: default
spec:
  action: Allow
  file:
    matchDirectories:
    - dir: /
      recursive: true
  process:
    matchPaths:
    - path: /usr/bin/sleep
    - path: /usr/sbin/nginx
  selector:
    matchLabels:
      app: nginx
  1. Create nginx deployment
kubectl create deployment nginx --image=nginx
  1. Exec to running pod
kubectl exec -ti $(kubectl get pod -l app=nginx -o name) -- bash

Expected behavior

Permission denied for bash or at least more clear documentation for how k8s exec commands and apparmor profiles are inter-related. Scrolling though code, I couldn't easily find what's happening either.

Generated apparmor profile looks as follows /etc/apparmor.d/kubearmor-default-nginx-nginx

## == Managed by KubeArmor == ##
#include <tunables/global>

## == Dispatcher profile START == ##
profile kubearmor-default-nginx-nginx flags=(attach_disconnected,mediate_deleted) {
    ## == PRE START == ##
    #include <abstractions/base>

    network,
    capability,
    ## == PRE END == ##

    ## == File/Dir START == ##
    /{,**} klmrw,
    ## == File/Dir END == ##
    ## == DISPATCHER START == ##
    /usr/bin/sleep ix,
    /usr/sbin/nginx ix,
    ## == DISPATCHER END == ##

  ## == Network START == ##
  ## == Network END == ##

  ## == Capabilities START == ##
  ## == Capabilities END == ##

    ## == Native Policy START == ##

    ## == Native Policy END == ##

    ## == POST START == ##
    /lib/x86_64-linux-gnu/{*,**} rm,

    deny @{PROC}/{*,**^[0-9*],sys/kernel/shm*} wkx,
    deny @{PROC}/sysrq-trigger rwklx,
    deny @{PROC}/mem rwklx,
    deny @{PROC}/kmem rwklx,
    deny @{PROC}/kcore rwklx,

    deny mount,

    deny /sys/[^f]*/** wklx,
    deny /sys/f[^s]*/** wklx,
    deny /sys/fs/[^c]*/** wklx,
    deny /sys/fs/c[^g]*/** wklx,
    deny /sys/fs/cg[^r]*/** wklx,
    deny /sys/firmware/efi/efivars/** rwklx,
    deny /sys/kernel/security/** rwklx,

    ## == POST END == ##
}
## == Dispatcher profile END == ##

## == FromSource per binary profiles START == ##
## == FromSource per binary profiles END == ##

## == Templates section START == ##

And this same profile if applied without kubearmor does prevent bash or anything other than nginx/sleep from running which makes sense, moreover it prevents nginx from running because of missing some other permissions. Is kubearmor somewhat different in that regard? Maybe someone can at least point to the code where this logic that skips enforcement of commands lives.

Prateeknandle commented 5 months ago

Hey @alexeysofin, we tried this scenario ourselves and we found that the behaviour is the same of the apparmor profiles irrespective of the kubearmor presence.

I've tried out this same profile and in the absence of kubearmor, kubectl exec is not blocked, this is the expected behaviour. PTAL https://github.com/kubearmor/KubeArmor/wiki/Enforcer-Feature-Parity