Skip to content
Henryk Paluch edited this page Apr 6, 2024 · 2 revisions

AppArmor

AppArmor is additional shield for selected binaries that restricts both system calls available and filesystem access. It is alternative to SELinux.

  • AppArmor is used by Debian, Ubuntu, and traditional (non-containerized) SUSE Linux
  • SELinux is used mainly on RedHat products and also on openSUSE MicroOS.

Introduction on openSUSE

WARNING! AppArmor audit entries are partially incompatible with ausearch and aureport utilties. Why? Because these utilities comes from RedHat (SELinux) and AppArmor uses different message format.

See https://bugs.launchpad.net/ubuntu/+source/audit/+bug/1117804

There are few manuals. This one is best:

To see if AppArmor is active try:

$ aa-enabled 

Yes

To see details on rules you can:

  1. use sudo /usr/sbin/aa-status
  2. directly examine /sys/kernel/security/apparmor/profiles

Using later:

  • to see which rules are enforced, try:
    sudo grep ' (enforce)$' /sys/kernel/security/apparmor/profiles | sort
  • to see which rules are not enforced you my try inverted grep:
    sudo grep -v ' (enforce)$' /sys/kernel/security/apparmor/profiles | sort

To see standard profiles, run this command:

$ rpm -ql apparmor-profiles

/etc/apparmor.d/apache2.d
/etc/apparmor.d/apache2.d/phpsysinfo
/etc/apparmor.d/bin.ping
/etc/apparmor.d/local/README
/etc/apparmor.d/local/bin.ping
/etc/apparmor.d/local/lsb_release
...
/usr/share/apparmor
/usr/share/apparmor/cache
/usr/share/apparmor/cache/d29c4283.0
/usr/share/apparmor/cache/d29c4283.0/.features
/usr/share/apparmor/cache/d29c4283.0/bin.ping
/usr/share/apparmor/cache/d29c4283.0/lsb_release
/usr/share/apparmor/cache/d29c4283.0/nvidia_modprobe
...
usr/share/apparmor/extra-profiles
/usr/share/apparmor/extra-profiles/README
/usr/share/apparmor/extra-profiles/bin.netstat
/usr/share/apparmor/extra-profiles/etc.cron.daily.logrotate
/usr/share/apparmor/extra-profiles/etc.cron.daily.slocate.cron
/usr/share/apparmor/extra-profiles/etc.cron.daily.tmpwatch
/usr/share/apparmor/extra-profiles/postfix-anvil
/usr/share/apparmor/extra-profiles/postfix-bounce

Questions regarding Curl

  • no profile found for curl
    sudo grep curl /sys/kernel/security/apparmor/profiles
    rpm -ql apparmor-profiles | fgrep curl

Intruging questions regarding Firefox

  • Firefox is not shielded by default as we can find:

    $ sudo grep 'firefox' /sys/kernel/security/apparmor/profiles
    
    (empty output)
  • however it is in extra-profiles:

    $ rpm -ql apparmor-profiles | fgrep firefox
    
    /usr/share/apparmor/extra-profiles/usr.lib.firefox.firefox
    /usr/share/apparmor/extra-profiles/usr.lib.firefox.firefox.sh
    /usr/share/apparmor/extra-profiles/usr.lib.firefox.mozilla-xremote-client

Experiment

WARNING! Do NOT do this on production system - you may easily make it unbootable!

We will try to make simple AppArmor for very "popular" xz utility

I copied /etc/apparmor.d/zgrep to /etc/apparmor.d/xz and created minimalist version of /etc/apparmor.d/xz

# experimental AppArmor profile for /usr/bin/xz
# Don't use it on production!
# Based on /etc/apparmor.d/zgrep: Copyright (C) 2022 Christian Boltz

abi <abi/3.0>,
include <tunables/global>

profile xz /usr/bin/xz {
  include <abstractions/base>
}

You can find "base" as /etc/apparmor.d/abstractions/base and see what is enabled. It is quite permissible.

Now try to load it under "complain" mode (it will log all access to Audit, but will not prevent access):

# apparmor_parser --reload -C /etc/apparmor.d/xz

Warning from /etc/apparmor.d/xz (/etc/apparmor.d/xz line 11): Caching disabled for: 'xz' due to force complain

Start watching audit log with:

tail -f /var/log/audit/audit.log | fgrep xz

Now try some trivial workload:

# as non-privileged user:
dd if=/dev/urandom bs=1024k count=16 of=test.bin
xz -9v test.bin
xz -dv test.bin.xz

You will se allowed entries in audit.log:

type=AVC msg=audit(1712389016.849:254): apparmor="ALLOWED" \
 operation="open" profile="xz" name="/home/ansible/test.bin" pid=23904 comm="xz" requested_mask="r" denied_mask="r" fsuid=1000 ouid=1000

Now tricky part - enable enforce mode - DO NOT DO THIS ON PRODUCTION!

apparmor_parser --reload  /etc/apparmor.d/xz

# verify that enforce is used
sudo fgrep -w xz /sys/kernel/security/apparmor/profiles

  xz (enforce)

If you dare you can reboot system, or even run dracut.

You can to use ausearch utility to make audit.log output more readable (see https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/7/html/security_guide/sec-understanding_audit_log_files for details). For example:

# -c is "comm" - name of process without path

$ ausearch -c xz

time->Sat Apr  6 09:37:07 2024
type=AVC msg=audit(1712389027.600:260): apparmor="ALLOWED" \
  operation="unlink" profile="xz" name="/home/ansible/test.bin" \
  pid=23904 comm="xz" requested_mask="d" denied_mask="d" fsuid=1000 ouid=100

After reboot xz will "no longer work", because our AppArmor rules:

$ dd if=/dev/urandom bs=1024k count=16 of=test2.bin
$ xz -9v test2.bin 

test2.bin (1/1)
xz: test2.bin: Permission denied

NOTE: Because of tension between RedHad (SELinux) and Canonical (AppArmor) we are unable to use ausearch to filter out DENIED messages. As workaround you can try:

# ausearch -c xz -i | fgrep apparmor=DENIED

type=AVC msg=audit(04/06/24 10:04:35.435:225) : \
 apparmor=DENIED operation=open profile=xz name=/home/ansible/test2.bin \
 pid=1178 comm=xz requested_mask=r denied_mask=r fsuid=ansible ouid=ansible 

See https://bugs.launchpad.net/ubuntu/+source/audit/+bug/1117804

Questions

Normally files under /etc/apparmor.d/ and /usr/share/apparmor/extra-profiles/ are text. But there is an exception - directory /usr/share/apparmor/cache/ - there are binaries...

Clone this wiki locally