AppArmor
This page was last modified on 17 January 2019, at 15:45.
Original author(s) | Immunix |
---|---|
Developer(s) | SUSE |
Initial release | 1998 |
Stable release |
2.13.0
/ 15 April 2018 |
Preview release |
2.12.0
|
Repository |
{{ |
Written in | C, Perl, C++ |
Operating system | Linux |
Type | System software |
License | GNU General Public Licence |
Website |
gitlab |
AppArmor ("Application Armor") is a security module of Linux kernel that limits the capabilities of programs by using their individual profiles. Profiles can grant or deny programs access to the network, raw sockets, read, write, or execute permissions on specific system paths. AppArmor complements DAC (discretionary access control) with mandatory access control (MAC). It is included in the Linux kernel since version 2.6.36.
Contents
Overview
AppArmor is a Linux security system based on mandatory access control. AppArmor restricts individual programs to a set of files, capabilities, and access to the network. Such restrictions are called AppArmor policies for a program or simply a profile. AppArmor complements the discretionary Unix access model: if access has been allowed by the system, the final decision rests with AppArmor, which verifies the permissions with its control and access policies. AppArmor supports a profile learning mode that helps users write and update security policies. The training mode allows you to create and configure a profile using the example of a running program. After full training there is a transition to the compulsory execution mode. Although the result of creating such a profile may be more “soft” than fully manual configuration for a specific environment and application, the training mode requires much less effort and knowledge required to use AppArmor.
AppArmor differs from some other MAC systems on Linux: it is path-based, it allows mixing of enforcement and complain mode profiles, it uses include files to ease development, and it has a far lower barrier to entry than other popular MAC systems.
AppArmor is an established technology first seen in Immunix and later integrated into Ubuntu, Novell/SUSE, and Mandriva. Core AppArmor functionality is in the mainline Linux kernel from 2.6.36 onwards; work is ongoing by AppArmor, Ubuntu and other developers to merge additional AppArmor functionality into the mainline kernel.[Reference 1]
History
- AppArmor's predecessor SubDomain began life as a Grad project
- 1998/1999 WireX founded by Crispin Cowan to commercialize SubDomain, and develop other security extensions to Linux. WireX produced Immunix a secure Linux distribution based on Red Hat Linux using StackGuard, FormatGuard, and SubDomain. WireX involved in creation of LSM.
- In early 2004 WireX rebranded to Immunix and then dropped its Linux distribution, refocusing instead on providing SubDomain for SuSE linux.
- SubDomain rewritten to use LSM, despite WireX involvement in creating the LSM the porting of AppArmor to the LSM was done late after the LSM was created for political reasons. This meant that LSM was less than optimal for AppArmor and the feedback that could have improved the LSM during its development never occured.
- A YaST GUI implemented for SubDomain on SuSE linux.
- In May 2005 Novell acquired Immunix and rebranded SubDomain as AppArmor and began cleaningup/rewritting the code for upstream linux kernel inclusion.
- AppArmor 2.0.1 released - based on SubDomain 2.0 code with AppArmor rebranding.
- AppArmor 2.1 released. Large portions of the kernel module where rewritten to use a new custom dfa based matching engine (dropping pcre for licencing reasons) and with name lookup being based on a large patch to vfs and LSM which passed the vfsmnt through into all of the relevant LSM hooks).
- In October 2007 Novell layed-off most of the development team working on AppArmor, and re-assigned the remaining developers putting AppArmor in development mode.
- June 2008 Novell releases AppArmor 2.3 released using another iteration of the vfs patches, and extension to the matching engine.
- In May 2009 Canonical Inc. picks up AppArmor maintenance and development.
- Fall 2009 AppArmor 2.4 released. Based on a large update/rewrite to of the AppArmor 2.3 kernel module, it was updated to for creds, and the LSM path_security hooks.
- July 2010 AppArmor security module merged into security-next tree. Core functionality accepted into official Linux 2.6.36 kernel. A few compatibility small patches are needed to work with current userspace.[Reference 2]
- AppArmor was enabled in Solus Release 3 on 2017/8/15.[Reference 3]
Distributions with AppArmor
Distributions that include AppArmor: [Reference 4]
- Annvix
- Arch Linux
- Debian
- Gentoo
- openSUSE (installed by default)
- Pardus Linux
- PLD
- Ubuntu (installed by default)
Installing AppArmor
Source layout
AppArmor consists of several different parts:
binutils/
- source for basic utilities written in compiled languages
changehat/
- source for using changehat with Apache, PAM and Tomcat
common/
- common makefile rules
desktop/
- empty
kernel-patches/
- compatibility patches for various kernel versions
libraries/
- libapparmor source and language bindings
parser/
- source for parser/loader and corresponding documentation
profiles/
- configuration files, reference profiles and abstractions
tests/
- regression and stress testsuites
utils/
- high-level utilities for working with AppArmor
Building and Installing AppArmor Userspace
To build and install AppArmor userspace on your system, build and install in the following order. Some systems may need to export various python-related environment variables to complete the build. For example, before building anything on these systems, use something along the lines of:
$ export PYTHONPATH=$(realpath libraries/libapparmor/swig/python) $ export PYTHON=/usr/bin/python3 $ export PYTHON_VERSION=3 $ export PYTHON_VERSIONS=python3
libapparmor:
$ cd ./libraries/libapparmor $ sh ./autogen.sh $ sh ./configure --prefix=/usr --with-perl --with-python # see below $ make $ make check $ make install
an additional optional argument to libapparmor's configure is --with-ruby
, to generate Ruby bindings to libapparmor.
Binary Utilities:
$ cd binutils $ make $ make check $ make install
parser:
$ cd parser $ make # depends on libapparmor having been built first $ make check $ make install
Utilities:
$ cd utils $ make $ make check $ make install
Apache mod_apparmor:
$ cd changehat/mod_apparmor $ make # depends on libapparmor having been built first $ make install
PAM AppArmor:
$ cd changehat/pam_apparmor $ make #depends on libapparmor having been built first $ make install
Profiles:
$ cd profiles $ make $ make check # depends on the parser having been built first $ make install
Profiles
AppArmor profiles are plain text files that are located in /etc/apparmor.d/
. The profile files are named according to the full path to the executable they manage, with the replacement of the "/" with ".". For example /etc/apparmor.d/bin.ping
is the AppArmor profile for the /bin/ping
command.
AppArmor profiles have 2 execution modes:
- Complaining/Learning: profile violations are resolved and stored in the log. Useful for testing and developing new profiles.
- Enforced/Confined: enforce policy profile, it also records the violation in the log.
There are two main types of rules used in a profile:
- Path entries: describes which files the application has access to on the filesystem.
- Capability entries: determine which permissions a restricted process may use.
Example for /etc/apparmor.d/bin.ping
:
#include <tunables/global>
/bin/ping flags=(complain) {
#include <abstractions/base>
#include <abstractions/consoles>
#include <abstractions/nameservice>
capability net_raw,
capability setuid,
network inet raw,
/bin/ping mixr,
/etc/modules.conf r,
}
-
#include <tunables/global>
: includes operators from another file. This allows operators belonging to multiple applications to reside in a single common file. -
/bin/ping flags=(complain)
: flags that set the training mode -
capability net_raw,
: allows the application to access features of CAP_NET_RAW Posix.1e. -
/bin/ping mixr,
: allows the application to read and execute the file.
The profile should restarted after editing.
Creating a profile
- Development of a test plan. The test plan should be divided into small text blocks. Each test block should have a brief description and a list of execution steps. Some standard text blocks:
- Program startup.
- Stopping the program.
- Program restarting.
- Test all commands supported by the init script.
- Create a new profile: Use 'aa-genprof' to create a new profile. Command in terminal:
sudo aa-genprof executable
- To get your new profile as part of the apparmor-profiles package, log the problem in Launchpad for the AppArmor package.
- Include your test plan and test blocks.
- Attach your new profile to the reported issue.
Updating profiles
If the program behaves incorrectly, analyze the messages in the log files. Aa-logprof can be used to scan AppArmor log files to check messages, review (analyze) them, and update profiles. The command in the terminal:sudo aa-logprof
AppArmor is guided by the principle of "everything that is not allowed is forbidden", so when there is no corresponding rule in the profile, the action is not allowed.
AppArmor Language
AppArmor profile Language
Profiles begin with the name of the profile followed by an optional flags field, then an opening { followed by the rules for the profile and is finished by a closing } If the profile name does not begin with a / then the keyword profile should be prepended.[Reference 5] Eg:
/usr/bin/firefox {
# profile contents
}
/usr/bin/firefox flags=(complain) {
# profile contents
}
profile /usr/bin/ {
# profile contents
}
profile user1 {
# profile contents
}
Profile names can contain file rule globbing characters to allow them to apply to multiple executables.
Comments
Comments are line oriented and begin with a #. Text following a '# to the end of the line is ignored (with the exception of the #include rule
). Eg:
# Comment 1
# Comment 2
profile example { # comment 3
# comment 4
/home/foo rw, # comment at the end of a file rule
}
Include Rules
Policy files can include other files to share text segments. AppArmor includes follow the C include convention. They start with #include
followed by either < >
for text chucks relative to a set include directory or " "
for files relative to the current file. The # is optional and shouldn't be used in newer profiles. Eg:
#include <file>
#include “a/relative/path/file”
include <file>
#include
conflicts with commenting rules and takes precedence. The # and include must not be separated from the include with white space otherwise it is considered a comment
# include is a comment
#include <file>
Child profiles
A profile can contain children profiles. Child profiles can be used to confine an application in a special way, or when you want the child to be unconfined on the system, but confined when called from the parent. Eg:
/parent/profile {
/path/to/child1 cx -> child1,
/path/to/child2 cx,
/path/to/* cx, # for * matching child3 will transition to child3,
# child4, child5, ... will transition to /path/to/child*
# if matching child profile does not exist will fail
/another/path/to/* cx -> child1, # send all matching execs to child1
profile child1 {
}
profile /path/to/child2 {
}
profile /path/to/child3 {
}
# generic fall back profile
profile /path/to/child* {
}
}
Network Rules
AppArmor currently supports course grained access to networking via network rules. For example, a network daemon might need:
/profile {
network inet dgram,
network inet stream,
}
Or a packet analyzer might need:
/profile {
network raw,
network packet,
}
File rules
File rules control how files are accessed and only occur within a profile. They consist of a pathname, a permission set and are terminated by a comma. They can be written with either the permission first or the pathname first, though the convention it to list the path first. A valid pathname always begins with a /. Eg:
/profile {
/path/to/file rw, # file rule beginning with a pathname (convention)
rw /path/to/file2, # file rule beginning with permissions
/path/to/file3 # file rule split over multiple lines
rw,
}
File rules can contain special globbing characters that allow matching to multiple files.
File Globbing
AppArmor uses a file globbing syntax similar to that used by the bash shell. Globbing is not standard full regular expression syntax, but instead uses a few characters known as wild cards. The AppArmor wildcards have slightly different semantics than that of bash
- * - match zero or more characters at the directory level. When looking at the path as a string this will match every character except /.
- ** - match 0 or more characters over multiple directory levels
- ? - match a single character that is not /
- {} - alternation - a comma separated list of alternate strings that can be matched. An empty string is allowed and means the empty string is a viable alternative
- [] - character class
- [^] - inverted character class
File Globbing examples:
/dir/file
- match a specific file
/dir/*
- match any files in a directory (including dot files)
/dir/a*
- match any file in a directory starting with 'a'
/dir/*.png
- match any file in a directory ending with '.png'
/dir/[^.]*
- match any file in a directory except dot files
/dir/
- match a directory
/dir/*/
- match any directory within /dir/
/dir/a*/
- match any directory within /dir/ starting with a
/dir/*a/
- match any directory within /dir/ ending with a
/dir/**
- match any file or directory in or below /dir/
/dir/**/
- match any directory in or below /dir/
/dir/**[^/]
- match any file in or below /dir/
/dir{,1,2}/** - match any file or directory in or below /dir/, /dir1/, and /dir2/
File permissions
The following file permissions are supported:
- r - read
- w - write
- a - append (implied by w)
- x - execute
- m - m - memory map executable
- k - lock (requires r or w, AppArmor 2.1 and later)
- l - link
The owner keyword can be used as a qualifier making permission conditional on owning the file (process fsuid == file's uid).
owner /foo rw,
The following are in development:
- create (implied by w)
- delete (implied by w)
- chown - change ownership (implied by w)
- chmod - change mode (implied by w)
Execute permissions
AppArmor distinguishes between the different ways a file may be executed. Because a new process is created when executing a file, the process is said to transition to another (possibly same) profile across execute.
The base execute permission are::
- ix - the new process should run under the current profile
- cx - the new process should run under a child profile that matches the name of the executable
- px - the new process should run under another profile that matches the name of the executable
- ux - the new process should run unconfined
A process that runs unconfined is actually in the built-in unconfined profile, which allows everything with no logging.
The px, cx, and ux permission when written using a capitalized leading character (Px, Cx, Ux) will trigger libc's Secure Execution. When developing profiles, the Secure Execution variants should in general be used so that the executed program starts in a clean environment.
The px and cx rules (and their Secure Execution variants) may also have an ix, or ux fallback, expressed as pix, pux, cix, or cux. Using the fallback indicates that the process should run under the profile if it exists, otherwise the profile transition should use the specified ix or ux transition. It is often a good idea to use 'PUx' instead of 'Ux' so you don't have to update your profile for when the executed program has an AppArmor profile added later. For example, if a confined program should be allowed to run 'evince', then the profile might have:
/usr/bin/evince PUx,
The px and cx rules (and all their variants) can also be modified to specify a profile by name instead of using the profile that matches the name of the executable. This is done by providing a -> transition arrow and the name of the profile.
/foo px -> profile1,
Using AppArmor
The apparmor-utils package contains command-line utilities that you can use to change the AppArmor execution mode, find profile status, create new profiles, and so on.[Reference 6]
- apparmor_status is used to see the current status of the AppArmor profile:
$ sudo apparmor_status
- aa-complain switch the profile to the complain mode:
$ sudo aa-complain /path/to/bin
- aa-enforce switch the profile to the enforce mode:
$ sudo aa-enforce /path/to/bin
- AppArmor profiles are located in directory <code>/etc/apparmor.d. It can be used to control all profiles mode. Enter the next command to switch all profiles to complain mode:
$ sudo aa-complain /etc/apparmor.d/*
Switch all profiles to enforce mode:$ sudo aa-enforce /etc/apparmor.d/*
- apparmor_parser command is used to load the profile into the kernel. It can also be used to restart the installed profile when using the option '-r'. To install enter:
$ cat /etc/apparmor.d/profile.name | sudo apparmor_parser -a
To restart:$ cat /etc/apparmor.d/profile.name | sudo apparmor_parser -r
-
/etc/init.d/apparmor
restarts all profiles:$ sudo /etc/init.d/apparmor reload
- Directory
/etc/apparmor.d/disable
can be used in conjunction with the option apparmor_parser -R to disable the profile:$ sudo ln -s /etc/apparmor.d/profile.name /etc/apparmor.d/disable/
$ sudo apparmor_parser -R /etc/apparmor.d/profile.name
- To activate a disabled profile, remove the symbolic link to the profile in
/etc/apparmor.d/disable/
. Then install the profile using the option '-a':$ sudo rm /etc/apparmor.d/disable/profile.name
$ cat /etc/apparmor.d/profile.name | sudo apparmor_parser -a
- AppArmor can be disabled and kernel module can be unloaded using the following command:
$ sudo /etc/init.d/apparmor stop
$ sudo update-rc.d -f apparmor remove
- To reactivate AppArmor enter:
$ sudo /etc/init.d/apparmor start
$ sudo update-rc.d apparmor defaults
AppArmor protection status can be inspected using both high-level and low-level tools. The high-level tools use the low-level tools to gather information, and most of the low-level tools require an unconfined 'root' (uid 0) process. It may be possible to confine these processes with file and capability privileges.[Reference 7]
High level view
The 'aa-status' tool gives a high level status of AppArmor and applications it has profiles for (as root):
# aa-status apparmor module is loaded. 11 profiles are loaded. 11 profiles are in enforce mode. /usr/lib/connman/scripts/dhclient-script /usr/share/gdm/guest-session/Xsession /usr/bin/googleearth /usr/bin/evince-previewer /usr/sbin/tcpdump /usr/lib/cups/backend/cups-pdf /usr/bin/evince-thumbnailer /sbin/dhclient3 /usr/bin/evince /usr/sbin/cupsd /usr/lib/NetworkManager/nm-dhcp-client.action 0 profiles are in complain mode. 2 processes have profiles defined. 2 processes are in enforce mode : /usr/sbin/cupsd (1192) /sbin/dhclient3 (22378) 0 processes are in complain mode. 0 processes are unconfined but have a profile defined.
Information on running processes
To discover which processes are confined, you can either use 'aa-status' as described above, or alternatively use the 'ps' command (as root):
# ps aux -Z | grep -v unconfined LABEL USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND /usr/sbin/cupsd root 1192 0.0 0.0 75148 1260 ? Ss Jan15 0:00 /usr/sbin/c... /sbin/dhclient3 root 22378 0.0 0.0 6464 1088 ? S Jan23 0:00 /sbin/dhcli...
The raw data is also available via /proc
(as root):
# grep -L unconfined /proc/*/attr/current /proc/1192/attr/current /proc/22378/attr/current
Most sites that deploy AppArmor are especially interested in confining applications that use the network. Because this is so common, the aa-unconfined tool can help system administrators discover network servers that may or may not be confined (as root):
# aa-unconfined 883 /usr/sbin/avahi-daemon not confined 883 /usr/sbin/avahi-daemon not confined 1192 /usr/sbin/cupsd confined by '/usr/sbin/cupsd (enforce)' 12375 /usr/sbin/pdns_recursor not confined 12375 /usr/sbin/pdns_recursor not confined 22378 /sbin/dhclient3 (/sbin/dhclient) confined by '/sbin/dhclient3 (enforce)' 27260 /usr/sbin/dictd (dictd 1.11.1: 1/275) not confined
Information from the kernel module
AppArmor supports the kernel-standard securityfs mechanism; securityfs is normally mounted on /sys/kernel/security
, and the apparmor module populates /sys/kernel/security/apparmor
with a few control and information files. The informational files are:
$ ls -1 /sys/kernel/security/apparmor/ features matching profiles
'features' and 'matching' provides feature and version information that is used by apparmor_parser to compile profiles for the running kernel. 'profiles' provides a list of the profiles loaded into the kernel as well as the per-profile enabled/complain/audit information.
Information from the persistent configuration files
You may also be curious about the profiles that AppArmor will load on next boot. /etc/apparmor.d/
contains all the profiles, as well as profile 'chunks' that are commonly shared between profiles. Some of these 'chunks' are abstractions, which are essentially libraries of access rules. On boot, the AppArmor init scripts will examine and load the profiles in /etc/apparmor.d/
, ignoring certain files such as vim swap files and package manager generated files as well as profiles that have a symbolic link in /etc/apparmor.d/disable/
. Files with a symbloic link in /etc/apparmor.d/force-complain/
are forced into complain mode.
If you want to verify the contents of a profile --- say, you want to make sure the abstractions that are included in the profile do not allow some ridiculous permissions --- you can invoke:
$ apparmor_parser -Q --debug /etc/apparmor.d/usr.bin.firefox | head -10 ----- Debugging built structures ----- Name: /usr/lib/firefox-4.0b7/firefox{,*[^s][^h]} Profile Mode: Enforce Capabilities: net_bind_service --- Entries --- Mode: r:r Name: (/) Mode: r:r Name: (/**/) Mode: rx:rx Name: (/bin/bash) Mode: rx:rx Name: (/bin/dash) Mode: rx:rx Name: (/bin/grep)
This listing shows the permissions granted when the user owns the resource (file, directory, pipe, etc.) and when the user does not own the resource.
Additionally, you can see the complete profile with all abstractions include with:
$ apparmor_parser -p /etc/apparmor.d/usr.bin.firefox ... ##included <abstractions/audio> /dev/admmidi* rw, /dev/adsp* rw, /dev/aload* rw, /dev/amidi* rw, /dev/audio* rw, /dev/dmfm* rw, ...
References
- ↑ AppArmor Wiki Page // Ubuntu Wiki. Updated on: 10.22.2018. URL: https://wiki.ubuntu.com/AppArmor (retrieved: 11.15.2018)
- ↑ AppArmor_History // GitLab [2011—2019]. Updated on: 08.04.2018. URL: https://gitlab.com/apparmor/apparmor/wikis/AppArmor_History (retrieved: 01.17.2019).
- ↑ Solus 3 Linux Distribution Released For Enthusiasts // phoronix. [2004—2018]. Updated on: 08.15.2017. URL: https://www.phoronix.com/scan.php?page=news_item&px=Solus-3-Released (retrieved: 10.04.2018).
- ↑ AppArmor Home Wiki // GitLab [2011—2019]. Updated on: 12.21.2018. Access Mode: https://gitlab.com/apparmor/apparmor/wikis/home/ (retrieved: 11.15.2018)
- ↑ AppArmor Profile Language // GitLab [2011—2019]. Updated on: 11.04.2017. URL: https://gitlab.com/apparmor/apparmor/wikis/QuickProfileLanguage (retrieved: 11.15.2018).
- ↑ AppArmor // ubuntu.ru. URL: https://help.ubuntu.ru/wiki/руководство_по_ubuntu_server/безопасность/apparmor (retrieved: 10.04.2018).
- ↑ AppArmor Monitoring // GitLab [2011—2019]. Updated on: 11.04.2017. URL: https://gitlab.com/apparmor/apparmor/wikis/AppArmorMonitoring (retrieved: 11.15.2018).
Literature
- ubuntu.ru [Electronic resource]: AppArmor Documentation / Date: 09.26.2018. Access mode: https://help.ubuntu.ru/wiki/руководство_по_ubuntu_server/безопасность/apparmor.
- AppArmor GitLab [Electronic resource]: AppArmor official wiki / Date: 09.26.2018. Access mode: https://gitlab.com/apparmor/apparmor/wikis/home
- AppArmor GitLab [Electronic resource]: AppArmor official wiki / Date: 09.26.2018. Access mode: https://gitlab.com/apparmor/apparmor/wikis/Documentation
- AppArmor GitLab [Electronic resource]: AppArmor official GitLab page / Date: 09.26.2018. Access mode:: https://gitlab.com/apparmor
Присоединяйся к команде
ISSN:
Следуй за Полисом
Оставайся в курсе последних событий
License
Except as otherwise noted, the content of this page is licensed under the Creative Commons Creative Commons «Attribution-NonCommercial-NoDerivatives» 4.0 License, and code samples are licensed under the Apache 2.0 License. See Terms of Use for details.