Course contentsShow
← Linux
Lesson 1557 of 1,81913. Containerization Primitives and NamespacesFree lesson

AppArmor Profiles for Containers

Restrict file and network capabilities of processes using mandatory access control profiles.

In this lesson, you will learn how to enforce fine-grained security policies on containerized processes using AppArmor to restrict file access and network capabilities.

Understanding Mandatory Access Control

While Linux namespaces and cgroups provide isolation, they do not inherently restrict what a process can do inside its allowed environment. AppArmor acts as a Mandatory Access Control (MAC) system that binds a security profile to specific programs. When a container engine (like Docker or containerd) launches a container, it can apply an AppArmor profile to the container process, effectively overriding default permissions.

Restricting Capabilities via Profiles

An AppArmor profile is a plain-text file that defines exactly which files a process can read, write, or execute, and which network operations it can perform. By applying a restrictive profile, even a process running as root inside a container can be prevented from accessing sensitive host files or performing raw socket operations.

Consider this snippet from a profile that limits a containerized web server:

profile container-web-server flags=(attach_disconnected, complain) {
  # Deny all network access except TCP
  network tcp,
  
  # Allow read access to specific library directories
  /usr/lib/** r,
  
  # Explicitly deny access to sensitive host files
  deny /etc/shadow w,
  deny /proc/sys/kernel/** w,
}

When this profile is loaded into the kernel and applied to your container, the LSM (Linux Security Module) framework hooks into system calls. If the process attempts to write to /etc/shadow, the kernel checks the profile, sees the deny rule, and returns a permission error, regardless of the process's internal UID.

Operational Workflow

  1. Load: Profiles are loaded into the kernel via apparmor_parser.
  2. Apply: When starting a container, the runtime uses the --security-opt apparmor=PROFILE_NAME flag.
  3. Audit: You can track violations using dmesg or /var/log/audit/audit.log, which capture denied system calls, allowing you to iterate on your profile without breaking production services.

By moving beyond simple namespace isolation, you ensure that even if an attacker achieves arbitrary code execution within a container, their blast radius is confined by the strict boundaries of the AppArmor profile.

Key Takeaway: AppArmor profiles provide a declarative, LSM-backed security layer that forces containers to adhere to a strict whitelist of file system and network operations, preventing privilege escalation beyond the intended container scope.