Skip to content

Apparmor whitelisting policy not working

Shreyas Mishra edited this page Jul 19, 2023 · 1 revision

Conjur-nginx Whitelisting policy not working

Policy

apiVersion: security.kubearmor.com/v1
kind: KubeArmorPolicy
metadata:
  name: conjur-nginx
  namespace: conjur
spec:
  selector:
    matchLabels:
      kubearmor.io/container.name: '[conjur-nginx]'
  action: Allow
  file:
    matchDirectories:
    - dir: /etc/nginx/
      recursive: true
      action: Block
    - dir: /etc/nginx/
      recursive: true
      fromSource:
      - path: /usr/sbin/nginx
    - dir: /opt/conjur/etc/ssl/
      recursive: true
      action: Block
    - dir: /opt/conjur/etc/ssl/
      recursive: true
      fromSource:
      - path: /usr/sbin/nginx
    - dir: /
      recursive: true
  process:
    matchDirectories:
    - dir: /
      recursive: true
  message: Conjur-nginx-policy

Behaviour

When we apply the whitelisting policy above we notice that while starting conjur-nginx container in conjur-oss deployment the apparmor blocks nginx to access to /etc/nginx folder.

Alert

image

Error in the pod

i2023/07/10 20:05:54 [emerg] 1#1: open() "/etc/nginx/nginx.conf" failed (13: Permission denied                                                                nginx: [emerg] open() "/etc/nginx/nginx.conf" failed (13: Permission denied)

Analysis

From the alert we know that /usr/sbin/nginx is the process which is being denied permission even though we gave it access.

Is there a problem with the apparmor policy ??

When we exec into the container and try to run /usr/sbin/nginx we don't get denied by apparmor. Which means there is no problem with the apparmor policy.

Can it be some problem with the dockerfile and entrypoint script ?

Now when building and running this dockerfile (link) the apparmor does not block access to etc/nginx .

Why ???

We find that the dockerfile used in conjur doesnt run the "/docker-entrypoint.sh" script as entrypoint and directly runs nginx.

## == Dispatcher profile START == ##
profile kubearmor-conjur-conjur-conjur-oss-conjur-nginx flags=(attach_disconnected,mediate_deleted) {
        ## == PRE START == ##
        #include <abstractions/base>
                                network,
                                capability,
        ## == PRE END == ##
        ## == File/Dir START == ##
        /{,**} klmrw,
        deny /etc/nginx/{,**} klmrw,
        deny /opt/conjur/etc/ssl/{,**} klmrw,
  ## == File/Dir END == ##
        ## == DISPATCHER START == ##
                                /usr/sbin/nginx px -> kubearmor-conjur-conjur-conjur-oss-conjur-nginx-/usr/sbin/nginx,
        /{,**} ix,
        ## == DISPATCHER END == ##

profile kubearmor-conjur-conjur-conjur-oss-conjur-nginx-/usr/sbin/nginx {
        /usr/sbin/nginx rix,

        ## == PRE START == ##
        #include <abstractions/base>
                                network,
                                capability,
        ## == PRE END == ##

        ## == File/Dir START == ##
        /{,**} klmrw,
        /etc/nginx/{,**} klmrw,
        /opt/conjur/etc/ssl/{,**} klmrw,
  ## == File/Dir END == ##
        ## == DISPATCHER START == ##
        ## == DISPATCHER END == ##


Understanding Apparmor profile

When a process is running under kubearmor-conjur-conjur-conjur-oss-conjur-nginx profile have deny rules that denies access to /etc/nginx/ and /opt/conjur/etc/ssl/ directories.

kubearmor-conjur-conjur-conjur-oss-conjur-nginx-/usr/sbin/nginx : The profile grants read permissions to /usr/sbin/nginx.

this line between the dispatcher start and end /usr/sbin/nginx px -> kubearmor-conjur-conjur-conjur-oss-conjur-nginx-/usr/sbin/nginx Transitions the profile to kubearmor-conjur-conjur-conjur-oss-conjur-nginx-/usr/sbin/nginx profile which has access to /etc/nginx folder.

With an entrypoint script:

The entrypoint script is started under the kubearmor-conjur-conjur-conjur-oss-conjur-nginx profile, and then when it executes Nginx (/usr/sbin/nginx), a profile transition is triggered, and the Nginx process is then governed by the kubearmor-conjur-conjur-conjur-oss-conjur-nginx-/usr/sbin/nginx profile. image

Without an entrypoint script:

The container directly starts the Nginx process as the main process which means that the container will share the same process ID as the host system. The AppArmor profile attached to the process will depend on containerd configuration which in this case does not have access to the /etc/nginx/ and /opt/conjur/etc/ssl/ directories. image

Clone this wiki locally