Lab 08: AppArmor — Profiles & Confinement

Time: 40 minutes | Level: Advanced | Docker: docker run -it --rm --privileged ubuntu:22.04 bash

AppArmor (Application Armor) is a Linux Mandatory Access Control (MAC) system that confines programs to a limited set of resources using per-application profiles. Unlike SELinux which labels everything, AppArmor works path-based — profiles specify exactly what files, capabilities, and network access a program is allowed. It's the default MAC system on Ubuntu.

⚠️ Docker Note: AppArmor requires kernel module support. In Docker, apparmor_status will show the module is loaded but the filesystem is not mounted. You can inspect, create, and parse profiles — but enforcement requires a real Ubuntu host. All config syntax shown is real and verified.


Step 1: Install AppArmor and Check Status

apt-get update -qq && apt-get install -y apparmor apparmor-utils apparmor-profiles 2>/dev/null

Check AppArmor status:

aa-status 2>&1
# or
apparmor_status 2>&1

📸 Verified Output:

$ docker run --rm ubuntu:22.04 bash -c "apt-get update -qq 2>/dev/null && apt-get install -y -qq apparmor apparmor-utils 2>/dev/null && aa-status 2>&1"
apparmor filesystem is not mounted.
apparmor module is loaded.

On a real Ubuntu host with AppArmor active:

$ aa-status
apparmor module is loaded.
64 profiles are loaded.
56 profiles are in enforce mode.
   /usr/bin/evince
   /usr/bin/firefox
   ...
8 profiles are in complain mode.
0 processes have profiles defined.

💡 aa-status (or apparmor_status) shows all loaded profiles and their modes. The count of enforce vs complain profiles tells you how actively AppArmor is protecting the system.


Step 2: Profile Directory Structure

📸 Verified Output:

Key directories:

Path
Purpose

/etc/apparmor.d/

Main profile directory — one file per confined program

/etc/apparmor.d/abstractions/

Reusable rule snippets (e.g., base, nameservice, ssl_certs)

/etc/apparmor.d/tunables/

Variables like @{HOME} and @{PROC}

/etc/apparmor.d/local/

Site-local overrides for existing profiles

/etc/apparmor.d/disable/

Symlinks here disable profiles

/etc/apparmor.d/force-complain/

Force profiles to complain mode

📸 Verified Output:


Step 3: Profile Modes — enforce, complain, disable

Each AppArmor profile runs in one of three modes:

📸 Verified Output:

💡 Always use complain mode first when deploying a new profile. Monitor /var/log/syslog or dmesg | grep apparmor for logged violations, then tighten the profile before switching to enforce.


Step 4: AppArmor Profile Syntax

Create a custom profile for a simple script:

📸 Verified Output:

💡 AppArmor permission flags: r=read, w=write, x=execute, m=mmap, i=inherit (exec keeps current profile), p=exec with specific profile, u=exec with no profile, ix=inherit+execute.


Step 5: Profile Permissions — Paths, Capabilities, Network

Understanding the three main permission domains:


Step 6: Loading Profiles and aa-logprof

📸 Verified Output:

💡 aa-logprof reads AppArmor events from the system log and interactively asks you what to allow. It's the recommended way to build real-world profiles — run the app in complain mode, exercise all features, then run aa-logprof to formalize the profile.


Step 7: Deny Rules and AppArmor Defaults

Deny rules explicitly block access even if a broader rule would allow it:

📸 Verified Output:

💡 deny rules take priority over allow rules. This lets you write broad allow /var/log/** r rules and then carve out sensitive exceptions with deny /var/log/auth.log r.


Step 8: Capstone — Confine a Web Application with a Custom Profile

Scenario: You've deployed a Python web API at /usr/local/bin/api-server. Create a restrictive AppArmor profile that allows only what it needs: read its config, write logs, serve on port 8080, and block all other access.

📸 Verified Output:


Summary

Task
Command
Notes

Check status

aa-status

Lists all loaded profiles and modes

Set enforce mode

aa-enforce /etc/apparmor.d/<profile>

Blocks violations

Set complain mode

aa-complain /etc/apparmor.d/<profile>

Logs only, no blocking

Disable profile

aa-disable /etc/apparmor.d/<profile>

Creates symlink in disable/

Load/reload profile

apparmor_parser -r <profile>

Parse and load into kernel

Build from logs

aa-logprof

Interactive profile builder from log events

Profile directory

/etc/apparmor.d/

One profile file per program

Abstractions

/etc/apparmor.d/abstractions/

Reusable rule includes

Logs

/var/log/syslog + grep apparmor

AppArmor violation events

Deny syntax

deny /path rw,

Explicit block, overrides allow rules

Capability deny

deny capability sys_admin,

Block Linux capabilities

Network rules

network inet tcp,

Allow/deny by protocol family

Last updated