41.7 Managing AppArmor Profiles: aa-status, aa-enforce, aa-complain
Alright, let’s get our hands dirty with the actual management of AppArmor profiles. You’ve got them installed, but now what? How do you know what’s even running? How do you tweak it when it inevitably breaks your perfectly good application? This is where you move from a passive user to someone who’s actually in control.
First things first, you need to take stock of the situation. AppArmor, unlike some other security frameworks (we won’t name names), is actually pretty good at telling you what it’s doing.
Checking the Lay of the Land with aa-status
Before you start flipping enforcement modes, you need to see what profiles are loaded and what state they’re in. This is your dashboard. The aa-status command is your best friend here. It’s simple, it’s direct, and it gives you exactly what you need without a lot of fuss.
Running it as root is non-negotiable here—this is kernel-level security state we’re talking about.
sudo aa-status
The output will look something like this, and it’s actually useful:
apparmor module is loaded.
44 profiles are loaded.
44 profiles are in enforce mode.
/usr/bin/evince
/usr/sbin/cupsd
/usr/sbin/ntpd
...
0 profiles are in complain mode.
0 processes are unconfined but have a profile defined.
See? Immediately, you know everything. The module is loaded (a surprising number of issues start here), how many profiles are ready to rock, and, crucially, how many are actually enforcing policy versus just whining about it (complain mode). The list of enforced profiles is gold; it tells you exactly which applications on your system are under AppArmor’s control. If you see 0 profiles loaded, you’ve either got a bigger problem or you need to restart the apparmor service (sudo systemctl restart apparmor).
Putting the Cuffs On: aa-enforce
So you’ve written a new profile, or you’ve found one cowering in /etc/apparmor.d/ that’s not yet active. It’s time to unleash it on the world. This is where aa-enforce comes in. You don’t enable a profile in AppArmor; you put it into enforce mode. Semantics matter. This command tells the kernel, “Hey, for this application, start actually blocking the things this policy says to block.”
The command is straightforward. You point it at the profile file. Note: you use the full path to the profile file, not just the profile name.
sudo aa-enforce /etc/apparmor.d/bin.ping
Now, here’s the thing everyone misses at least once: aa-enforce only changes the mode for the next time the application starts. It loads the new policy into the kernel. If the targeted program (like ping in this case) is already running, that existing process is still under the old rules (or lack thereof). This is a classic “gotcha.” You need to restart the application for the new enforced profile to take effect. It’s not a bug; it’s just how the kernel works. You can’t swap the security rules on a running process mid-execution—that would be chaos.
Letting It Slide: aa-complain
Your shiny new profile is enforced. You try to run your application, and it immediately shatters into a million permission-denied pieces. Congratulations, you’ve just experienced the most common AppArmor workflow!
This is not failure. This is data collection. Instead of just giving up, you put the profile into complain mode. This is AppArmor’s learning mode. The policy is still loaded and monitored, but instead of blocking actions, it just logs them. It’s the framework’s way of saying, “I would have totally stopped you from doing that, but I’m just going to make a note of it for now.”
You use aa-complain exactly like aa-enforce:
sudo aa-complain /etc/apparmor.d/sbin.my_custom_app
Now, go run your application and try to do everything it needs to do. Let it fail “safely.” All those permission denials that would have been blocked are now being written to /var/log/syslog or /var/log/audit/audit.log. This log is the raw material you need to fix your profile. You can then use tools like aa-logprof to systematically parse these logs and update your profile, asking you “Should we allow this?” for each violation.
The beauty of this cycle—enforce, break, complain, test, update, re-enforce—is that it’s how you build airtight policies without making your system utterly unusable during the process. It acknowledges that writing perfect security policy on the first try is a fantasy reserved for textbooks and bad presentations.
The key takeaway? Management isn’t a one-time action. It’s an interactive process of interrogation. You use aa-status to see what’s happening, aa-enforce to lock things down, and aa-complain when you (inevitably) got it wrong the first time. It’s a conversation with your security system, not a series of commands you yell at it.