AppArmor confines individual applications to a defined set of permitted file, network, and capability access — so that even if an application is compromised, the damage it can do is limited to its defined profile.
AppArmor vs Traditional Permissions
Standard Linux permissions control what a user can access. AppArmor adds a layer controlling what a specific program can access, regardless of which user runs it — useful for containing a compromised web application, for example, even if it's running as a legitimate user.
Prerequisites
- Ubuntu 22.04/24.04 (AppArmor is enabled by default) or Debian with AppArmor installed
- Root or sudo access
Step 1 — Verify AppArmor Is Active
sudo aa-status
Ubuntu ships with AppArmor enabled by default. For Debian:
sudo apt install apparmor apparmor-utils -y
Step 2 — List Loaded Profiles
sudo aa-status
Shows profiles in enforce mode (actively restricting) versus complain mode (logging violations without blocking).
Step 3 — Check Available Pre-Built Profiles
ls /etc/apparmor.d/
Many common packages (Nginx, MySQL) ship with pre-built AppArmor profiles automatically applied on install.
Step 4 — Put a Profile into Complain Mode (Testing)
sudo aa-complain /etc/apparmor.d/usr.sbin.nginx
Complain mode logs what the application would be blocked from doing, without actually blocking it — useful for testing a new profile before enforcing it.
Step 5 — Review Complain Mode Logs
sudo journalctl -k | grep apparmor | grep "type=1400"
Step 6 — Switch to Enforce Mode
sudo aa-enforce /etc/apparmor.d/usr.sbin.nginx
Creating a Custom Profile for Your Own Application
sudo aa-genprof /path/to/your/application
This launches an interactive tool: run your application through its typical usage patterns while aa-genprof observes, then it helps you build a profile based on observed behavior.
Example Basic Custom Profile
sudo nano /etc/apparmor.d/myapp
#include <tunables/global>
/opt/myapp/myapp {
#include <abstractions/base>
/opt/myapp/myapp mr,
/opt/myapp/data/** rw,
/etc/myapp/config.yml r,
deny /home/** rwx,
deny /root/** rwx,
}
sudo apparmor_parser -r /etc/apparmor.d/myapp
Disabling a Specific Profile (If Causing Problems)
sudo aa-disable /etc/apparmor.d/usr.sbin.nginx
Common Errors
Application fails mysteriously after enabling enforce mode — check dmesg or the audit log for AppArmor DENIED messages, then add the necessary permission to the profile rather than disabling AppArmor entirely.
sudo dmesg | grep -i apparmor | grep DENIED
Best Practices
- Always test new profiles in complain mode before switching to enforce
- Use pre-built profiles from your distribution where available rather than writing from scratch
- Apply the principle of least privilege — grant only the specific access an application genuinely needs
Related Articles
- How to Implement the Principle of Least Privilege on a Linux VPS
- Docker Security Best Practices for Production Servers
- VPS Security Checklist for Beginners
