openskills.info
AppArmor logo

AppArmor

itLinux

AppArmor

AppArmor confines a Linux program to a declared set of allowed operations. It is a Linux Security Module, or LSM. The kernel enforces its policy after the usual discretionary access checks.

The practical goal is damage containment. A network service may need to read its configuration, bind a socket, and write its own state. It does not need every permission held by its Unix user. An AppArmor profile narrows that service to the resources and operations its workload requires.

The mental model

Follow one request through four parts:

  1. Process — a running program requests an operation from the kernel.
  2. Profile — AppArmor identifies the profile attached to that process.
  3. Rule — the profile allows matching file, capability, network, signal, ptrace, mount, D-Bus, or other mediated operations.
  4. Decision — enforce mode blocks an operation without permission. Complain mode permits it and records the violation for policy development.

AppArmor policy is allow-list oriented. When an enforcing profile has no rule that permits a mediated operation, the kernel denies it. An explicit deny rule also blocks access, but it can suppress routine audit noise.

This policy adds a boundary. It does not replace Unix ownership, mode bits, access control lists, capabilities, service hardening, patching, or application security. Every applicable access-control layer must allow an operation before it succeeds.

Profiles attach policy to programs

An attached profile names an executable path. The kernel applies that profile when a process executes the matching program. An unattached named profile does not apply automatically; a transition or a tool such as aa-exec must select it.

Profiles are text files, usually under /etc/apparmor.d/. A profile has a header and a rule block:

include <tunables/global>

/usr/local/bin/report-worker {
  include <abstractions/base>

  /usr/local/bin/report-worker mr,
  /etc/report-worker/** r,
  /var/lib/report-worker/** rw,
  network inet stream,
}

The attachment is /usr/local/bin/report-worker. The rules permit executable mapping, configuration reads, state reads and writes, and IPv4 stream networking. The example does not claim that this is a complete production profile. Real policy must reflect the program, libraries, runtime, distribution, and enabled kernel features.

Abstractions are reusable policy fragments. Tunables are variables that adapt policy to local paths. Both reduce duplication, but an abstraction still grants access. Read its contents and choose the narrowest suitable one.

File rules are path based

AppArmor file rules match path patterns. A single star matches within one directory level. A double star crosses directory levels. A trailing slash distinguishes a directory rule from a file rule.

Common permissions include:

  • r — read.
  • w — write; it also implies append.
  • m — map a file as executable memory.
  • k — lock a file when combined with read or write access.
  • l — create a hard link.
  • ix — execute and inherit the current profile.
  • px — execute under another profile.
  • cx — execute under a child profile.
  • ux — execute unconfined; avoid this escape unless you have a specific, reviewed reason.

Execution rules deserve close review because they decide the next process's confinement. A broad file read rule does not automatically permit execution. A transition can preserve confinement, switch profiles, enter a child profile, or drop confinement.

Modes support a policy lifecycle

Enforce mode is the default when no mode flag is present. It blocks violations and logs them. Complain mode allows violations and logs them. Use complain mode to observe a defined test plan, not to claim that a profile protects the workload.

A useful authoring loop is:

define workload → create profile → exercise all intended behavior
       ↑                                      ↓
review rules ← inspect audit events ← refine policy
       ↓
validate syntax → reload → enforce → monitor

aa-genprof guides initial profile creation by placing the target in complain mode and scanning audit events. aa-logprof reviews AppArmor messages and proposes profile updates. These tools suggest policy from observed behavior; they do not know which behavior is legitimate. You make that security decision.

Operational boundaries

AppArmor only mediates operations supported by the running kernel and policy ABI. Distribution packaging, enabled features, and tool versions matter. Network rules can be coarse. Some interfaces, such as D-Bus mediation, also depend on cooperating user-space components.

Path-based policy is readable and maps well to application layouts. It also means path changes, alternate executable locations, generated files, mount layouts, and container namespaces can change what a rule matches. Treat profiles as maintained code. Test application upgrades and inspect denials before broadening access.

AppArmor is a strong choice when you can describe a program's expected behavior and want a kernel-enforced boundary around it. It is less useful when nobody owns the profile lifecycle or when the workload changes faster than policy can be reviewed safely.

Where to go next

Start with the upstream profile basics and quick reference. Read a packaged profile and every abstraction it includes. Then build a profile for a small program in a disposable virtual machine. Exercise a written test plan, inspect audit records, refine the rules, reload the profile, and switch to enforce mode. After that, study execution transitions, signal and ptrace rules, D-Bus policy, namespaces, stacking, and policy ABI compatibility.