KaliLinux 2017.1: Mandatory Access Control with AppArmor

This article will describe usage of AppArmor.

1 Install AppArmor

Install AppArmor, change kernel parameter and reboot.

$ sudo apt install -y apparmor apparmor-utils \
       apparmor-profiles apparmor-profiles-extra
$ sudo systemctl enable apparmor
$ . /etc/default/grub
$ V="${GRUB_CMDLINE_LINUX} apparmor=1 security=apparmor"
$ sudo sed -e "s/^GRUB_CMDLINE_LINUX=.*/GRUB_CMDLINE_LINUX=\"${V}\"/g" \
       -i /etc/default/grub
$ sudo grub-mkconfig -o /boot/grub/grub.cfg
$ sudo reboot

Enable profile after reboot. Do not enable /etc/apparmor.d/usr.sbin.mysqld because it is empty file.

$ for profile in /etc/apparmor.d/*; do
  [ "${profile}" != "/etc/apparmor.d/usr.sbin.mysqld" ] && \
    sudo aa-enforce "${profile}"
$ sudo systemctl reload apparmor

2 Show AppArmor status

The aa-status shows AppArmor status. Enforce mode blocks unallowed operation. Complain mode does not unallowed operation but reports to log file. For example, /usr/bin/evince's behavior is limited by AppArmor (AppArmor is path based MAC). And not listed path here are not limited by AppArmor.

$ sudo aa-status
apparmor module is loaded.
54 profiles are loaded.
54 profiles are in enforce mode.

2.1 Change profile status

Change to enforce mode with aa-enforce.

$ sudo aa-enforce /etc/apparmor.d/<profile>

Change to complain mode with aa-complain.

$ sudo aa-complain /etc/apparmor.d/<profile>

2.2 Enable and disable profile

Disable profile with apparmor_parser -R. Creating symbolic link to "disable directory" disables profiles on AppArmor boot.

$ sudo apparmor_parser -R /etc/apparmor.d/<profile>
$ sudo ln -s /etc/apparmor.d/<profile> /etc/apparmor.d/disable/

Disable profile with apparmor_parser -r. Deleting symbolic link from "disable directory" enables profiles on AppArmor boot.

$ sudo apparmor_parser -r /etc/apparmor.d/<profile>
$ sudo rm -f /etc/apparmor.d/disable/<profile>

3 Create profile

This article will use /bin/mycat which is /bin/cat copy. And create profile for /bin/mycat.

$ sudo cp /bin/cat /bin/mycat

Create base profile with aa-genprof. And terminate aa-genprof with pressing F key.

After running aa-genprof, run /bin/mycat on the other terminal and output log to /var/log/syslog. Pressing S key to aa-genprof will read /var/log/syslog and suggest profile.

$ sudo aa-genprof /bin/mycat
Profiling: /bin/mycat

[(S)can system log for AppArmor events] / (F)inish

The base profile is the following.

$ sudo cat /etc/apparmor.d/bin.mycat
# Last Modified: Tue Jun 13 16:38:23 2017
#include <tunables/global>

/bin/mycat {
  #include <abstractions/base>

  /bin/mycat mr,


Change this base profile to the following. Note that /foo is treated as a file and /bar/ is treated as a directory.

$ sudo cat /etc/apparmor.d/bin.mycat
# Last Modified: Tue Jun 13 16:38:23 2017
#include <tunables/global>

/bin/mycat {
  #include <abstractions/base>

  /bin/mycat mr,

  # /foo is file and /bar/ is directory.
  /etc/hostname r, # /etc/hostname can be read.
  /etc/dpkg/* r,   # Files in /etc/dpkg can be read but directory cannot.
  /etc/apt/** r,   # All file and directory in /etc/apt can be read.

Enable profile with aa-enforce.

$ sudo aa-enforce /etc/apparmor.d/bin.mycat
Setting /etc/apparmor.d/bin.mycat to enforce mode.

Running /bin/mycat is the following.

$ mycat /etc/passwd > /dev/null
mycat: /etc/passwd: Permission denied
$ mycat /etc/hostname > /dev/null
$ mycat /etc/dpkg/dpkg.cfg > /dev/null
$ mycat /etc/dpkg/dpkg.cfg.d/force-unsafe-io > /dev/null
mycat: /etc/dpkg/dpkg.cfg.d/force-unsafe-io: Permission denied
$ mycat /etc/apt/apt.conf.d/00CDMountPoint > /dev/null