Question 9: AppArmor Profile

Problem Statement

Solve this question on: ssh cks7262

Some containers need to run more secure and restricted. There is an existing AppArmor profile located at /opt/course/9/profile on cks7262 for this.

Tasks:

  1. Install the AppArmor profile on Node cks7262-node1
  2. Connect using ssh cks7262-node1 from cks7262
  3. Add label security=apparmor to the Node
  4. Create a Deployment named apparmor in Namespace default with:
    • One replica of image nginx:1.27.1
    • NodeSelector for security=apparmor
    • Single container named c1 with the AppArmor profile enabled only for this container
  5. The Pod might not run properly with the profile enabled. Write the logs of the Pod into /opt/course/9/logs on cks7262 so another team can work on getting the application running.
Use sudo -i to become root which may be required for this question

Solution

Step 1: Examine and Install AppArmor Profile

First, let's examine the provided profile:

➜ ssh cks7262 

➜ candidate@cks7262:~# vim /opt/course/9/profile
# cks7262:/opt/course/9/profile 

#include 
  
profile very-secure flags=(attach_disconnected) {
  #include 

  file,

  # Deny all file writes.
  deny /** w,
}

This is a simple profile named very-secure which denies all file writes. Now, let's copy it to the Node and install it:

➜ candidate@cks7262:~# scp /opt/course/9/profile cks7262-node1:~/
profile                                     100%  161   329.9KB/s   00:00

➜ candidate@cks7262:~# ssh cks7262-node1

➜ candidate@cks7262-node1:~# ls
profile

➜ candidate@cks7262-node1:~# sudo apparmor_parser -q ./profile

Let's verify the profile has been installed:

➜ candidate@cks7262-node1:~# sudo apparmor_status
apparmor module is loaded.
7 profiles are loaded.
2 profiles are in enforce mode.
   cri-containerd.apparmor.d
   very-secure
0 profiles are in complain mode.
0 profiles are in prompt mode.
0 profiles are in kill mode.
5 profiles are in unconfined mode.
   firefox
   opera
   steam
   stress-ng
   thunderbird
36 processes have profiles defined.
36 processes are in enforce mode.
   /usr/local/apache2/bin/httpd (13154) cri-containerd.apparmor.d
...
Step 2: Label the Node

Add the required label to the Node:

➜ candidate@cks7262:~# k label node cks7262-node1 security=apparmor
Step 3: Create the Deployment

Create a Deployment that uses the AppArmor profile:

➜ candidate@cks7262:~# k create deploy apparmor --image=nginx:1.27.1 --dry-run=client -o yaml > 9_deploy.yaml

➜ candidate@cks7262:~# vim 9_deploy.yaml
# 9_deploy.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  creationTimestamp: null
  labels:
    app: apparmor
  name: apparmor
  namespace: default
spec:
  replicas: 1
  selector:
    matchLabels:
      app: apparmor
  strategy: {}
  template:
    metadata:
      creationTimestamp: null
      labels:
        app: apparmor
    spec:
      nodeSelector:                          # add
        security: apparmor                   # add
      containers:
      - image: nginx:1.27.1
        name: c1                             # change
        securityContext:                     # add
          appArmorProfile:                   # add
            type: Localhost                  # add
            localhostProfile: very-secure    # add

➜ candidate@cks7262:~# k -f 9_deploy.yaml create

Let's check the status of the Pod:

➜ candidate@cks7262:~# k get pod -owide | grep apparmor
apparmor-56b8498684-nshbp     0/1     CrashLoopBackOff  ...   cks7262-node1

The Pod is in CrashLoopBackOff state. Let's check the logs:

➜ candidate@cks7262:~# k logs apparmor-56b8498684-nshbp
/docker-entrypoint.sh: 13: /docker-entrypoint.sh: cannot create /dev/null: Permission denied
/docker-entrypoint.sh: No files found in /docker-entrypoint.d/, skipping configuration
2024/09/07 16:19:08 [emerg] 1#1: mkdir() "/var/cache/nginx/client_temp" failed (13: Permission denied)
nginx: [emerg] mkdir() "/var/cache/nginx/client_temp" failed (13: Permission denied)

Let's verify the AppArmor profile is being applied:

➜ candidate@cks7262:~# ssh cks7262-node1

➜ candidate@cks7262-node1:~# sudo -i

➜ root@cks7262-node1:~# crictl pods | grep apparmor
42e0152b4f1d6       44 seconds ago      Ready    apparmor-56b8498684-nshbp  ...

➜ root@cks7262-node1:~# crictl ps -a | grep 42e0152b4f1d6
CONTAINER      ...   STATE     NAME  ...  POD ID          POD
c9f0c4a8f4d4a  ...   Exited    c1    ...  42e0152b4f1d6   apparmor-56b8498684-nshbp

➜ root@cks7262-node1:~# crictl inspect c9f0c4a8f4d4a | grep -i profile
            "profile_type": 1
            "profile_type": 2,
          "apparmor_profile": "localhost/very-secure"
        "apparmorProfile": "very-secure",
Step 4: Save Pod Logs

Finally, let's save the Pod logs to the required location:

➜ candidate@cks7262:~# k logs apparmor-56b8498684-nshbp > /opt/course/9/logs
The AppArmor profile has been successfully implemented:
  • The profile has been installed on the Node
  • The Node has been labeled with security=apparmor
  • The Deployment has been created with the AppArmor profile enabled
  • The Pod logs have been saved for further investigation
Back to Questions List