| |

LFCS 144 ๐Ÿง AppArmor โ€” Concepts

โฑ๏ธ Estimated read: 10 min | |

The previous chapters covered SELinux, which is the default Mandatory Access Control (MAC) system on RHEL-family distributions. This chapter introduces AppArmor, which is the default MAC system on Ubuntu and SUSE. Both systems enforce a security policy that sits behind the traditional Unix permissions, but they use fundamentally different models. SELinux uses inode-based labels and a centralized policy engine. AppArmor uses path-based profiles and attaches the policy to the application. The LFCS exam tests this distinction, the two enforcement modes, and the commands that inspect the current state. The critical trap is assuming that the SELinux commands apply to AppArmor. The ls -Z command shows nothing useful on an AppArmor system, and the semanage command is not installed.

Key point: AppArmor is a Linux Security Module (LSM) that confines applications using path-based profiles. It operates in two modes: enforce (denies and logs) and complain (allows and logs). The aa-status command shows the current state and the loaded profiles. The profiles are stored in /etc/apparmor.d/. The apparmor_parser command loads a profile into the kernel.


Why AppArmor requires a specific mental model

The path-based versus label-based problem. SELinux assigns a label to every file and every process, and the policy matches on the labels. The label is stored in the file’s extended attributes, and it follows the file when it is moved or renamed. AppArmor assigns a profile to a program, and the profile contains rules that match on file paths. The /var/www/html/** rule allows the program to read anything under that path. The path is evaluated at runtime, not stored on the file. This is the fundamental difference: SELinux asks “what is the label of this file?”, and AppArmor asks “what is the path of this file?” .

The application-centric problem. An AppArmor profile is attached to a specific executable, such as /usr/sbin/httpd. When the program runs, the kernel checks the profile before every file access, network access, and capability use. The profile is an allow-list: the program can do what the profile permits, and nothing else. A SELinux policy is system-wide: it defines the rules for every domain and every type, and the kernel enforces the entire policy. AppArmor is simpler because the policy is scoped to the application. SELinux is more comprehensive because the policy covers the whole system .

The complain mode problem. AppArmor has two modes. In enforce mode, the profile is enforced, and the denied actions are logged. In complain mode, the profile is not enforced, and the denied actions are logged but allowed. The complain mode is the development mode: it shows what the profile would deny without breaking the application. The aa-complain and aa-enforce commands switch the mode for a specific profile. The aa-status command shows the mode of each loaded profile .

The audit problem. AppArmor logs the denials to the system log (/var/log/syslog) or the audit log (/var/log/audit/audit.log). The log entry contains the profile name, the operation, the path, and the requested permission. The aa-logprof command reads the log and suggests profile changes interactively. The dmesg and journalctl -k commands show the kernel messages, which include the AppArmor denials.

The trade-off. AppArmor is easier to learn and maintain than SELinux. The profiles are readable text files, and the path-based rules are intuitive. The cost is that AppArmor is less precise: a path-based rule allows any file under that path, regardless of the file’s content or origin. A SELinux label-based rule is more precise, but the policy is more complex. The exam tests the conceptual difference and the AppArmor commands.


a. The enforcement modes and the aa-status command

AppArmor profiles have two modes: enforce and complain. The aa-status command shows the current state, the loaded profiles, and their modes.

# Show the AppArmor status
sudo aa-status

The output shows the number of loaded profiles, the number in enforce mode, the number in complain mode, and the list of each profile with its mode.

apparmor module is loaded.
12 profiles are loaded.
10 profiles are in enforce mode.
   /usr/sbin/cupsd
   /usr/sbin/named
   ...
2 profiles are in complain mode.
   /usr/bin/evince
   ...

The systemctl status apparmor command shows the service status. The apparmor.service loads the profiles at boot.

systemctl status apparmor

The profiles are stored in /etc/apparmor.d/. The ls /etc/apparmor.d/ command lists the profile files. The aa-status output shows the loaded profiles, which may be a subset of the files in the directory.


b. The profile structure and the apparmor_parser

An AppArmor profile is a text file. It starts with the profile name (the executable path), followed by the rules in braces.

# /etc/apparmor.d/usr.sbin.httpd
/usr/sbin/httpd {
  #include <abstractions/base>
  /var/www/html/** r,
  /var/log/httpd/** rw,
  /etc/httpd/** r,
  network inet tcp,
  capability net_bind_service,
}

The rule /var/www/html/** r allows the program to read any file under /var/www/html/. The r is the read permission. The w is write. The rw is read and write. The ** matches any file or directory recursively. The network inet tcp rule allows the program to use TCP over IPv4. The capability net_bind_service rule allows the program to bind to a privileged port .

The apparmor_parser -r command reloads a profile. The -r flag is the replace mode: it loads the new version of the profile and replaces the running one. The -R flag removes a profile.

# Reload a profile
sudo apparmor_parser -r /etc/apparmor.d/usr.sbin.httpd

# Remove a profile
sudo apparmor_parser -R /etc/apparmor.d/usr.sbin.httpd

The aa-complain and aa-enforce commands switch the mode of a profile. The argument is the profile file or the executable path.

# Set a profile to complain mode
sudo aa-complain /etc/apparmor.d/usr.sbin.httpd

# Set a profile to enforce mode
sudo aa-enforce /etc/apparmor.d/usr.sbin.httpd

The aa-genprof command generates a new profile for an application. It runs the application in complain mode, collects the accesses, and suggests the rules. The aa-logprof command reads the existing log and suggests updates to the profile.


c. The audit trail and the aa-logprof workflow

AppArmor logs the denials to the system log. The journalctl -k command shows the kernel messages, which include the AppArmor denials. The dmesg command shows the same messages.

# Show AppArmor denials from the kernel log
sudo journalctl -k | grep -i apparmor

# Show the recent denials
sudo dmesg | grep -i apparmor

The log entry shows the profile name, the operation, the path, and the requested permission.

apparmor="DENIED" operation="open" profile="/usr/sbin/httpd" name="/srv/applogs/error.log" pid=1234 comm="httpd" requested_mask="w" denied_mask="w"

The profile="/usr/sbin/httpd" is the profile that denied the operation. The name="/srv/applogs/error.log" is the path that was denied. The requested_mask="w" is the write permission. The denied_mask="w" confirms the denial.

The aa-logprof command reads the log and suggests the profile changes interactively. It shows each denial and asks whether to allow it, deny it, or add a rule. The aa-logprof is the correct tool for the incremental profile development.

# Analyze the log and suggest profile changes
sudo aa-logprof

The aa-genprof command is the alternative for a new application. It starts the application in complain mode, runs it, and collects the accesses. The aa-genprof /path/to/app command generates the profile from the collected accesses.


Complete Example Session

# ============================================
# PART 1: CHECK THE STATUS
# ============================================

sudo aa-status
# Shows loaded profiles, modes, and counts.
# ============================================
# PART 2: LIST PROFILES
# ============================================

ls /etc/apparmor.d/
# Lists the profile files.
# ============================================
# PART 3: VIEW A PROFILE
# ============================================

cat /etc/apparmor.d/usr.sbin.httpd
# Shows the rules for the httpd profile.
# ============================================
# PART 4: SET COMPLAIN MODE
# ============================================

sudo aa-complain /etc/apparmor.d/usr.sbin.httpd
# ============================================
# PART 5: OBSERVE THE DENIAL
# ============================================

sudo journalctl -k | grep -i apparmor
# Shows the denial with the profile, path, and mask.
# ============================================
# PART 6: UPDATE THE PROFILE
# ============================================

# Add the rule to the profile file:
# /srv/applogs/** rw,

sudo apparmor_parser -r /etc/apparmor.d/usr.sbin.httpd
# ============================================
# PART 7: SET ENFORCE MODE
# ============================================

sudo aa-enforce /etc/apparmor.d/usr.sbin.httpd
# ============================================
# PART 8: VERIFY THE FIX
# ============================================

sudo aa-status | grep httpd
# Shows the profile in enforce mode.
# ============================================
# PART 9: USE aa-logprof
# ============================================

sudo aa-logprof
# Interactive suggestions based on the log.

The nine parts trace the AppArmor workflow: status, profile list, profile view, complain mode, denial observation, profile update, enforce mode, verification, and aa-logprof.


Quick Reference

Status Commands

CommandPurpose
aa-statusShow loaded profiles and modes
systemctl status apparmorService status
journalctl -k | grep apparmorKernel denials
dmesg | grep apparmorKernel denials

Mode Commands

CommandPurpose
aa-complain <profile>Set complain mode
aa-enforce <profile>Set enforce mode
apparmor_parser -r <profile>Reload profile
apparmor_parser -R <profile>Remove profile

Profile Commands

CommandPurpose
aa-genprof <app>Generate new profile
aa-logprofSuggest profile updates

Profile Locations

PathPurpose
/etc/apparmor.d/Profile files
/sys/kernel/security/apparmor/Loaded profiles

Best Practices

โœ… Do This:

sudo aa-status
<!-- Check the loaded profiles and modes -->          # โœ…
sudo aa-complain /etc/apparmor.d/usr.sbin.httpd
<!-- Use complain mode for testing -->                # โœ…
sudo apparmor_parser -r /etc/apparmor.d/usr.sbin.httpd
<!-- Reload after profile changes -->                # โœ…

โŒ Don’t Do This:

# Disable AppArmor globally to fix one app
<!-- Use complain mode for the specific profile -->  # โŒ
# Use SELinux commands on AppArmor
<!-- The tools are not interchangeable -->           # โŒ
# Leave a profile in complain mode in production
<!-- Complain mode does not enforce -->              # โŒ

Common Pitfalls

PitfallWhy It HappensFix
App denied despite DACProfile does not allow the pathAdd rule, reload
aa-status shows nothingAppArmor not loadedsystemctl start apparmor
Profile not enforcedProfile in complain modeaa-enforce
Denial not loggedAudit rate limitingCheck journalctl -k
New file path deniedProfile has old pathUpdate and reload

Real-World Examples

1. Status

sudo aa-status

2. Complain Mode

sudo aa-complain /etc/apparmor.d/usr.sbin.httpd

3. Enforce Mode

sudo aa-enforce /etc/apparmor.d/usr.sbin.httpd

4. Reload Profile

sudo apparmor_parser -r /etc/apparmor.d/usr.sbin.httpd

5. View Denials

sudo journalctl -k | grep -i apparmor

6. Generate Profile

sudo aa-genprof /usr/bin/myapp

7. Log Profile

sudo aa-logprof

8. Profile File

cat /etc/apparmor.d/usr.sbin.httpd

9. List Profiles

ls /etc/apparmor.d/

10. Service Status

systemctl status apparmor

Visual

AppArmor vs SELinux

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚  AppArmor                                    โ”‚
โ”‚  โ”œโ”€โ”€ Path-based                              โ”‚
โ”‚  โ”œโ”€โ”€ Application profile                     โ”‚
โ”‚  โ”œโ”€โ”€ Simpler to write                        โ”‚
โ”‚  โ””โ”€โ”€ Default on Ubuntu/SUSE                  โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
                   โ”‚
                   โ–ผ
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚  SELinux                                     โ”‚
โ”‚  โ”œโ”€โ”€ Label-based                             โ”‚
โ”‚  โ”œโ”€โ”€ System-wide policy                      โ”‚
โ”‚  โ”œโ”€โ”€ More complex                            โ”‚
โ”‚  โ””โ”€โ”€ Default on RHEL/Fedora                  โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

Enforcement Modes

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚  Enforce mode                                โ”‚
โ”‚  โ”œโ”€โ”€ Denies the action                       โ”‚
โ”‚  โ””โ”€โ”€ Logs the denial                         โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
                   โ”‚
                   โ–ผ
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚  Complain mode                               โ”‚
โ”‚  โ”œโ”€โ”€ Allows the action                       โ”‚
โ”‚  โ””โ”€โ”€ Logs the denial                         โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

Summary

ItemValue
MAC system (Ubuntu)AppArmor
ModelPath-based
ModesEnforce, Complain
Status commandaa-status
Enforce commandaa-enforce
Complain commandaa-complain
Reload commandapparmor_parser -r
Profile directory/etc/apparmor.d/
Audit logjournalctl -k
Profile generatoraa-genprof, aa-logprof

Key takeaways:

  • AppArmor is path-based; SELinux is label-based. An AppArmor profile restricts a specific executable by matching file paths. A SELinux policy matches file labels. The path model is simpler to configure, but the label model is more precise .
  • The two modes are enforce and complain. Enforce mode denies and logs. Complain mode allows and logs. The aa-complain and aa-enforce commands switch the mode for a specific profile .
  • The aa-status command is the inspection tool. It shows the loaded profiles and their modes. The journalctl -k command shows the kernel denials, which include the profile, path, and requested mask.
  • The profile is a text file. It contains the rules that allow the program to access paths, network resources, and capabilities. The apparmor_parser -r command reloads the profile after a change.
  • The aa-logprof command is the development tool. It reads the denial log and suggests the profile changes interactively. The aa-genprof command generates a new profile from scratch.

Remember: AppArmor is the MAC system on Ubuntu. The profile is the policy. The path is the rule. The enforce mode is the security. The complain mode is the development. The aa-status is the view. The journalctl -k is the denial. The exam tests the distinction from SELinux and the mode commands.

Was this helpful?


Stop using slow, ad-bloated tool sites! ๐Ÿคฎ

๐Ÿ”Ž Search “KandZ Tools” on Google to use many professional utilities for free.

KandZ.me is the ultimate minimalist hub for:
โœ… Finance (Mortgage, Interest, Inflation)
โœ… Tech (Base64, JSON, Dev Suite, IP)
โœ… Health (BMI, BMR, TDEE)
โœ… Productivity (Timer, Workspace, QR)

โšก๏ธ Fast & Private
๐Ÿ”’ No data leaves your device
๐Ÿ’Ž 100% Free

๐Ÿ”— Use it now: https://tools.kandz.me
๐Ÿ”– Bookmark itโ€”youโ€™ll need it later!