Debian Linux Security Ubuntu

Debian AppArmor Tutorial

AppArmor is a mandatory access control system for Linux. In a mandatory access control system (MAC), the kernel imposes restrictions on paths, sockets, ports, and various input/output mechanisms. It was developed by Immunex and now is maintained by SUSE. It has been part of the Linux kernel since version 2.6.36.

While the Linux kernel provides good isolation of users and strong file permission control, a MAC like AppArmor provides more finely-grained permissions and protection against many unknown threats. If a security vulnerability is found in the Linux kernel or other system daemon, a well-configured AppArmor system can prevent access to critical paths that could be vulnerable to the issue.

AppArmor can work in effectively two modes – enforce and complain. Enforce is the default production status of AppArmor, while complain is useful for developing a rule set based on real operation patterns and for logging violations. It is configured via plain text files in a relatively friendly format and has a shorter learning curve than most other mandatory access control systems.


To install AppArmor on Debian, run (as root):

apt install apparmor apparmor-utils auditd

You may omit auditd if you don’t need profile generation tools.

If you wish to install starter and additional profiles, run:

apt install apparmor-profiles apparmor-profiles-extra


Since AppArmor is a Linux kernel module, you must enable it with the following commands:

mkdir -p /etc/default/grub.d

Create the file /etc/default/grub.d/apparmor.cfg with the following contents:


Save and exit, then run:


Then reboot.

There is debate if this should be done automatically. You may wish to consult the end of this bug report to see if this has been changed since the time of this writing.

Once you reboot, you can check to see if AppArmor is enabled by running:


This command will list loaded AppArmor profiles and list their current state of compliance (enforced, complain, etc.)

If you run:

ps auxZ | grep -v '^unconfined'

You’ll see a list of programs that are confined by an AppArmor profile. A confined program is one that is affected and limited (either passively, in complain mode, or actively in enforced mode) by AppArmor.

Changing Modes / Disabling AppArmor

If you wish to disable AppArmor because a program isn’t working, you may wish to consider placing the profile in complain mode instead of enforced mode. To do this, run (as root, or via sudo):

aa-complain /path/to/program

For example, if ping won’t work correctly, use:

aa-complain /usr/bin/ping

Once a profile is in complain mode you can examine the logging via /var/log/syslog or with journalctl -xe on systemd systems (Debian 8.x, Jessie, and higher).

Once you have edited the profile to remove or adjust the restriction, you can turn on enforce mode again for the binary with:

aa-enforce /path/to/program

In the example above, replace /path/to/program with the full path to the binary affected by the profile in question.

If you have a problem with a program and it’s in complain mode, the logs will provide specific information about what action was denied. The operation field will explain what the program tried to do, the profile field the specific profile affected, name will specify the target of the action (i.e. what file was stopped from a read or write operation), and the requested and denied masks indicate if the operation, both requested by the program and denied per the profile, was read or read-write.

You can disable a profile entirely by running:

aa-disable /path/to/program

Or, you can disable AppArmor completely by editing the file: /etc/default/grub.d/apparmor.cfg to contain:


Then running:


And rebooting your system.

Working with AppArmor Profiles

AppArmor profiles reside in the /etc/apparmor.d/ directory. If you install the apparmor-profiles and apparmor-profiles-extra packages package, you’ll find profiles in /usr/share/doc/apparmor-profiles and /usr/share/doc/apparmor-profiles/extra. To activate them, copy the files into /etc/apparmor.d then edit them to ensure they contain the values you want, save, then run:

service apparmor reload

If you wish to reload just one profile, run:

apparmor_parser -r /etc/apparmor.d/profile

Where “profile” is the name of the profile in question.

It is not recommended to just copy the profiles and extra profiles into the /etc/apparmor.d directory without hand-editing them. Some profiles may be old and some most certainly will not contain the values you want. If you do copy them all, at least set them to complain so that you can monitor violations without breaking programs in production:

cd /etc/apparmor.d
for f in *.* ; do aa-complain /etc/apparmor.d/$f; done

You can use the aa-enforce command individually to enable profiles you wish to keep, tune the ones that cause issues and enforce those, or remove ones you don’t need by running aa-disable or removing the profile file from /etc/apparmor.d.

Creating an AppArmor Profile

Before you create a custom profile, you will want to search the /etc/apparmor.d and /usr/share/doc/apparmor-profiles directories for an existing profile that covers the binary in question. To search these, run:

find /usr/share/doc/apparmor-profiles | grep “program” -i

Replace program with the program you want to protect with AppArmor. If you find one, copy it to /etc/apparmor.d and then edit the file in your favorite text editor.

Each profile comprises of three main sections: includes, capabilities, and paths. You can find a helpful reference in SuSE’s documentation.


Includes provide syntax that you can use inside the file. They use the C/C++ #include <> syntax and usually reference abstractions found in the /etc/apparmor.d/abstractions directory.


The capabilities section, typically found after the includes, lists specific capabilities that the program can perform. For example, you can let a program perform a setuid operation with:

capability setuid

The capability net_bind_service allows a program to bind to a network port. If you don’t grant this, a server daemon like Apache can’t open port 80 and listen. However, omitting this capability can provide excellent security for processes you don’t trust on the network.


You may list paths that the program is able to read (and possibly write). For example, if you want to allow the program to access the /etc/passwd file, add:

/etc/passwd r

In the profile. Note the “r” – this means read only. If you change this to “w”, writing to this path or file will be allowed.

Even if you allow a path in AppArmor, it is still subject to Linux file system restrictions (i.e. set with chmod, chgrp, and chown). However, AppArmor will still provide an extra layer of protection should those mechanisms be compromised.


The key to a successful AppArmor deployment is to set profiles to complain, then enforce. Careful log examination will give you the minimal paths and capabilities needed for successful program operation. By assigning these and no more you will dramatically increase your system security.

About the author

Robert Oliver

Robert Oliver

Writer, System Admin, Full Stack Developer, Philosopher.