| README.md | Add README.md | |
AppArmor Configuration Guide for Arch Linux
This guide covers setup and configuration of AppArmor, a Mandatory Access Control (MAC) framework that provides application sandboxing and enhanced security for Linux systems.
What AppArmor provides:
- Application confinement beyond traditional Unix permissions
- Path-based access control (simpler than SELinux label-based approach)
- Protection against zero-day exploits through policy enforcement
- Detailed logging of policy violations
- Per-application security profiles
Prerequisites:
- Arch Linux with systemd
- Officially supported kernel (linux, linux-lts, linux-zen, linux-hardened)
- Root access or sudo privileges
Note: AppArmor supplements rather than replaces Discretionary Access Control (DAC). It cannot grant processes more privileges than they originally had.
Table of Contents
- Understanding AppArmor
- Installation
- Kernel Configuration
- Enable and Verify AppArmor
- Profile Management
- Working with Profiles
- Troubleshooting Applications
- Creating Profiles
- Installing Additional Profiles
- Advanced Configuration
- Tips and Tricks
- Common Issues
Appendices:
- Appendix A: Profile Syntax Reference
- Appendix B: Command Reference
- Appendix C: Security Considerations
1. Understanding AppArmor
1.1 How AppArmor Works
AppArmor is implemented as a Linux Security Module (LSM) and works by:
- Loading security profiles for applications
- Enforcing restrictions when applications attempt restricted operations
- Logging policy violations to system logs
- Operating in two modes: enforce (block violations) or complain (log only)
1.3 Profile Modes
AppArmor profiles operate in two modes:
| Mode | Behavior | Use Case |
|---|---|---|
| Enforce | Violations are blocked and logged | Production systems |
| Complain | Violations are logged only | Profile development and testing |
Note: Deny rules are enforced even in complain mode.
1.3 Default Deny Model
AppArmor follows a default-deny approach:
- Everything not explicitly allowed is forbidden
- Applications without profiles run unconfined
- Profiles define exact permissions granted to applications
- Access beyond profile scope triggers logging and (in enforce mode) denial
2. Installation
2.1 Install AppArmor Package
sudo pacman -S apparmor
The apparmor package provides:
- Kernel userspace tools (
aa-status,aa-enforce,aa-complain, etc.) - Default profiles in
/etc/apparmor.d/ - Profile parsing and loading tools
- Audit log analysis utilities
2.2 Enable AppArmor Service
sudo systemctl enable apparmor.service
This ensures AppArmor profiles load at boot.
Note: AppArmor will not be active until the kernel is configured to enable it
3. Kernel Configuration
3.1 Set Kernel Parameter
AppArmor must be enabled in the kernel's LSM initialization order. Add the following kernel parameter:
lsm=landlock,lockdown,yama,integrity,apparmor,bpf
3.2 LSM Parameter Explanation
The lsm= kernel parameter sets the initialization order of Linux Security Modules:
- Order matters: AppArmor must be the first "major" LSM (before any other MAC system like SELinux or TOMOYO)
- capability is omitted: It is automatically included and should not be manually specified
- Current value: Check with
cat /sys/kernel/security/lsm - Configured value: Check kernel config with
zgrep CONFIG_LSM= /proc/config.gz
Valid LSM modules:
| Module | Type | Purpose |
|---|---|---|
landlock |
Sandboxing | User-space application sandboxing |
lockdown |
Integrity | Kernel lockdown for secure boot |
yama |
Restrictions | Ptrace scope restrictions |
integrity |
Measurement | IMA/EVM integrity subsystem |
apparmor |
MAC | Mandatory access control (this guide) |
bpf |
Restrictions | BPF program restrictions |
3.3 Reboot and Verify
Reboot to apply kernel parameter:
sudo reboot
After reboot, verify AppArmor is in the LSM list:
cat /sys/kernel/security/lsm
Expected output:
landlock,lockdown,yama,integrity,apparmor,bpf
4. Enable and Verify AppArmor
4.1 Check if AppArmor is Enabled
sudo aa-enabled
Expected output:
Yes
If this returns "No" or an error, verify:
- Kernel parameter is set correctly (
cat /proc/cmdline | grep lsm) - System was rebooted after adding kernel parameter
apparmor.serviceis enabled and started
4.2 Check AppArmor Status
sudo aa-status
Sample output:
apparmor module is loaded.
44 profiles are loaded.
44 profiles are in enforce mode.
/usr/bin/man
...
0 profiles are in complain mode.
5 processes have profiles defined.
5 processes are in enforce mode.
/usr/bin/man (1234)
...
0 processes are in complain mode.
0 processes are unconfined but have a profile defined.
Status explanation:
| Field | Meaning |
|---|---|
| Profiles loaded | Number of profiles currently loaded into kernel |
| Profiles in enforce mode | Profiles actively blocking violations |
| Profiles in complain mode | Profiles only logging violations |
| Processes in enforce mode | Running processes confined by enforce-mode profiles |
| Processes in complain mode | Running processes with complain-mode profiles |
| Unconfined with profile | Processes that have a profile defined but are not currently confined |
5. Profile Management
5.1 Profile Locations
| Location | Purpose |
|---|---|
/etc/apparmor.d/ |
Active profiles (loaded at boot) |
/usr/share/apparmor/extra-profiles/ |
Additional profiles (not production-ready, require testing) |
/etc/apparmor.d/abstractions/ |
Reusable profile fragments |
/etc/apparmor.d/tunables/ |
Variables for paths and settings |
/etc/apparmor.d/local/ |
Local overrides for profiles |
5.2 Switching Profile Modes
Set profile to enforce mode:
sudo aa-enforce /etc/apparmor.d/usr.bin.application
Set profile to complain mode:
sudo aa-complain /etc/apparmor.d/usr.bin.application
Disable a profile:
sudo aa-disable /etc/apparmor.d/usr.bin.application
Note: After disabling a profile, it will not load at next boot. To re-enable, use aa-enforce or aa-complain.
5.3 Reloading Profiles
Reload a single profile:
sudo apparmor_parser -r /etc/apparmor.d/usr.bin.application
Reload all profiles:
sudo systemctl reload apparmor.service
Use reload after editing profiles to apply changes without rebooting.
5.4 Listing Loaded Profiles
sudo aa-status
For a quick list of enforce-mode profiles only:
sudo aa-status | grep "profiles are in enforce mode" -A 100
6. Working with Profiles
6.1 Understanding Profile Structure
Profiles are human-readable text files in /etc/apparmor.d/ that define application permissions.
Basic profile example:
/etc/apparmor.d/usr.bin.example
#include <tunables/global>
profile example /usr/bin/example {
#include <abstractions/base>
# Binary and libraries
/usr/bin/example mr,
/usr/lib/example/** rm,
# Configuration and data
@{HOME}/.config/example/ r,
@{HOME}/.config/example/** rw,
# System files
/etc/example.conf r,
}
Profile components:
| Component | Purpose | Example |
|---|---|---|
#include <tunables/global> |
Include global variables | Defines @{HOME}, @{PROC}, etc. |
profile name /path/to/binary |
Profile declaration | Names the profile and specifies binary |
#include <abstractions/X> |
Include common permissions | <abstractions/base> for basic system access |
| Path rules | Define file access | /path/to/file r, (read permission) |
6.2 Common Access Modes
| Mode | Meaning | Description |
|---|---|---|
r |
Read | Read file contents |
w |
Write | Write, create, delete, truncate files |
a |
Append | Append to files (subset of write) |
k |
Lock | File locking |
m |
Memory map executable | Map file as executable |
x |
Execute | Execute file (requires qualifier) |
l |
Link | Create hard links |
ix |
Inherit execute | Execute and inherit current profile |
Px |
Profile execute | Execute with dedicated profile transition |
Ux |
Unconfined execute | Execute unconfined (use carefully) |
6.3 Globbing Patterns
AppArmor supports pattern matching:
| Pattern | Matches |
|---|---|
* |
Zero or more characters (excludes /) |
** |
Zero or more characters (includes /) |
? |
Single character |
[abc] |
One character from set |
[a-z] |
One character from range |
{ab,cd} |
Alternation (ab or cd) |
Examples:
/home/*/Documents/* # Matches /home/user/Documents/file.txt
/usr/lib/** # Matches all files under /usr/lib recursively
/etc/apparmor.d/tunables/* # Matches files directly in tunables, not subdirs
6.4 Variables and Abstractions
Tunables define path variables:
@{HOME}=/home/*/ /root/
@{PROC}=/proc/
@{multiarch}=*-linux-gnu*
Abstractions provide reusable permission sets:
| Abstraction | Purpose |
|---|---|
<abstractions/base> |
Basic system files and libraries |
<abstractions/nameservice> |
DNS and name resolution |
<abstractions/dbus-session-strict> |
D-Bus session access |
<abstractions/fonts> |
Font access |
<abstractions/audio> |
Audio device access |
6.5 Local Overrides
Local overrides allow adding rules without modifying the main profile:
sudo vim /etc/apparmor.d/local/usr.bin.application
Add rules:
# Allow access to USB drives
/media/** rw,
/mnt/** rw,
Reload profile:
sudo apparmor_parser -r /etc/apparmor.d/usr.bin.application
Benefit: Local overrides persist across package updates, while main profiles may be overwritten.
7. Troubleshooting Applications
7.1 Viewing AppArmor Logs
View denials from current boot:
sudo journalctl -k -b | grep 'apparmor="DENIED"'
Follow denials in real-time:
sudo journalctl -kf | grep apparmor
Search for specific application:
sudo journalctl -k -b | grep 'apparmor="DENIED"' | grep application_name
7.2 Understanding Log Format
AppArmor logs follow this format:
apparmor="DENIED" operation="open" profile="usr.bin.example" name="/path/to/file" pid=1234 comm="example" requested_mask="r" denied_mask="r" fsuid=1000 ouid=1000
Key fields:
| Field | Meaning |
|---|---|
operation |
Operation attempted (open, exec, capable, etc.) |
profile |
Profile that denied the access |
name |
Path or resource that was denied |
comm |
Command/process name |
requested_mask |
Permissions requested (r, w, x, etc.) |
denied_mask |
Permissions that were denied |
7.3 Systematic Troubleshooting Workflow
When an application doesn't work with AppArmor:
-
Check for denials:
sudo journalctl -k -b | grep 'apparmor="DENIED"' | grep application_name -
Set profile to complain mode:
sudo aa-complain /etc/apparmor.d/profile_name -
Test application:
Run the application normally and verify it works in complain mode.
-
Review logged denials:
sudo journalctl -k -b | grep 'apparmor="ALLOWED"' | grep profile_nameNote: In complain mode, denials are logged as "ALLOWED" with complain flag.
-
Add necessary rules to local override:
sudo vim /etc/apparmor.d/local/profile_nameBased on logs, add rules like:
/path/to/needed/file r, /path/to/writable/dir/** rw, -
Reload profile in enforce mode:
sudo aa-enforce /etc/apparmor.d/profile_name sudo apparmor_parser -r /etc/apparmor.d/profile_name -
Test again:
Verify application works in enforce mode with new rules.
7.4 Common Denial Patterns
File access denials:
apparmor="DENIED" operation="open" name="/home/user/.config/app/config"
Solution: Add file access rule:
@{HOME}/.config/app/** rw,
Capability denials:
apparmor="DENIED" operation="capable" capname="net_admin"
Solution: Add capability:
capability net_admin,
Execute denials:
apparmor="DENIED" operation="exec" name="/usr/bin/helper"
Solution: Add execute rule with appropriate transition:
/usr/bin/helper ix, # Inherit current profile
# OR
/usr/bin/helper Px, # Transition to helper's profile
8. Creating Profiles
8.1 Prerequisites for Profile Creation
Install the Audit framework for proper logging:
sudo pacman -S audit
Enable and start auditd:
sudo systemctl enable --now auditd
Why auditd is needed: Arch Linux uses systemd and does not log kernel messages to file by default. AppArmor's profiling tools rely on audit logs to track application behavior.
8.2 Automated Profile Generation
AppArmor provides tools for semi-automated profile creation:
Generate profile skeleton:
sudo aa-genprof /usr/bin/application
This starts an interactive session:
- Launches the application
- Monitors application behavior
- Prompts for permission decisions
- Generates profile based on observed behavior
Usage:
- Start
aa-genprof /usr/bin/application - In another terminal, use the application normally (exercise all features)
- Return to
aa-genprofterminal and press 'S' to scan logs - Review and approve/deny each suggested rule
- Save the profile when complete
8.3 Refining Profiles with aa-logprof
After initial profile creation or when updating existing profiles:
sudo aa-logprof
This tool:
- Scans audit logs for AppArmor events
- Presents each denial with context
- Offers to add appropriate rules
- Updates profiles automatically
Workflow:
- Run application with profile in complain mode
- Use all application features
- Run
aa-logprof - Review each denial and choose to allow, deny, or abstract
- Save updated profile
8.4 Manual Profile Creation
For more control, profiles can be created manually:
sudo vim /etc/apparmor.d/usr.bin.application
Basic template:
#include <tunables/global>
profile application /usr/bin/application {
#include <abstractions/base>
# Binary
/usr/bin/application mr,
# Libraries
/usr/lib/application/** mr,
# Configuration
@{HOME}/.config/application/ r,
@{HOME}/.config/application/** rw,
# Data
@{HOME}/.local/share/application/** rw,
# Logs
@{HOME}/.cache/application/ rw,
@{HOME}/.cache/application/** rw,
# System files (if needed)
/etc/application.conf r,
# Temporary files
/tmp/** rw,
}
Load the profile:
sudo apparmor_parser -r /etc/apparmor.d/usr.bin.application
Set to enforce mode:
sudo aa-enforce /etc/apparmor.d/usr.bin.application
8.5 Testing Profiles
Always test in complain mode first:
sudo aa-complain /etc/apparmor.d/usr.bin.application
Test workflow:
- Set profile to complain mode
- Run application through typical usage
- Check logs for denials
- Add necessary permissions
- Reload profile
- Repeat until no more denials
- Switch to enforce mode
- Final testing
8.6 Deny Rules
Deny rules explicitly block access and take precedence over allow rules:
deny /home/*/.ssh/** rw,
deny /etc/shadow r,
Use cases:
- Block access to sensitive files even if abstraction allows it
- Silence noisy log entries for expected denials
- Enforce additional restrictions beyond default-deny
Important: Deny rules are enforced even in complain mode. If an application doesn't work in complain mode, check for deny rules in the profile or included abstractions.
9. Installing Additional Profiles
9.1 Extra Profiles from Official Repository
Arch provides additional profiles in /usr/share/apparmor/extra-profiles/:
ls /usr/share/apparmor/extra-profiles/
Note: These profiles are not production-ready and require manual testing and adjustment.
To use an extra profile:
-
Copy to active directory:
sudo cp /usr/share/apparmor/extra-profiles/usr.bin.application /etc/apparmor.d/ -
Set to complain mode:
sudo aa-complain /etc/apparmor.d/usr.bin.application -
Load profile:
sudo apparmor_parser -r /etc/apparmor.d/usr.bin.application -
Test application and refine with
aa-logprof -
Switch to enforce mode when ready
9.2 AppArmor.d Profile Collection
The apparmor.d project provides a comprehensive set of community-maintained profiles for common applications.
Install from AUR:
paru -S apparmor.d
Or for enforce mode by default:
paru -S apparmor.d.enforced
Differences:
| Package | Default Mode | Use Case |
|---|---|---|
apparmor.d |
Complain | Testing, development systems |
apparmor.d.enforced |
Enforce | Production systems (after testing) |
After installation:
sudo systemctl reload apparmor.service
Coverage:
The apparmor.d project includes profiles for:
- Desktop applications (browsers, editors, media players)
- System services (systemd units, networking tools)
- Development tools (compilers, interpreters)
- Package managers
Important: Test applications after installation. The profiles may need adjustment for your specific use case:
sudo aa-status # Check which profiles are loaded
sudo journalctl -k -b | grep 'apparmor="DENIED"' # Check for issues
Troubleshooting apparmor.d profiles:
If an application doesn't work after installing apparmor.d:
-
Switch specific profile to complain mode:
sudo aa-complain /etc/apparmor.d/application_profile -
Check logs and add local overrides as needed
-
Report issues to the apparmor.d project
Note: The apparmor.d project is actively maintained but individual profiles may have varying stability levels.
10. Advanced Configuration
10.1 Profile Caching
AppArmor translates text profiles into binary format at boot, which can increase boot time. Caching pre-compiled profiles improves startup performance.
Check current AppArmor load time:
systemd-analyze blame | grep apparmor
Enable caching:
Edit /etc/apparmor/parser.conf:
sudo vim /etc/apparmor/parser.conf
Uncomment:
## Turn creating/updating of the cache on by default
write-cache
Optional - change cache location:
cache-loc=/var/cache/apparmor/
Default cache location: Since AppArmor 2.13.1, the default is /var/cache/apparmor/ (previously /etc/apparmor.d/cache.d/).
Verify improvement:
sudo reboot
After reboot:
systemd-analyze blame | grep apparmor
Load time should be significantly reduced (typically 50-90% improvement).
10.2 Partial Profile Loading
To load only specific profiles at boot:
sudo systemctl edit apparmor.service
Add:
[Service]
ExecStart=
ExecStart=/usr/bin/apparmor_parser -r /etc/apparmor.d/profile1 /etc/apparmor.d/profile2
This overrides the default behavior of loading all profiles.
10.3 Custom Abstractions
Create reusable permission sets:
sudo vim /etc/apparmor.d/abstractions/custom-app-access
Content:
# Custom abstraction for specific application needs
/opt/custom-software/** r,
/usr/local/custom/** rw,
Use in profiles:
#include <abstractions/custom-app-access>
11. Tips and Tricks
11.1 Desktop Notifications for Denials
Get real-time desktop notifications when AppArmor denies access.
Prerequisites:
sudo pacman -S audit python-notify2 python-psutil
Configure audit group access:
sudo groupadd -r audit
sudo gpasswd -a $USER audit
Edit /etc/audit/auditd.conf:
sudo vim /etc/audit/auditd.conf
Set:
log_group = audit
Override tmpfiles.d permissions:
Since audit 4.1.2, tmpfiles.d sets /var/log/audit to 700. Override with:
sudo vim /etc/tmpfiles.d/audit.conf
Content:
z /var/log/audit 750 root audit - -
Enable and start auditd:
sudo systemctl enable --now auditd
Create autostart desktop entry:
mkdir -p ~/.config/autostart
vim ~/.config/autostart/apparmor-notify.desktop
Content:
[Desktop Entry]
Type=Application
Name=AppArmor Notify
Comment=Receive on screen notifications of AppArmor denials
TryExec=aa-notify
Exec=aa-notify -p -s 1 -w 60 -f /var/log/audit/audit.log
StartupNotify=false
NoDisplay=true
Options explained:
| Option | Meaning |
|---|---|
-p |
Poll for new events |
-s 1 |
Check log every 1 second |
-w 60 |
Display notifications for 60 seconds |
-f /var/log/audit/audit.log |
Audit log file to monitor |
Reboot and verify:
pgrep -ax aa-notify
Note: Depending on system configuration, notification volume may be high. Adjust -s interval or disable for specific profiles.
12. Common Issues
12.1 Login Impossible After Upgrade
Symptoms:
-
Cannot log in to any account
-
System journal shows:
apparmor="DENIED" operation="capable" profile="unix-chkpwd" capname="dac_read_search"
Cause: /etc/shadow or /etc/gshadow permissions are incorrect (not readable by root).
Solution:
-
Boot with AppArmor disabled:
- Edit kernel parameters at boot (add
apparmor=0) - Or use fallback boot entry without AppArmor
- Edit kernel parameters at boot (add
-
Fix permissions:
sudo chmod 600 /etc/shadow /etc/gshadow -
Reboot normally
12.2 Samba/CIFS Server Fails to Start
Symptoms:
Samba service fails with permission errors.
Solution:
Samba has specific AppArmor profile requirements. See:
man apparmor.d
Search for Samba-specific sections, or check /etc/apparmor.d/usr.sbin.smbd for configuration.
12.3 D-Bus Mediation Issues
Note: D-Bus mediation requires kernel support (added in 6.17) and D-Bus compiled with AppArmor support.
Arch's dbus package is built without AppArmor support, so D-Bus rules in profiles are non-functional.
Workaround: Use filesystem permissions to control D-Bus socket access, or use an alternative D-Bus implementation with AppArmor support.
12.4 Profile Fails to Load
Symptoms:
sudo apparmor_parser -r /etc/apparmor.d/profile_name
Returns syntax error.
Common causes:
- Missing comma after permission (
/path/to/file rshould be/path/to/file r,) - Unmatched braces
- Invalid permission flags
- Missing abstraction includes
Solution:
Check syntax carefully. The error message usually indicates line number:
AppArmor parser error for /etc/apparmor.d/usr.bin.app in profile /usr/bin/app at line 42: syntax error, unexpected TOK_ID
12.5 Kernel Not Loading AppArmor
Symptoms:
sudo aa-enabled
Returns "No" even after reboot.
Diagnosis:
-
Check kernel parameter is set:
cat /proc/cmdline | grep lsm -
Check if AppArmor is in LSM list:
cat /sys/kernel/security/lsm -
Verify AppArmor module is available:
ls /sys/kernel/security/apparmor
Solution:
- If parameter is missing: Add
lsm=parameter (see Section 3.1) - If parameter exists but AppArmor not in LSM list: Check parameter syntax
- If
/sys/kernel/security/apparmordoesn't exist: Kernel may not have AppArmor compiled in (unlikely on official Arch kernels)
Appendix A: Profile Syntax Reference
A.1 File Permission Flags
| Flag | Permission | Description |
|---|---|---|
r |
Read | Read file contents, list directory |
w |
Write | Write, create, delete, rename |
a |
Append | Append to file only |
k |
Lock | File locking via flock/fcntl |
m |
Memory map executable | Map file with PROT_EXEC |
l |
Link | Create hard links |
ix |
Inherit execute | Execute with current profile |
Px |
Profile execute | Execute with dedicated profile, fail if no profile |
Cx |
Child execute | Execute with sub-profile |
Ux |
Unconfined execute | Execute without confinement |
px |
Profile execute | Execute with dedicated profile, fallback to inherit |
ux |
Unconfined fallback | Execute unconfined if no profile exists |
A.2 Capability Flags
Capabilities represent privileged operations. Common capabilities:
| Capability | Purpose |
|---|---|
chown |
Change file ownership |
dac_override |
Bypass file permission checks |
dac_read_search |
Bypass read/execute permission checks |
fowner |
Bypass permission checks for file owner |
kill |
Send signals to other processes |
net_admin |
Network administration |
net_bind_service |
Bind to privileged ports (<1024) |
setuid |
Set user ID |
setgid |
Set group ID |
sys_admin |
System administration operations |
sys_ptrace |
Ptrace any process |
Usage:
capability net_bind_service,
capability sys_admin,
A.3 Network Access
Network rules:
network inet stream, # TCP IPv4
network inet dgram, # UDP IPv4
network inet6 stream, # TCP IPv6
network unix stream, # Unix domain socket stream
network unix dgram, # Unix domain socket datagram
Simplified form (all protocols):
network,
A.4 Signal Rules
Allow sending signals:
signal send set=(term, kill) peer=/usr/bin/application,
signal receive set=(term) peer=unconfined,
A.5 Ptrace Rules
Allow ptrace operations:
ptrace read peer=/usr/bin/debugger,
ptrace trace peer=unconfined,
A.6 Mount Rules
Allow mount operations:
mount fstype=tmpfs -> /tmp/,
mount options=(ro, nodev) /dev/sda1 -> /mnt/,
A.7 Pivot Root
pivot_root oldroot=/mnt/old/ /mnt/new/,
A.8 Change Profile
Allow transition to another profile:
change_profile -> /usr/bin/application,
Appendix B: Command Reference
B.1 Profile Management Commands
| Command | Purpose |
|---|---|
aa-status |
Display current AppArmor status |
aa-enabled |
Check if AppArmor is enabled |
aa-enforce <profile> |
Set profile to enforce mode |
aa-complain <profile> |
Set profile to complain mode |
aa-disable <profile> |
Disable profile |
aa-audit <profile> |
Set profile to audit mode (log all, allow all) |
aa-teardown |
Unload all AppArmor profiles |
B.2 Profile Creation Commands
| Command | Purpose |
|---|---|
aa-genprof <binary> |
Generate profile interactively |
aa-autodep <binary> |
Generate basic profile automatically |
aa-logprof |
Update profiles based on logs |
aa-easyprof |
Generate profile from template |
B.3 Parser Commands
| Command | Purpose |
|---|---|
apparmor_parser -r <profile> |
Reload/replace profile |
apparmor_parser -R <profile> |
Remove profile from kernel |
apparmor_parser -a <profile> |
Add profile to kernel |
apparmor_parser --preprocess <profile> |
Show preprocessed profile |
B.4 Utility Commands
| Command | Purpose |
|---|---|
aa-notify |
Monitor and display denials |
aa-decode |
Decode hex-encoded paths in logs |
aa-unconfined |
List unconfined processes with network access |
aa-features-abi |
Show supported AppArmor features |
B.5 Systemd Commands
| Command | Purpose |
|---|---|
systemctl enable apparmor |
Enable AppArmor service |
systemctl disable apparmor |
Disable AppArmor service |
systemctl reload apparmor |
Reload all profiles |
systemctl status apparmor |
Show AppArmor service status |
Appendix C: Security Considerations
C.1 What AppArmor Protects Against
- Application compromise: Limits damage from exploited applications
- Privilege escalation: Restricts what elevated processes can do
- Data exfiltration: Controls file and network access
- Zero-day exploits: Unknown vulnerabilities are constrained by profile
- Malicious plugins: Browser/application plugins run confined
- Configuration errors: Prevents misconfigured services from accessing sensitive data
C.2 What AppArmor Does NOT Protect Against
- Kernel exploits: AppArmor is a kernel module and cannot protect against kernel-level attacks
- Unconfined processes: Applications without profiles run unrestricted
- Root compromise: Root can disable AppArmor
- Physical access: Attacker with physical access can boot without AppArmor
- Overly permissive profiles: Poorly written profiles provide minimal protection
- Social engineering: Cannot prevent user from explicitly granting access
C.3 Security Best Practices
Profile all critical applications:
Prioritize profiles for:
- Network-facing services (web servers, mail servers)
- Applications handling untrusted input (browsers, document viewers)
- Privileged services (system daemons)
Start with complain mode:
- Always test profiles in complain mode first
- Monitor logs for unexpected denials
- Gradually tighten permissions
Use enforce mode in production:
- Complain mode provides no actual protection
- Only use complain mode for testing and development
Minimize capabilities:
- Only grant capabilities actually needed
- Avoid overly broad capabilities like
sys_admin
Regular profile maintenance:
- Review profiles after application updates
- Check logs periodically for new denials
- Update profiles as application behavior changes
Combine with other security measures:
AppArmor is one layer of defense. Also use:
- Firewall (nftables/iptables)
- Strong passwords and authentication
- Regular system updates
- Principle of least privilege
- SELinux or other MAC systems (if not using AppArmor)
C.4 AppArmor vs DAC
AppArmor supplements, not replaces, Discretionary Access Control:
| Scenario | DAC Check | AppArmor Check | Result |
|---|---|---|---|
| User owns file, profile allows | Pass | Pass | Allowed |
| User owns file, profile denies | Pass | Deny | Denied |
| User doesn't own, profile allows | Deny | Pass | Denied |
| User doesn't own, profile denies | Deny | Deny | Denied |
Takeaway: AppArmor can only restrict, never grant, access beyond DAC permissions.
C.5 Distribution Differences
Kernel feature availability varies:
- Ubuntu carries AppArmor-specific kernel patches (D-Bus mediation, network rules)
- Arch uses close-to-mainline kernel (fewer AppArmor features)
- Check feature support:
aa-features-abi --extract
Profile compatibility:
- Ubuntu profiles may use features unavailable on Arch
- Test profiles thoroughly before deploying
- Consult
/etc/apparmor.d/abi/for supported features
Quick Reference
Essential Commands
# Status
sudo aa-status
# Enable profile
sudo aa-enforce /etc/apparmor.d/profile
# Test profile
sudo aa-complain /etc/apparmor.d/profile
# View denials
sudo journalctl -k -b | grep 'apparmor="DENIED"'
# Reload profile
sudo apparmor_parser -r /etc/apparmor.d/profile
File Locations
| Path | Contents |
|---|---|
/etc/apparmor.d/ |
Active profiles |
/etc/apparmor.d/local/ |
Local overrides |
/etc/apparmor.d/abstractions/ |
Reusable fragments |
/usr/share/apparmor/extra-profiles/ |
Additional profiles |
/var/log/audit/audit.log |
Audit logs |
/var/cache/apparmor/ |
Profile cache |
Common Profile Pattern
#include <tunables/global>
profile app /usr/bin/app {
#include <abstractions/base>
/usr/bin/app mr,
/usr/lib/app/** mr,
@{HOME}/.config/app/** rw,
/etc/app.conf r,
}
Additional Resources
- Official AppArmor Wiki: https://gitlab.com/apparmor/apparmor/wikis/home
- AppArmor.d Project: https://apparmor.pujol.io/
- Arch Wiki: https://wiki.archlinux.org/title/AppArmor
- Man Pages:
man apparmor.d- Profile syntaxman aa-status- Status commandman apparmor_parser- Parser usageman aa-genprof- Profile generation
- Core Policy Reference: https://gitlab.com/apparmor/apparmor/wikis/AppArmor_Core_Policy_Reference
- Profiling Guides: