Table of Contents
- What is AppArmor?
- How AppArmor Works: Core Concepts
- AppArmor vs. Other MAC Systems
- Getting Started with AppArmor
- Anatomy of an AppArmor Profile
- Common AppArmor Use Cases
- Troubleshooting AppArmor Issues
- Best Practices for AppArmor
- Conclusion
- References
What is AppArmor?
AppArmor is a Linux Security Module (LSM) that implements mandatory access control (MAC). Unlike discretionary access control (DAC)—the default Linux permission model, which relies on user/group ownership—MAC enforces system-wide policies that restrict applications to predefined actions, regardless of user privileges.
Developed initially by Immunix in the early 2000s, AppArmor was later adopted by SUSE Linux and Ubuntu, and is now integrated into most major Linux distributions. Its primary goal is to enforce the principle of least privilege: every program should only access the resources (files, network, capabilities) it explicitly needs to function.
How AppArmor Works: Core Concepts
AppArmor operates through three foundational components: profiles, modes, and a policy language.
1. Profiles: The Heart of AppArmor
A profile is a text file that defines the allowed (and denied) actions for a specific application. Each profile is tied to an executable path (e.g., /usr/bin/firefox or /usr/sbin/apache2), ensuring the rules apply only when that executable runs.
Profiles are stored in /etc/apparmor.d/ (e.g., /etc/apparmor.d/usr.bin.firefox for Firefox). Many Linux distributions ship with prebuilt profiles for common applications like Apache, Nginx, and Firefox.
2. Modes: Enforce, Complain, or Disable
Profiles can operate in three modes, balancing security and usability:
- Enforce Mode: Actively blocks disallowed actions and logs violations. This is the default for critical applications.
- Complain Mode (a.k.a. “Learning Mode”): Allows disallowed actions but logs them. Use this to debug or generate initial profiles by observing an application’s behavior.
- Disabled Mode: The profile is inactive; no restrictions are enforced.
3. Policy Language: Defining Rules
AppArmor’s policy language is human-readable and path-based, making it easier to learn than alternatives like SELinux. Rules define allowed access to:
- Files: Read (
r), write (w), execute (x), or memory-map (m) permissions. - Network: TCP/UDP connections, ports, and protocols.
- Capabilities: Linux capabilities (e.g.,
CAP_NET_BIND_SERVICEfor binding to privileged ports). - Signals: Allowed signals between processes.
AppArmor vs. Other MAC Systems
Linux offers several MAC frameworks; the most popular are AppArmor and SELinux. Here’s how they compare:
| Feature | AppArmor | SELinux |
|---|---|---|
| Policy Type | Path-based (e.g., /usr/bin/nginx). | Label-based (e.g., httpd_t). |
| Learning Curve | Low; intuitive path-based rules. | High; requires understanding labels. |
| Granularity | Moderate; good for most use cases. | High; highly customizable. |
| Default Profiles | Prebuilt for common apps (Apache, Firefox). | Fewer prebuilt; more manual setup. |
| Distro Adoption | Ubuntu, SUSE, Debian (optional). | Red Hat, CentOS, Fedora. |
Smack (Simplified Mandatory Access Control Kernel) is another lightweight alternative, but it lacks AppArmor’s flexibility and prebuilt profiles.
AppArmor’s key advantage is its user-friendliness: it’s easier to deploy, debug, and maintain, making it ideal for developers, sysadmins, and organizations without dedicated security teams.
Getting Started with AppArmor
Prerequisites
AppArmor is preinstalled on most modern Linux distributions (e.g., Ubuntu 16.04+, SUSE Linux Enterprise). To verify:
# Check if AppArmor is enabled
aa-status
If missing, install it:
-
Ubuntu/Debian:
sudo apt install apparmor apparmor-utils apparmor-profiles -
SUSE/openSUSE:
sudo zypper install apparmor apparmor-utils -
Fedora/RHEL (less common, but possible):
sudo dnf install apparmor
Key Commands
| Command | Purpose |
|---|---|
aa-status | Check AppArmor status and loaded profiles. |
aa-enforce <profile> | Switch a profile to enforce mode. |
aa-complain <profile> | Switch to complain mode. |
aa-disable <profile> | Disable a profile. |
aa-logprof | Generate rules from logs (complain mode). |
aa-genprof <executable> | Create a new profile interactively. |
Example: Managing a Profile
To secure the Nginx web server:
-
Check if a prebuilt profile exists:
ls /etc/apparmor.d/usr.sbin.nginx -
Enforce the profile:
sudo aa-enforce usr.sbin.nginx -
Verify:
aa-status | grep nginx # Output: /usr/sbin/nginx (enforce)
Anatomy of an AppArmor Profile
Let’s dissect a simple profile to understand its structure. Below is a minimal profile for a custom script at /usr/local/bin/myapp:
# /etc/apparmor.d/usr.local.bin.myapp
# Include common rules (e.g., base system libraries)
#include <tunables/global>
# Profile header: Path to the executable
/usr/local/bin/myapp {
# Flags: Run in complain mode (optional)
#flags=(complain)
# File access rules
/usr/local/bin/myapp rPx, # Allow executing the app itself
/etc/myapp.conf r, # Read config file
/var/log/myapp.log rw, # Read/write log file
/usr/lib/** rm, # Read/memory-map system libraries
# Network rules: Allow TCP on port 8080
network tcp port 8080,
# Capabilities: Allow binding to port 8080 (non-privileged)
capability net_bind_service,
# Deny access to sensitive files
deny /etc/shadow rw,
}
Key Profile Components
- Includes:
#include <tunables/global>reuses common rules (e.g., for/bin,/lib). - Profile Header: The path to the executable (e.g.,
/usr/local/bin/myapp). - Flags: Optional modifiers like
complainorattach_disconnected. - Rules:
rPx:r(read),P(execute as a new profile),x(execute).network tcp port 8080: Allow TCP connections on port 8080.capability net_bind_service: Grant theCAP_NET_BIND_SERVICEcapability.
Common AppArmor Use Cases
1. Securing Web Servers (Apache/Nginx)
Prebuilt profiles for Apache (usr.sbin.apache2) and Nginx (usr.sbin.nginx) restrict access to web roots, logs, and system files, preventing attackers from escaping the web server’s context.
2. Container Security
Tools like Docker and LXD use AppArmor to isolate containers. For example, Docker applies the docker-default profile to containers, limiting access to the host filesystem and network.
3. Desktop Applications
Profiles for Firefox (usr.bin.firefox) and Thunderbird restrict browser access to sensitive directories (e.g., /home/user/.ssh), mitigating malware spread.
4. IoT Devices
AppArmor’s lightweight design makes it ideal for IoT systems, where resources are limited. It secures embedded apps (e.g., sensors, gateways) without performance overhead.
Troubleshooting AppArmor Issues
Logs: Where to Look
AppArmor logs denials to:
/var/log/audit/audit.log(viaauditd)./var/log/syslogor/var/log/messages(viarsyslog).
Example denial log:
audit[1234]: AVC apparmor="DENIED" operation="open" profile="/usr/local/bin/myapp" name="/etc/shadow" pid=1234 comm="myapp" requested_mask="rw" denied_mask="rw"
Debugging Workflow
-
Switch to Complain Mode: Temporarily allow all actions but log denials:
sudo aa-complain usr.local.bin.myapp -
Reproduce the Issue: Run the application and trigger the problematic behavior.
-
Generate Rules: Use
aa-logprofto parse logs and add missing rules interactively:sudo aa-logprof -
Switch Back to Enforce Mode:
sudo aa-enforce usr.local.bin.myapp
Common Issues
- App Fails to Start: Check logs for missing file/network access; use
aa-logprofto add rules. - Profile Too Restrictive: Relax rules for non-critical paths (e.g., allow
/tmp/** rwfor temporary files). - Profile Not Loading: Ensure the profile filename matches the executable path (e.g.,
usr.bin.firefoxfor/usr/bin/firefox).
Best Practices for AppArmor
- Start with Prebuilt Profiles: Use distro-provided profiles for common apps (they’re battle-tested).
- Use Complain Mode First: Generate profiles by observing an app’s behavior in complain mode.
- Keep Profiles Minimal: Only allow what’s necessary (least privilege principle).
- Avoid Editing Prebuilt Profiles Directly: Use local overrides in
/etc/apparmor.d/local/(e.g.,usr.sbin.nginx.local). - Test Changes: Validate profiles in staging before deploying to production.
- Monitor Logs: Regularly check for denials to identify misconfigurations or emerging threats.
Conclusion
AppArmor is a cornerstone of Linux security, offering a balance of power and simplicity. By confining applications to predefined profiles, it limits the impact of breaches and hardens systems against attacks. Whether you’re securing a server, container, or IoT device, AppArmor’s path-based policies and user-friendly tools make it accessible to both beginners and experts.
To get started, enable prebuilt profiles, experiment with complain mode, and gradually refine your policies. With AppArmor, you’ll add a robust layer of defense to your Linux infrastructure.