Apparmor and its usage

From EIK wiki

AppArmor and its usage

Whats is AppArmor


AppArmor is a Linux kernel security module that allows the system administrator to restrict programs' capabilities with per-program profiles. Profiles can allow capabilities like network access, raw socket access, and the permission to read, write, or execute files on matching paths. AppArmor supplements the traditional Unix discretionary access control(DAC) model by providing (mandatory access control) (MAC). It was included in the mainline Linux kernel since version 2.6.36 and its development has been supported by Canonical since 2009. It is available by default on Ubuntu and Suse distributions. AppArmor relies on paths instead of inodes, which are used by another similar security mechanism SELinux. Apparmor uses rules, which are combined into profiles for every process you want to restrict by it. These profiles can be run in "enforce" or "complain" modes. To generate profile you can run it with AppArmor in profile mode. While enforced profile will disallow any restricted activity, profile ran in complain mode will still allow program to do what was intended, but log this violation in logfile.

AppArmor features

AppArmor can restrict following things

  • file access (read, write, link, lock)
  • library loading
  • execution of applications
  • coarse-grained network (protocol, type, domain)
  • capabilities
  • coarse owner checks (task must have the same euid/fsuid as the object being checked) starting with Ubuntu 9.10
  • mount starting with Ubuntu 12.04 LTS
  • unix(7) named sockets starting with Ubuntu 13.10
  • DBus API (path, interface, method) starting with Ubuntu 13.10
  • signal(7) starting with Ubuntu 14.04 LTS
  • ptrace(2) starting with Ubuntu 14.04 LTS
  • unix(7) abstract and anonymous sockets starting with Ubuntu 14.10

AppArmor commands

Check status




Load profile

 apparmor_parser -a /etc/apparmor.d/

Replace (reload) singe profile

  apparmor_parser -r /etc/apparmor.d/

Reload all profiles

 systemctl reload apparmor

Disable profile

  ln -s /etc/apparmor.d/ /etc/apparmor.d/disable/
  apparmor_parser -R /etc/apparmor.d/

Enabling disabled profile

 rm /etc/apparmor.d/disable/
 apparmor_parser -a /etc/apparmor.d/

Run profile in complain mode

 aa-complain /path/to/program

Run profile in enforce mode

 aa-enforce /path/to/program

Disabling AppArmor

Open /etc/default/grub file and change or add this line GRUB_CMDLINE_LINUX_DEFAULT="apparmor=0". Then run update-grub2 and restart your PC.

Permission flags

These are permission flags which are used in policy files. With them you can specify which things are allowed and which are denied.

  • r - read
  • w - write -- conflicts with append
  • a - append -- conflicts with write
  • ux - unconfined execute
  • Ux - unconfined execute -- scrub the environment
  • px - discrete profile execute
  • Px - discrete profile execute -- scrub the environment
  • cx - transition to subprofile on execute
  • Cx - transition to subprofile on execute -- scrub the environment
  • ix - inherit execute
  • m - allow PROT_EXEC with mmap(2) calls
  • l - link
  • k - lock

Example log record in complain mode

Apr 27 17:35:30 test kernel: [11443.630597] audit: type=1400 audit(1493303730.576:1168): apparmor="ALLOWED" operation="open" profile="/usr/sbin/proftpd" name="/etc/protocols" pid=21403 comm="proftpd" requested_mask="r" denied_mask="r" fsuid=0 ouid=0

apparmor="ALLOWED" operation="open" //allows action

profile="/usr/sbin/proftpd" //program which is allowed to open

name="/etc/protocols" // file which will be opened 

pid=21403 //process id

comm="proftpd" // actual command

requested_mask="r" // requested action read

denied_mask="r" // action to be denied

fsuid=0 ouid=0 //  file system id and object owner uid

Sample profile explained

# Last Modified: Wed Apr 26 21:46:31 2017
#include <tunables/global>

/usr/sbin/nginx {               // profile 
  #include <abstractions/base>  // includes basic base rules

  capability dac_override,      // can override Discretionary access control
  network inet stream,          // can create ipv4 socket

  /etc/group r,                 //
  /etc/nginx/conf.d/ r,         //
  /etc/nginx/mime.types r,      //
  /etc/nginx/nginx.conf r,      //   file read allowed
  /etc/nginx/sites-enabled/ r,  //
  /etc/nsswitch.conf r,         //
  /etc/passwd r,                //
  /etc/ssl/openssl.cnf r,       //
  /usr/sbin/nginx mr,           //   allows reading and writing files in memory 
  /var/log/nginx/error.log w,   //   write to file allowed
  /var/www/html/** r,           //   read allowed recursively inside directory

Creating new profiles

There are two ways of profiling. First one is called Stand-Alone profiling and second one is Systematic profiling.

  • Stand-alone is more fit if you want to create profile for one application, however setbacks are, that you need to keep running the profiling process whole time, while you are creating profile.
  • Systematic profiling is meant for multiple processes, and you can restart server and programs while still profiling.

Stand-alone profiling

First you probably need to install additional package by running apt install apparmor-utils.

For example, lets try and profile Vsftpd. After installing it, this command needs to be run first aa-genprof /usr/sbin/vsftpd. It will stay in monitoring mode. Then in other terminal window restart or start Vsftpd daemon by running systemctl restart vsftpd. After that just proceed with casual tasks. Connect with local user to FTP, upload, download, create and delete files and directories. Also create file in /tmp. After doing this, switch to first terminal window and push S for (S)can system log for AppArmor events. Aa-genprof will then asks a couple of questions about actions what vsftpd did and you can either approve or disable them, alone with some more options. For example this rule /home/user1/* ris very narrow and ftp will not work properly if your system have more than one user. First profile that was made for vsftpd looked like this

  # Last Modified: Wed Apr 26 00:39:00 2017
  #include <tunables/global>
  /usr/sbin/vsftpd {
  #include <abstractions/authentication>
  #include <abstractions/base>
  #include <abstractions/nameservice>
  #include <abstractions/lxc/container-base>
  /dev/urandom r,
  /etc/fstab r,
  /etc/ftpusers r,
  /etc/hosts.allow r,
  /etc/hosts.deny r,
  /etc/mtab r,
  /etc/shells r,
  /etc/vsftpd.* r,
  /etc/vsftpd/* r,
  /home/*/ rw,
  /usr/sbin/vsftpd mrix,
  /var/log/vsftpd.log w,

After you test it out, you will notice, that you can still access pretty much everything even when this profile does not specify it. It is because the line #include <abstractions/lxc/container-base> gives wide access. So instead i changed permissions to be more narrow, and now profile looked like this. User will be able to write in his home directory and in /tmp. He will not see contents in /home.

# Last Modified: Wed Apr 26 20:39:27 2017
#include <tunables/global>

/usr/sbin/vsftpd {
  #include <abstractions/authentication>
  #include <abstractions/base>
  #include <abstractions/nameservice>

  capability audit_write,
  capability setgid,
  capability setuid,
  capability sys_admin,
  capability sys_chroot,

  / r,
  /dev/urandom r,
  /etc/fstab r,
  /etc/ftpusers r,
  /etc/hosts.allow r,
  /etc/hosts.deny r,
  /etc/mtab r,
  /etc/shells r,
  /etc/vsftpd.* r,
  /etc/vsftpd/* r,
  /tmp/ r,
  /tmp/* w,
  /usr/sbin/vsftpd mrix,
  /var/log/vsftpd.log w,
  @{HOME}/ r,
  @{HOME}/* w,

Systematic profiling

Lets try and do systematic profiling on vsftpd and nginx. After installing them, this command needs to be run in order to create profile skeleton for both programms aa-autodep vsftpd nginx. After that run this command to puth both profiles in complain mode aa-complain vsftpd nginx. Then restart both services systemctl restart vsftpd ; systemctl restart nginx and do some basic tasks. Open html page in web browser, create and open some subdirectories. Upload and delete files with ftp client. After you think you have done everything you require from both services, run this command aa-logprof and approve rules. You may need to run it a few times untill you tweak rules just right. Below are the basic rules which allows ftp juser to upload files in his home directory and in /var/www/html/, and ngix to serve them properly over http.

# Last Modified: Wed Apr 26 21:50:54 2017
#include <tunables/global>

/usr/sbin/vsftpd {
  #include <abstractions/base>
  #include <abstractions/postfix-common>

  capability audit_write,
  capability net_bind_service,
  capability sys_admin,

  network inet6 stream,
  network netlink raw,

  / r,
  /etc/ftpusers r,
  /etc/group r,
  /etc/login.defs r,
  /etc/nsswitch.conf r,
  /etc/pam.d/* r,
  /etc/passwd r,
  /etc/securetty r,
  /etc/shadow r,
  /etc/shells r,
  /etc/vsftpd.conf r,
  @{HOME}/ r,
  @{HOME}/** rw,
  /usr/sbin/vsftpd mr,
  /var/ r,
  /var/log/vsftpd.log w,
  /var/www/ rw,
  /var/www/html/** rw,
# Last Modified: Wed Apr 26 21:46:31 2017
#include <tunables/global>

/usr/sbin/nginx {
  #include <abstractions/base>

  capability dac_override,

  network inet stream,

  /etc/group r,
  /etc/nginx/conf.d/ r,
  /etc/nginx/mime.types r,
  /etc/nginx/nginx.conf r,
  /etc/nginx/sites-enabled/ r,
  /etc/nsswitch.conf r,
  /etc/passwd r,
  /etc/ssl/openssl.cnf r,
  /usr/sbin/nginx mr,
  /var/log/nginx/error.log w,
  /var/www/html/** r,

Practical example by hardening server

Lets assume that you want to set up Ubuntu LTS server and quickly harden it with AppArmor. The server will run Virtualmin as a server control panel. First you install Virtualmin by running these commands. Saddly they do not provide checksumms.


Then install additional profiles

apt install apparmor-profiles

By checking aa-status you can see that there are bunch of profiles already in enforce and complain mode.


Next, to actually enable profiling on new process, you need to install AppArmor tools apt-get install apparmor-utils Then put proftpd process in complaint mode aa-autodep proftpd aa-complain proftpd

If you are running more than one program in complain mode, then by default kernel might limit messages logged, and this might not let you build complete profile. To temporarily circumvent this, execute this command sysctl -w kernel.printk_ratelimit=0

Next we check which services are running and listening to network sockets, but does not have profiles defined yet by running aa-unconfined In output you can see that there are some unconfined programs running. We skip perl because that is too generic, also SSH for now, and enable profiling for ProFTPD and some Dovecot subprocesses (we need to use full path for master process, because it is not in out $PATH).

aa-autodep proftpd
aa-autodep /usr/lib/postfix/sbin/master
aa-autodep dovecot

Then run them in complain mode

aa-complain dovecot
aa-complain proftpd
aa-complain /usr/lib/postfix/sbin/master

Restart services

systemctl restart postfix
systemctl restart dovecot
systemctl restart proftpd

After that just proceed to do normal things, browse and send emails, create new folders in IMAP account, upload and download files thru ProFTPD. After you think you have done everything you wanted to allow, run aa-logprof and generate profiles. Lets mass enable generated profiles in enforce mode

aa-enforce /etc/apparmor.d/usr.lib.dovecot.*
aa-enforce /etc/apparmor.d/usr.lib.postfix*
aa-enforce proftpd

Reminder that enabling profiles in enforced mode might render your system unstable. You need to have a clear plan, what your system is going to do. How many users will be there, what will they want to do, etc.

Getting additional rules

You can download precreated AppArmor rules for most popular services by installing additional package apt install apparmor-profiles. They are installed in same default directory /etc/apparmor.d as the rest of profiles.

Additional resources