AppArmor Security Profiles for Kubernetes

๐Ÿ’ก AppArmor Security Profiles for Kubernetes โ€” Executive Summary

Technical architectural analysis, practical configuration manifests, and deployment instructions for AppArmor Security Profiles for Kubernetes.

๐Ÿ“‘ Table of Contents

Understanding AppArmor behavior

Why AppArmor? (DAC vs MAC)

  • Discretionary Access Control (DAC)
  • Definition: Linux’s basic security model that grants file permissions (rwxrwxrwx) based on user/group identity.
  • Limits: The process inherits all privileges of the user that runs it.
  • Vulnerability Example: When a simple log cleanup program (cleanup.sh) is running with root privileges, even if it is contaminated by an attacker and attempts to leak important data to the external Internet or execute a binary such as ping, there is no way to restrict this in the DAC environment because the user is root.
  • Mandatory Access Control (MAC)
  • Definition: Forcibly constrains the behavior of a process based on a central, predefined security policy (profile).
  • Effect: Even if the process runs with root privileges, any actions not specified in the profile (e.g. connecting to the Internet, accessing unauthorized files, etc.) are blocked.
  • Alternative solutions: Representative examples include SELinux (RedHat family, complex configuration) and AppArmor (Ubuntu/Debian family, intuitive and relatively easy configuration).

AppArmor’s core mode and profile controls

AppArmor can operate in three modes on your system:

1. AppArmor 3 modes

  1. Enforce (enforcement mode): Immediately blocks unauthorized activity by enforcing the defined security profile.
  2. Complain (report mode): Does not block policy violations, but only records them in the logs (syslog, audit.log). (Mainly used in the testing phase before application to the operating environment)
  3. Unconfined: Runs like a normal process without any restrictions.
bash
# ํŠน์ • ํ”„๋กœํŒŒ์ผ์„ 'Enforce (์‹ค์ œ ์ฐจ๋‹จํ•˜๋Š” ๋ชจ๋“œ)'๋กœ ๋ณ€๊ฒฝ
sudo aa-enforce /etc/apparmor.d/$profile

# ํŠน์ • ํ”„๋กœํŒŒ์ผ์„ 'Complain (๋กœ๊ทธ๋งŒ ๋‚จ๊ธฐ๋Š” ๋ชจ๋“œ)'๋กœ ๋ณ€๊ฒฝ
sudo aa-complain /etc/apparmor.d/$profile

# ํ”„๋กœํ•„ ์ œ๊ฑฐ = 'Unconfined (ํ”„๋กœํ•„์ด ์ ์šฉ๋˜์ง€ ์•Š์€ ์ƒํƒœ)'๋กœ ๋ณ€๊ฒฝ
sudo apparmor_parser -R /etc/apparmor.d/$profile

2. Hands-on: Automatic profile creation process

Instead of writing rules manually, you can easily build profiles using AppArmor’s monitoring tools.

  1. Utility Installation
bash
   # auditd ์„ค์น˜ (syslog์— Appํ™œ๋™ ๊ธฐ๋ก, profile ์ž๋™์ƒ์„ฑ์‹œ ํ•„์š”)
   sudo apt install -y auditd
   # auditd ์„œ๋น„์Šค ์‹œ์ž‘ ๋ฐ ๋ถ€ํŒ… ์‹œ ์ž๋™ ์‹คํ–‰ ์„ค์ •
   sudo systemctl start auditd
   sudo systemctl enable auditd

   sudo apt-get install -y apparmor-utils
  1. Write target script (/root/apparmor/app.sh)
bash
   mkdir -p /root/apparmor/

   cat <<EOF > /root/apparmor/app.sh
   #!/bin/bash
   touch /tmp/file.txt       # ์ž„์‹œ ํŒŒ์ผ ์ƒ์„ฑ
   echo "File Created"
   rm /tmp/file.txt          # ์ž„์‹œ ํŒŒ์ผ ์‚ญ์ œ
   echo "File Removed"
   EOF
  1. Run automatic profile creation
bash
   sudo aa-genprof /root/apparmor/app.sh
  • After execution, actually run the script (./app.sh) in another terminal to create the file access pattern you normally need.
  • Return to the aa-genprof screen, enter S to scan the log, and select Inherit or Allow for access requests.
  • Once the profile is saved, a file is created in the /etc/apparmor.d/root.apparmor.app.sh path.


Allow Guide (S โ€“ I โ€“ I โ€“ A โ€“ A โ€“ A โ€“ A โ€“ S โ€“ F)

bash
   [(S)can system log for AppArmor events] / (F)inish
   Reading log entries from /var/log/audit/audit.log.

   Profile:  /root/apparmor/app.sh
   Execute:  /usr/bin/touch
   Severity: 3

   (I)nherit / (C)hild / (N)amed / (X) ix On / (D)eny / Abo(r)t / (F)inish

   Profile:  /root/apparmor/app.sh
   Execute:  /usr/bin/rm
   Severity: unknown

   (I)nherit / (C)hild / (N)amed / (X) ix On / (D)eny / Abo(r)t / (F)inish
   Complain-mode changes:

   Profile:  /root/apparmor/app.sh
   Path:     /dev/tty
   New Mode: owner rw
   Severity: 9

    [1 - include <abstractions/consoles>]
     2 - owner /dev/tty rw,
   (A)llow / [(D)eny] / (I)gnore / (G)lob / Glob with (E)xtension / (N)ew / Audi(t) / (O)wner permissions off / Abo(r)t / (F)inish
   Adding include <abstractions/consoles> to profile.

   Profile:  /root/apparmor/app.sh
   Path:     /etc/ld.so.cache
   New Mode: owner r
   Severity: 1

    [1 - owner /etc/ld.so.cache r,]
   (A)llow / [(D)eny] / (I)gnore / (G)lob / Glob with (E)xtension / (N)ew / Audi(t) / (O)wner permissions off / Abo(r)t / (F)inish
   Adding owner /etc/ld.so.cache r, to profile.

   Profile:  /root/apparmor/app.sh
   Path:     /etc/locale.alias
   New Mode: owner r
   Severity: unknown

    [1 - owner /etc/locale.alias r,]
   (A)llow / [(D)eny] / (I)gnore / (G)lob / Glob with (E)xtension / (N)ew / Audi(t) / (O)wner permissions off / Abo(r)t / (F)inish
   Adding owner /etc/locale.alias r, to profile.

   Profile:  /root/apparmor/app.sh
   Path:     /tmp/file.txt
   New Mode: owner w
   Severity: unknown

    [1 - include <abstractions/user-tmp>]
     2 - owner /tmp/file.txt w,
   (A)llow / [(D)eny] / (I)gnore / (G)lob / Glob with (E)xtension / (N)ew / Audi(t) / (O)wner permissions off / Abo(r)t / (F)inish
   Adding include <abstractions/user-tmp> to profile.

   = Changed Local Profiles =

   The following local profiles were changed. Would you like to save them?

    [1 - /root/apparmor/app.sh]
   (S)ave Changes / Save Selec(t)ed Profile / [(V)iew Changes] / View Changes b/w (C)lean profiles / Abo(r)t
   Writing updated profile for /root/apparmor/app.sh.

   Profiling: /root/apparmor/app.sh

   Please start the application to be profiled in
   another window and exercise its functionality now.

   Once completed, select the "Scan" option below in
   order to scan the system logs for AppArmor events.

   For each AppArmor event, you will be given the
   opportunity to choose whether the access should be
   allowed or denied.

   [(S)can system log for AppArmor events] / (F)inish
   Setting /root/apparmor/app.sh to enforce mode.

   Reloaded AppArmor profiles in enforce mode.

   Please consider contributing your new profile!
   See the following wiki page for more information:
   https://gitlab.com/apparmor/apparmor/wikis/Profiles

   Finished generating profile for /root/apparmor/app.sh.


4. Testing unauthorized behavior
โ€“ If you secretly add an unauthorized binary call such as ping localhost to the script and then run it, operation will be severely restricted with a Permission Denied error even if the executor is root.
5. How to deactivate (remove) a profile

bash
   sudo apparmor_parser -R /etc/apparmor.d/root.apparmor.app.sh

AppArmor integration in Kubernetes (K8s) environments

Kubernetes can load and apply a node-level AppArmor profile to improve the security of containers inside a Pod.

1. Prerequisites

  • AppArmor must be enabled in the Node kernel.
  • The AppArmor profile to be applied to the container must be preloaded on the file system of all nodes on which the pod will run.

2. Example AppArmor profile for K8s (deny all writes)

How to parse after registering in /etc/apparmor.d/k8s-deny-write file:

bash
cat <<EOF > /etc/apparmor.d/k8s-deny-write
profile k8s-apparmor-example-deny-write flags=(attach_disconnected) {
	file,
	# ๋ชจ๋“  ์“ฐ๊ธฐ ๋™์ž‘ ์ฐจ๋‹จ (์—ฌ๊ธฐ์„œ์˜ #์€ ์‹ค์ œ ์ฃผ์„์ž…๋‹ˆ๋‹ค)
	deny /** w,
}
EOF
bash
# ๋กœ๋“œ
sudo apparmor_parser -r -W /etc/apparmor.d/k8s-deny-write

# ํ”„๋กœํ•„ ๋กœ๋“œ ์ƒํƒœ ํ™•์ธ
aa-status | grep k8s-apparmor-example-deny-write

3. Pod manifest settings (apply securityContext)

Declare the profile via securityContext according to the V1.30+ specification or the general Pod specification.

bash
cat <<EOF | kubectl apply -f - 
apiVersion: v1
kind: Pod
metadata:
  name: hello-apparmor
spec:
  securityContext:
    appArmorProfile:
      type: Localhost
      localhostProfile: k8s-apparmor-example-deny-write # ๋…ธ๋“œ์— ๋กœ๋“œ๋œ ํ”„๋กœํ•„ ์ด๋ฆ„
  containers:
  - name: busybox
    image: busybox:1.36
    command: ["sh", "-c", "echo 'Hello AppArmor' && sleep 3600"]
EOF

k get pods hello-apparmor


[!IMPORTANT]
Troubleshooting

  • If the profile with the name specified by localhostProfile is not actually loaded on the node, the Pod will not run and will remain in the ContainerCreating state.
  • When you run kubectl describe pod , you will see the error message Failed to create container... AppArmor profile not found. Therefore, you must deploy security profiles to all nodes in batches using DaemonSet or a provisioning tool.

4. Profile application test

bash
kubectl exec -it hello-apparmor -- sh
# in container

touch /tmp/test.txt
```prompt
touch: /tmp/test.txt: Permission denied
`

echo "test" > /var/log/test.log
```prompt
sh: can't create /var/log/test.log: nonexistent directory
`

5. Clean up test resources

bash
# ํ”„๋กœํ•„ ์ œ๊ฑฐ
sudo apparmor_parser -R /etc/apparmor.d/k8s-deny-write

# ํ”„๋กœํ•„ ํŒŒ์ผ ์ œ๊ฑฐ
rm /etc/apparmor.d/k8s-deny-write

# ์ œ๊ฑฐ
k delete pods hello-apparmor --force

Key summary

  • AppArmor is a powerful Linux security module that complements DACโ€™s โ€˜excessive root privilege inheritanceโ€™ problem.
  • Production application strategy: If you apply Enforce mode right from the beginning, a disaster may occur where actual service functions are interrupted. Therefore, it is standard to start with Complain mode, analyze logs, and then change to Enforce when it is stabilized.
  • K8s Security Fundamentals: The pattern of combining AppArmor settings with Pod-level securityContext is essential to solidify the security perimeter in CKS testing and enterprise environments.

References


Summary of Kubernetes usage

1. Overview & Concepts

AppArmor (Application Armor) is a Mandatory Access Control (MAC) system implemented in the Linux kernel. Complements traditional Unix-style discretionary access control (DAC, based on file owner and permissions) to restrict processes from accessing system resources (files, networks, functions, etc.).

Key concepts

  • Path-based restrictions: While SELinux operates based on the โ€˜Labelโ€™ of the file system, AppArmor applies security rules based on the absolute path of the file, making it intuitive and easy to manage.
  • Profile: A text file that defines a list of tasks that a particular application or executable can perform. It is mainly located in the /etc/apparmor.d/ directory.
  • Execution Modes:
  • Enforce (Enforce mode): Do not allow, block, and log actions not defined in the profile.
  • Complain: Does not block if rules are violated, just logs what actions are not allowed. (Mainly used during development and profile learning stages)

Flow in Kubernetes environment


โ€“ Applies to: Executable files (binaries) or processes in a specific path
โ€“ Operates in: not inside the container, in the Linux kernel (LSM: Linux Security Module) on the host device
โ€“ Restricting actions: * Read, write, and execute permissions for specific files/directories (r, w, x)
โ€“ Network socket creation and communication
โ€“ Use special functions (Capabilities) such as RAW capture

If you look at the flow of applying AppArmor in Kubernetes, it becomes clear why the process is subject to control.

  1. Load profile to host node: First, register the profile with AppArmor on the Kubernetes worker node (host OS). (Example: k8s-apparmor-deny-write)
  2. Declared in Pod YAML: Assigns that profile to a specific container through Pod settings.
  3. Applied when running the container: When the container runs, the container’s main process (PID 1) and its child processes are subject to profile restrictions by the host kernel.
References and Guidelines (NOTE)

Easy to understand example
If a process inside the container attempts to modify the /etc/passwd file or attempts an unauthorized network binding, AppArmor intercepts this at the host kernel level, generates a Permission Denied error, and blocks it.

Cluster Requirements

  • Kubernetes version: 1.4\~
  • AppArmor kernel module must be available. โ€” In order to force the AppArmor profile to the Linux kernel, the AppArmor kernel module must be installed and available. For example, distributions such as Ubuntu and SUSE support the module by default, while many others support it optionally.
bash
  # ๋ชจ๋“ˆ์ด ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•œ์ง€ ํ™•์ธํ•˜๋ ค๋ฉดย ๋‹ค์Œ์ด `Y`์ธ์ง€ ํ™•์ธ
  cat /sys/module/apparmor/parameters/enabled
  • Container runtime supports AppArmor. โ€” Container runtimes such as Docker (original, Docker), CRI-O or containerd that currently support all common Kubernetes use AppArmor. Must support. You should refer to this runtime documentation to ensure that your cluster meets the requirements to use AppArmor.
  • The profile is loaded. โ€” AppArmor applies to pods by specifying the AppArmor profile that should run with each container. If the profile specified in the kernel is not loaded, Kubelet (>= v1.4) rejects the pod.
bash
  # ํ•ด๋‹น ๋…ธ๋“œ์— ์–ด๋–ค ํ”„๋กœํŒŒ์ผ์ด ์ ์žฌ๋˜์—ˆ๋Š”์ง€๋Š”ย ๋‹ค์Œ์„ ํ†ตํ•ด ํ™•์ธ
  ssh nodename "sudo cat /sys/kernel/security/apparmor/profiles | sort"

About scope of application and profile designation

  • AppArmor profiles can be specified at the pod level or container level. Container AppArmor profiles have higher priority than pod profiles.
  • pod.spec.containers.securityContext.appArmorProfile
  • pod.spec.securityContext.appArmorProfile
  • appArmorProfile
yaml
  securityContext:
    appArmorProfile:
      type: <profile_type>
  • is one of the following:
    • RuntimeDefault: Use the runtime’s default profile
    • Localhost: Use profile loaded on host (see below)
    • Unconfined: Run without AppArmor
  • Description
    โ€œ`yaml
    k explain pod.spec.securityContext.appArmorProfile
    โ€”
    KIND: Pod
    VERSION: v1

    FIELD: appArmorProfile

    DESCRIPTION:
    appArmorProfile is the AppArmor options to use by the containers in this
    pod. Note that this field cannot be set when spec.os.name is windows.
    AppArmorProfile defines a pod or containerโ€™s AppArmor settings.

    FIELDS:
    localhostProfile
    localhostProfile indicates a profile loaded on the node that should be used.
    The profile must be preconfigured on the node to work. Must match the loaded
    name of the profile. Must be set if and only if type is โ€œLocalhostโ€.

    type -required-
    enum: Localhost, RuntimeDefault, Unconfined
    type indicates which kind of AppArmor profile will be applied. Valid options
    are:
    Localhost โ€“ a profile pre-loaded on the node.
    RuntimeDefault โ€“ the container runtimeโ€™s default profile.
    Unconfined โ€“ no AppArmor enforcement.

    Possible enum values:
     - `"Localhost"` indicates that a profile pre-loaded on the node should be
    used.
     - `"RuntimeDefault"` indicates that the container runtime's default
    AppArmor profile should be used.
     - `"Unconfined"` indicates that no AppArmor profile should be enforced.
    

    โ€œ`

2. System Architecture

AppArmor operates in close connection with management tools in user space and the LSM (Linux Security Module) framework within the Linux kernel.

Architecture & System Flow Diagram
Architecture & System Flow
Pan & Zoom

3. Sequence Diagram

This is a runtime flow in which the AppArmor kernel module checks and processes when a container or general process attempts to access a file.

Architecture & System Flow Diagram
Architecture & System Flow
Pan & Zoom

4. System binary

AppArmor provides a variety of userspace tools and binaries for interacting with the kernel and managing profiles.

As it is a kernel security tool, it must be run separately on each node.

Core Management Binary


Binaries other than apparmor_parser and aa-status are confirmed to be outside the scope of the CKS exam.

  • apparmor_parser: The core binary of AppArmor. The human-readable text profile is parsed, compiled into a binary format that the kernel can understand, and then loaded into the kernel.
bash
  # -r ํ”Œ๋ž˜๊ทธ์™€ ํ•จ๊ป˜ ์‚ฌ์šฉํ•˜๋ฉด create/update ๋ชจ๋‘ ๋Œ€์‘๊ฐ€๋Šฅ
  sudo apparmor_parser -r /etc/apparmor.d/$profile
  # ํ”„๋กœํŒŒ์ผ ์ ์šฉ
  sudo apparmor_parser $profile
  • aa-status (or apparmor_status): Checks the AppArmor status of the current system. Shows the number of loaded profiles, the mode (Enforce/Complain) for each profile, and a list of processes being quarantined by the profile being applied.
bash
  # ์‹คํ–‰๋œ ๋…ธ๋“œ์˜ ๋กœ๋“œ๋œ ํ”„๋กœํ•„ ๋ชฉ๋ก ์กฐํšŒ
  sudo aa-status

  # ํ”„๋กœํŒŒ์ผ ํ™œ์„ฑํ™”์—ฌ๋ถ€ ์กฐํšŒ
  sudo aa-status | grep $profile

System diagnosis and verification

  • aa-enabled This is a binary that simply answers whether AppArmor is enabled in the current system kernel with Yes or No. Mainly used in script branch statements.
bash
  aa-enabled

Direct process isolation execution (outside the scope of the question)

  • aa-exec Used when executing a program while forcing a specific AppArmor profile.
bash
  aa-exec -p <ํ”„๋กœํ•„์ด๋ฆ„> <์‹คํ–‰ํ• ๋ช…๋ น์–ด>

System management and initialization (mainly used during booting/shutdown) (outside the scope of the exam)

  • aa-teardown Removes and unloads all AppArmor profiles loaded in the current kernel at once. In other words, it is used to temporarily completely disable all of AppArmor’s defenses. (Must be used with caution.)
bash
  sudo aa-teardown
  • aa-remove-unknown Among the profiles loaded in the kernel, โ€˜Unknownโ€™ profiles that do not exist as actual files in the current /etc/apparmor.d/ directory are identified and automatically removed cleanly from the kernel.
bash
  sudo aa-remove-unknown
  • aa-load This is an internal script used to reload policy files in /etc/apparmor.d/ into the kernel all at once. (Similar to running apparmor_parser -r over the entire directory we learned earlier.)
bash
  sudo aa-load

For developer and internal verification (outside the scope of the exam)

  • aa-features-abi Outputs the AppArmor feature interface version supported by the current Linux kernel. It is rarely used directly in general operations or testing.
bash
  aa-features-abi

5. Utility binary

Profile creation and change management binary (outside the scope of the exam)

  • aa-genprof: Used when creating a profile for a new application from scratch. It automatically builds a rudimentary profile by running the program and monitoring its behavior.
bash
  sudo aa-genprof /usr/bin/custom-app
  # ๋ช…๋ น์–ด๋ฅผ ์‹คํ–‰ํ•˜๋ฉด ๋Œ€๊ธฐ ์ƒํƒœ๊ฐ€ ๋ฉ๋‹ˆ๋‹ค. 
  # ๋‹ค๋ฅธ ํ„ฐ๋ฏธ๋„์—์„œ custom-app์„ ์‹คํ–‰ํ•ด ์ •์‚ญ์ ์ธ ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•œ ๋’ค, 
  # ๋‹ค์‹œ ๋Œ์•„์™€ 'S'๋ฅผ ๋ˆŒ๋Ÿฌ ๋กœ๊ทธ๋ฅผ ์Šค์บ”ํ•˜๊ณ  ํ”„๋กœํ•„์„ ์ €์žฅํ•ฉ๋‹ˆ๋‹ค.
  • aa-logprof: Scans system logs (/var/log/audit/audit.log or syslog) generated by Complain mode, etc., and interactively asks and updates the behavior of newly discovered applications to add to existing profiles.
bash
  sudo aa-logprof
  # ์‹œ์Šคํ…œ ๋กœ๊ทธ๋ฅผ ์ฝ์–ด์™€ ํ—ˆ์šฉ ์—ฌ๋ถ€๋ฅผ ๋ฌป๋Š” ์ธํ„ฐ๋ž™ํ‹ฐ๋ธŒ ์ฐฝ(Y/N/A/D ๋“ฑ)์ด ๋œน๋‹ˆ๋‹ค.
  • aa-autodep: Analyzes the shared libraries and dependencies used by the target binary and automatically creates a very basic skeleton profile.
bash
  sudo aa-autodep /usr/bin/custom-app

Mode switching and utility binary (outside the scope of the exam)

  • aa-enforce: Immediately puts the target profile or binary into Enforce mode.
bash
  # ํ”„๋กœํ•„ ํŒŒ์ผ ๊ฒฝ๋กœ๋ฅผ ์ง€์ •ํ•˜๊ฑฐ๋‚˜, ๋“ฑ๋ก๋œ ๋ฐ”์ด๋„ˆ๋ฆฌ ๊ฒฝ๋กœ๋ฅผ ์ง€์ •ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
  sudo aa-enforce /etc/apparmor.d/usr.sbin.nginx
  sudo aa-enforce /usr/sbin/nginx
  • aa-complain: Immediately switches the target profile or binary to Complain mode.
bash
  sudo aa-complain /usr/sbin/nginx
  • aa-disable: Unloads a specific profile from the kernel and permanently disables it.
bash
  sudo aa-disable /usr/sbin/nginx
  • aa-audit: Force audit log recording for a specific profile.
bash
  # 1. ํŠน์ • ๋ฐ”์ด๋„ˆ๋ฆฌ์— ์ ์šฉ๋œ ํ”„๋กœํ•„์— audit ๋ชจ๋“œ ๊ฐ•์ œ ์ ์šฉ
  sudo aa-audit /usr/sbin/nginx

  # 2. ํ”„๋กœํ•„ ํŒŒ์ผ ๊ฒฝ๋กœ๋ฅผ ์ง์ ‘ ์ง€์ •ํ•˜์—ฌ ์ ์šฉ
  sudo aa-audit /etc/apparmor.d/usr.sbin.nginx

  # 3. (์›์ƒ ๋ณต๊ตฌ) ๊ฐ์‚ฌ ๋ชจ๋“œ๋ฅผ ํ•ด์ œํ•˜๊ณ  ์ผ๋ฐ˜ ๋ชจ๋“œ๋กœ ๋ณต๊ท€
  sudo aa-audit --remove /usr/sbin/nginx
  • aa-unconfined: Identifies a list of binaries that are not protected (restricted) by the AppArmor profile among processes currently running and opening a network socket.
bash
  # 1. ํ˜„์žฌ ๋„คํŠธ์›Œํฌ ์†Œ์ผ“์„ ์—ด๊ณ  ์‹คํ–‰ ์ค‘์ธ ํ”„๋กœ์„ธ์Šค ์ค‘ ๋ณดํ˜ธ๋ฐ›์ง€ ์•Š๋Š” ๋ชฉ๋ก ์ถœ๋ ฅ
  sudo aa-unconfined

  # ์ถœ๋ ฅ ์˜ˆ์‹œ:
  # 1234 /usr/sbin/sshd not confined
  # 5678 /usr/bin/python3 (์ •์ƒ ๋ณดํ˜ธ ์ค‘์ธ ๊ฑด ์•„์˜ˆ ์•ˆ ๋œจ๊ฑฐ๋‚˜ ๋‹ค๋ฅด๊ฒŒ ํ‘œ์‹œ๋จ)

  # 2. ๋„คํŠธ์›Œํฌ ์‚ฌ์šฉ ์—ฌ๋ถ€์™€ ์ƒ๊ด€์—†์ด, ์‹œ์Šคํ…œ์—์„œ ์‹คํ–‰ ์ค‘์ธ ๋ชจ๋“  ํ”„๋กœ์„ธ์Šค๋ฅผ ์ƒ…์ƒ…์ด ๊ฒ€์‚ฌ
  sudo aa-unconfined --paranoid
  • aa-notify: A utility that sends a notification to the desktop or a designated channel when an AppArmor blocking log (DENIED) occurs.
bash
  aa-notify -p -s 5 &
  # -p: ๋ฐ์Šคํฌํ†ฑ ์•Œ๋ฆผ(Notification) ์ฐฝ์œผ๋กœ ํ‘œ์‹œ
  # -s 5: ์ตœ๊ทผ 5์ดˆ ์ด๋‚ด์˜ ๋ฐ€๋ฆฐ ๋กœ๊ทธ๋Š” ์š”์•ฝํ•ด์„œ ๋ณด์—ฌ์คŒ

Tips for taking and using the Certified Kubernetes Security Specialist (CKS)

AppArmor is one of the frequently asked, high-scoring security topics on the CKS exam. Here are some practical tips for solving problems quickly and without panicking at the test site.

CKS Test Center Practice Code of Conduct

  1. Check all worker nodes: The AppArmor profile must be loaded into the kernel of the worker node where the container will run directly, not the Kubernetes master. Connect ssh to the node specified in the problem and perform the operation.
  2. Profile validity check: When connecting to a node, type aa-status to check whether the profile name requested in the problem is already loaded.
  3. Memorize the new profile load command: If the profile file provided in the problem is specified, it must be loaded into the kernel using a parser. Bash
bash
   # ํ”„๋กœํ•„ ์ถ”๊ฐ€/์ƒˆ๋กœ๊ณ ์นจ (-r ์˜ต์…˜ ์‚ฌ์šฉ)
   sudo apparmor_parser -r /etc/apparmor.d/์ œ๊ณต๋œ_ํ”„๋กœํ•„_ํŒŒ์ผ๋ช…
  1. Debugging when container startup fails: If a Pod that has completed AppArmor configuration goes into CreateContainerConfigError or CrashLoopBackOff status, immediately suspect the following two things.
    โ€“ Does the profile name written in localhostProfile match the name that appears in aa-status of the worker node, including lowercase and lowercase letters?
    โ€“ Are there any grammatical errors in the internal structure of the profile file? (Check the node’s /var/log/syslog or journalctl -u kubelet)

Differences from seccomp (CKS frequent concept)

seccomp, which is required along with AppArmor in the CKS exam, also limits the process, but there is a difference in the โ€˜layerโ€™ that controls it.

Security tools Main blocking targets and criteria Features
AppArmor Binary paths and resources (concepts)
Example: โ€œThis process is prohibited from reading /vmlinuz and prohibited from networkingโ€
Intuitively controls abstracted resource access such as file paths and networks
seccomp System call number
Example: โ€œThis container is prohibited from using the chmod and chown system calls.โ€
The kernel function itself is tightly blocked at the low level (syscall).

Problem solving tips

  1. Find and record whether a specific profile is activated on a specific node
bash
   ### ์›๊ฒฉ์œผ๋กœ ๊ธฐ๋กํ•˜๊ธฐ
   cat <<EOF > /root/profiles.txt
   $(ssh node01 bash -c 'aa-status' | grep -E 'docker-default|snap.lxd.lxc|ftpd|tcpdump' | awk '{print $1}')
   EOF

   ### or ์ง์ ‘ ์กฐํšŒ ํ›„ ๊ธฐ๋ก
   ssh node01
   aa-status | grep -E 'docker-default|snap.lxd.lxc|ftpd|tcpdump'
  1. Rename the prepared profile and activate it on all nodes
bash
   ### Change in File
   vi $profile
   ```profile
   profile <profile_name> flags=(attach_disconnected,mediate_deleted) {
   `

   ### ๋ชจ๋“  ๋…ธ๋“œ์— ํŒŒ์ผ ์ „์†ก
   scp $profile node01:

   ### ๋ชจ๋“  ๋…ธ๋“œ์— ์ ์šฉ
   apparmor_parser $profile
   ssh node01
   apparmor_parser $profile
  1. An error occurred due to an incorrect profile name. Modify deployment to succeed
bash
   # ํ”„๋กœํŒŒ์ผ๋ช… ํ™•์ธ
   ssh node01 bash -c 'aa-status'

   # ์ˆ˜์ • ์ ์šฉ
   kubectl edit deployment -n $ns $deploy_name
   ```yaml
   # pod.spec or pod.spec.containers
   securityContext:
     appArmorProfile:
       type: Localhost
       localhostProfile: <profile_name>
   `
  1. Specific container (Multi-Container) unit targeting type 1. Check the specified container name and move pod.spec.securityContext to pod.spec.containers.securityContext

Comments

Leave a Reply

Your email address will not be published. Required fields are marked *