How to Configure AppArmor Profiles and Enforce Modes on Ubuntu Server for Daemon Sandboxing

In production Linux environments, securing applications cannot rely solely on standard discretionary access controls (Unix file permissions). If a vulnerability such as remote code execution (RCE) is discovered in a web server like Nginx or a database service, the attacker inherits all privileges of that service user. AppArmor (Application Armor) provides Mandatory Access Control (MAC) enforced at the Linux kernel layer. By binding restrictive security profiles to specific executable paths, AppArmor confines daemons strictly to authorized files, sockets, and capabilities—preventing attackers from traversing the filesystem even if the process is compromised.

Auditing AppArmor Status on Ubuntu Server

AppArmor is enabled by default across all modern Ubuntu Server releases. To inspect the current operational state, loaded profiles, and process enforcement:

sudo aa-status

The output reports the number of loaded profiles divided into two distinct operational modes:

Operational Mode Kernel Behavior Logging Action Primary Use Case
Enforce Mode Blocks unauthorized actions immediately. Logs denial event to audit log. Active production protection.
Complain Mode Permits the action without blocking. Logs policy violations for review. Profile generation, testing, and troubleshooting.

Installing AppArmor Userland Utilities

To generate, modify, and audit profiles easily, install the apparmor-utils package containing command-line management binaries:

sudo apt update
sudo apt install apparmor-utils apparmor-profiles -y

Generating a Custom Profile Using aa-genprof

Suppose you have a custom Node.js API or proprietary daemon running at /usr/local/bin/custom-api that you wish to sandbox. Rather than hand-coding complex policy syntax, use the interactive generator:

sudo aa-genprof /usr/local/bin/custom-api
  1. aa-genprof places the application into Complain mode and starts a live event monitor.
  2. In a separate terminal, exercise your application thoroughly: execute API requests, trigger database connections, and write log files.
  3. Return to the aa-genprof prompt and press S to scan the audit logs.
  4. The utility prompts you to allow, deny, or glob access to requested files, network sockets, and capabilities.
  5. Press F to finish and save the compiled profile to /etc/apparmor.d/usr.local.bin.custom-api.

Understanding AppArmor Profile Syntax and Permissions

Profiles located in /etc/apparmor.d/ use clear, human-readable directives:

#include <tunables/global>

/usr/local/bin/custom-api {
  #include <abstractions/base>
  #include <abstractions/nameservice>

  # Allow network socket communication
  network inet tcp,
  network inet udp,

  # Allow read-only access to configuration files
  /etc/custom-api/*.conf r,

  # Allow read/write access to dedicated log directory
  /var/log/custom-api/*.log rw,

  # Explicitly deny access to shadow password database
  deny /etc/shadow mrwklx,
}

Toggling Modes and Reloading Profiles

To transition a profile between Complain and Enforce modes without restarting the daemon:

# Set profile to Complain mode for diagnostics
sudo aa-complain /usr/local/bin/custom-api

# Switch profile back to strict Enforce mode
sudo aa-enforce /usr/local/bin/custom-api

# Reload all profiles in /etc/apparmor.d/
sudo apparmor_parser -r /etc/apparmor.d/usr.local.bin.custom-api

Auditing Violations with aa-logprof

When an application’s behavior changes following an update, inspect denied actions and update the profile automatically:

sudo aa-logprof

Confinements enforced by AppArmor provide defense-in-depth, neutralizing zero-day exploits and establishing resilient security boundaries across Ubuntu Server services.

Get the best tech tips delivered straight to your inbox.

Join thousands of readers mastering Apple, Google, Microsoft, and Linux.