In this lesson, you will learn how to transition your AppArmor profiles from flexible, modifiable states into hardened, immutable kernel-level policy locks to prevent unauthorized tampering during a security breach.
The Logic of Policy Immutability
In a standard environment, an administrator can load, reload, or unload AppArmor profiles using apparmor_parser. However, if an attacker gains root-level access during a system compromise, their first move is often to unload security profiles to hide their tracks or disable restrictions. To counter this, we implement "Kernel-Level Policy Locks"—a state where the policy is pinned directly into the kernel memory, rendering it unmodifiable without a system reboot.
Implementing the Lock
While there isn't a single "lock" command, we achieve this by managing the kernel's interaction with the AppArmor module. Once your baseline profiles (developed in lessons 2–8) are finalized and thoroughly tested via regressions, you move them into the forced-complain or strict enforce mode and restrict the ability to modify the securityfs interface.
To effectively "lock" these profiles in place, you must strip the capability to modify the AppArmor policy store from your administrative users. You can do this by using a secondary security layer—such as a rigid system-level profile—that prevents the apparmor_parser utility from being executed or restricts write access to /sys/kernel/security/apparmor/policy/.
Consider a scenario where you want to ensure a core service profile cannot be disabled:
# 1. Load the profile into enforce mode
apparmor_parser -r -W /etc/apparmor.d/usr.bin.critical-service
# 2. Prevent further unloading by removing the administrative
# capability to write to the policy interface.
# This is done by setting a restrictive system-wide mask
# on the parser utility itself.
chmod 500 /sbin/apparmor_parser
By removing write access to the parser and restricting the CAP_MAC_ADMIN capability (via the capabilities restrictions learned in lesson 6), you effectively lock the current policy state into the kernel. Even a root user will find themselves unable to reload or unload these profiles, effectively neutralizing the attacker’s ability to bypass your security architecture.
Key Takeaway: Kernel-level policy locking is achieved by finalizing your profiles and stripping the administrative capability to interact with the AppArmor policy interface, turning your dynamic defense into an immutable security baseline.