post image January 6, 2022 | 2 min Read

AppArmor with Docker and Kubernetes

Example

apt-get install apparmor
apt-get install apparmor-utils

aa-status

# generate a profile for CURL
aa-genprof curl


cat  /etc/apparmor.d/usr.bin.curl 
# Last Modified: Tue Apr 13 20:23:56 2021
#include <tunables/global>

/usr/bin/curl {
  #include <abstractions/base>

  /lib/x86_64-linux-gnu/ld-*.so mr,
  /usr/bin/curl mr,

}

# load newly defined profile
apparmor_parser /etc/apparmor.d/docker-nginx 

# remove already existing profile
apparmor_parser -R /etc/apparmor.d/some-profile

# default AppArmor profile
 docker run --security-opt apparmor=docker-default nginx
Unable to find image 'nginx:latest' locally
latest: Pulling from library/nginx
f7ec5a41d630: Pull complete 
aa1efa14b3bf: Pull complete 
b78b95af9b17: Pull complete 
c7d6bca2b8dc: Pull complete 
cf16cd8e71e0: Pull complete 
0241c68333ef: Pull complete 
Digest: sha256:75a55d33ecc73c2a242450a9f1cc858499d468f077ea942867e662c247b5e412
Status: Downloaded newer image for nginx:latest
/docker-entrypoint.sh: /docker-entrypoint.d/ is not empty, will attempt to perform configuration
/docker-entrypoint.sh: Looking for shell scripts in /docker-entrypoint.d/
/docker-entrypoint.sh: Launching /docker-entrypoint.d/10-listen-on-ipv6-by-default.sh
10-listen-on-ipv6-by-default.sh: info: Getting the checksum of /etc/nginx/conf.d/default.conf
10-listen-on-ipv6-by-default.sh: info: Enabled listen on IPv6 in /etc/nginx/conf.d/default.conf
/docker-entrypoint.sh: Launching /docker-entrypoint.d/20-envsubst-on-templates.sh
/docker-entrypoint.sh: Launching /docker-entrypoint.d/30-tune-worker-processes.sh
/docker-entrypoint.sh: Configuration complete; ready for start up


# custom AppArmor profile
 docker run --security-opt apparmor=docker-nginx nginx
/docker-entrypoint.sh: No files found in /docker-entrypoint.d/, skipping configuration
/docker-entrypoint.sh: 13: /docker-entrypoint.sh: cannot create /dev/null: Permission denied



**An example of apparmor profile''


apiVersion: v1                                                                   [0/1787]
kind: Pod                                                                                
metadata:                                                                                
  annotations:                                                                           
    container.apparmor.security.beta.kubernetes.io/secure: localhost/docker-nginx        
  creationTimestamp: null
  labels:
    run: secure
  name: secure
spec:
  containers:
  - image: nginx
    name: secure
    resources: {}
  dnsPolicy: ClusterFirst
  restartPolicy: Always
status: {}

**Restrict particular path in Nginx''


vim /etc/apparmor.d/usr.sbin.nginx-updated

...
#include <tunables/global>
  
profile restricted-nginx flags=(attach_disconnected,mediate_deleted) {
  #include <abstractions/base>

  network inet tcp,
  network inet udp,
  network inet icmp,

  deny network raw,

  deny network packet,

  file,
  umount,

  deny /bin/** wl,
  deny /usr/share/nginx/html/restricted/* rw,
  deny /boot/** wl,
...
:wq!

**Load apparmor profile''

apparmor_parser  /etc/apparmor.d/usr.sbin.nginx-updated

**Create Nginx pod with restrction''

cat CKS/custom-nginx.yaml 

apiVersion: v1
kind: Pod
metadata:
    creationTimestamp: null
    labels:
        run: nginx
    name: nginx
    annotations:
        container.apparmor.security.beta.kubernetes.io/nginx: localhost/restricted-nginx
        #container.apparmor.security.beta.kubernetes.io/nginx: localhost/custom-nginx
spec:
    containers:
        -
            image: 'nginx:alpine'
            name: nginx
            volumeMounts:
                -
                    mountPath: /usr/share/nginx/html
                    name: test-volume
    volumes:
        -
            name: test-volume
            hostPath:
                path: /data/pages
                type: Directory
author image

Jan Toth

I have been in DevOps related jobs for past 6 years dealing mainly with Kubernetes in AWS and on-premise as well. I spent quite a lot …

comments powered by Disqus