AppArmor for Complete System - Including init, PID1, Systemd, Everything! - Full System MAC policy

Testing on Qubes. Figured out how to make initramfs xtrace visible.

(

)


  • . /scripts/init-bottom/ORDER
  • /scripts/init-bottom/apparmor-profile-everything
    Warning from stdin (line 1): config file ‘/etc/apparmor/parser.conf’ not found
    [ 4.575432] audit: type=1400 audit(1576958583.257:2): apparmor=“STATUS” operation=“profile_load” profile=“unconfined” name=“systemd-modules-load” pid=243 comm=“apparmor_parser”
    Warning from stdin (line 1): config file ‘/etc/apparmor/parser.conf’ not found
    [ 4.578381] audit: type=1400 audit(1576958583.261:3): apparmor=“STATUS” operation=“profile_load” profile=“unconfined” name=“systemd-sysctl” pid=246 comm=“apparmor_parser”
    Warning from stdin (line 1): config file ‘/etc/apparmor/parser.conf’ not found
    [ 4.582981] audit: type=1400 audit(1576958583.265:4): apparmor=“STATUS” operation=“profile_load” profile=“unconfined” name=“init-systemd” pid=251 comm=“apparmor_parser”
  • ‘[’ -e /conf/param.conf ]
  • /scripts/init-bottom/udev

What does ALLOWED mean? I guess that is OK but why does it show it?

[ 5.299519] audit: type=1400 audit(1576958583.981:5290): apparmor=“ALLOWED” operation=“open” profile=“init-systemd//null-/bin/systemd-tmpfiles” name=“/etc/tmpfiles.d/” pid=320 comm=“systemd-tmpfile” requested_mask=“r” denied_mask=“r” fsuid=0 ouid=0
[ 5.299752] audit: type=1400 audit(1576958583.985:5291): apparmor=“ALLOWED” operation=“open” profile=“init-systemd//null-/lib/systemd/systemd-random-seed” name=“/etc/machine-id” pid=319 comm=“systemd-random-” requested_mask=“r” denied_mask=“r” fsuid=0 ouid=0
[ 5.299805] audit: type=1400 audit(1576958583.985:5292): apparmor=“ALLOWED” operation=“chmod” profile=“init-systemd//null-/lib/systemd/systemd-random-seed” name=“/var/lib/systemd/random-seed” pid=319 comm=“systemd-random-” requested_mask=“w” denied_mask=“w” fsuid=0 ouid=0
[ 5.299858] audit: type=1400 audit(1576958583.985:5293): apparmor=“ALLOWED” operation=“chown” profile=“init-systemd//null-/lib/systemd/systemd-random-seed” name=“/var/lib/systemd/random-seed” pid=319 comm=“systemd-random-” requested_mask=“w” denied_mask=“w” fsuid=0 ouid=0
[ 5.300356] audit: type=1400 audit(1576958583.985:5294): apparmor=“ALLOWED” operation=“open” profile=“init-systemd” name=“/proc/319/comm” pid=1 comm=“systemd” requested_mask=“r” denied_mask=“r” fsuid=0 ouid=0
[ 5.300401] audit: type=1400 audit(1576958583.985:5295): apparmor=“ALLOWED” operation=“open” profile=“init-systemd” name=“/proc/319/comm” pid=1 comm=“systemd” requested_mask=“r” denied_mask=“r” fsuid=0 ouid=0
[ 5.300444] audit: type=1400 audit(1576958583.985:5296): apparmor=“ALLOWED” operation=“open” profile=“init-systemd” name=“/proc/319/cgroup” pid=1 comm=“systemd” requested_mask=“r” denied_mask=“r” fsuid=0 ouid=0


Permission hardening needs a profile. Or kicksecure shell profile?

[ 10.303738] audit: type=1400 audit(1576958588.989:26448): apparmor=“ALLOWED” operation=“open” profile=“init-systemd//null-/usr/lib/security-misc/permission-hardening//null-/usr/bin/find” name=“/usr/lib/python3/dist-packages/OpenGL/EGL/VERSION/” pid=721 comm=“find” requested_mask=“r” denied_mask=“r” fsuid=0 ouid=0
[ 10.304240] audit: type=1400 audit(1576958588.989:26449): apparmor=“ALLOWED” operation=“open” profile=“init-systemd//null-/usr/lib/security-misc/permission-hardening//null-/usr/bin/find” name=“/usr/lib/python3/dist-packages/OpenGL/EGL/VERSION/pycache/” pid=721 comm=“find” requested_mask=“r” denied_mask=“r” fsuid=0 ouid=0
[ 10.304832] audit: type=1400 audit(1576958588.989:26450): apparmor=“ALLOWED” operation=“open” profile=“init-systemd//null-/usr/lib/security-misc/permission-hardening//null-/usr/bin/find” name=“/usr/lib/python3/dist-packages/OpenGL/EGL/NOK/” pid=721 comm=“find” requested_mask=“r” denied_mask=“r” fsuid=0 ouid=0
[ 10.305305] audit: type=1400 audit(1576958588.989:26451): apparmor=“ALLOWED” operation=“open” profile=“init-systemd//null-/usr/lib/security-misc/permission-hardening//null-/usr/bin/find” name=“/usr/lib/python3/dist-packages/OpenGL/EGL/NOK/pycache/” pid=721 comm=“find” requested_mask=“r” denied_mask=“r” fsuid=0 ouid=0
[ 10.305895] audit: type=1400 audit(1576958588.989:26452): apparmor=“ALLOWED” operation=“open” profile=“init-systemd//null-/usr/lib/security-misc/permission-hardening//null-/usr/bin/find” name=“/usr/lib/python3/dist-packages/OpenGL/EGL/pycache/” pid=721 comm=“find” requested_mask=“r” denied_mask=“r” fsuid=0 ouid=0
[ 10.306437] audit: type=1400 audit(1576958588.989:26453): apparmor=“ALLOWED” operation=“open” profile=“init-systemd//null-/usr/lib/security-misc/permission-hardening//null-/usr/bin/find” name=“/usr/lib/python3/dist-packages/OpenGL/EGL/EXT/” pid=721 comm=“find” requested_mask=“r” denied_mask=“r” fsuid=0 ouid=0
[ 10.306960] audit: type=1400 audit(1576958588.989:26454): apparmor=“ALLOWED” operation=“open” profile=“init-systemd//null-/usr/lib/security-misc/permission-hardening//null-/usr/bin/find” name=“/usr/lib/python3/dist-packages/OpenGL/EGL/EXT/pycache/” pid=721 comm=“find” requested_mask=“r” denied_mask=“r” fsuid=0 ouid=0
[ 10.307604] audit: type=1400 audit(1576958588.993:26455): apparmor=“ALLOWED” operation=“open” profile=“init-systemd//null-/usr/lib/security-misc/permission-hardening//null-/usr/bin/find” name=“/usr/lib/python3/dist-packages/OpenGL/EGL/KHR/” pid=721 comm=“find” requested_mask=“r” denied_mask=“r” fsuid=0 ouid=0
[ 10.308072] audit: type=1400 audit(1576958588.993:26456): apparmor=“ALLOWED” operation=“open” profile=“init-systemd//null-/usr/lib/security-misc/permission-hardening//null-/usr/bin/find” name=“/usr/lib/python3/dist-packages/OpenGL/EGL/KHR/pycache/” pid=721 comm=“find” requested_mask=“r” denied_mask=“r” fsuid=0 ouid=0
[ 10.308764] audit: type=1400 audit(1576958588.993:26457): apparmor=“ALLOWED” operation=“open” profile=“init-systemd//null-/usr/lib/security-misc/permission-hardening//null-/usr/bin/find” name=“/usr/lib/python3/dist-packages/OpenGL/EGL/ANDROID/” pid=721 comm=“find” requested_mask=“r” denied_mask=“r” fsuid=0 ouid=0

[ 10.303738] audit: type=1400 audit(1576958588.989:26448): apparmor=“ALLOWED” operation=“open” profile=“init-systemd//null-/usr/lib/security-misc/permission-hardening//null-/usr/bin/find” name=“/usr/lib/python3/dist-packages/OpenGL/EGL/VERSION/” pid=721 comm=“find” requested_mask=“r” denied_mask=“r” fsuid=0 ouid=0
[ 10.304240] audit: type=1400 audit(1576958588.989:26449): apparmor=“ALLOWED” operation=“open” profile=“init-systemd//null-/usr/lib/security-misc/permission-hardening//null-/usr/bin/find” name=“/usr/lib/python3/dist-packages/OpenGL/EGL/VERSION/pycache/” pid=721 comm=“find” requested_mask=“r” denied_mask=“r” fsuid=0 ouid=0
[ 10.304832] audit: type=1400 audit(1576958588.989:26450): apparmor=“ALLOWED” operation=“open” profile=“init-systemd//null-/usr/lib/security-misc/permission-hardening//null-/usr/bin/find” name=“/usr/lib/python3/dist-packages/OpenGL/EGL/NOK/” pid=721 comm=“find” requested_mask=“r” denied_mask=“r” fsuid=0 ouid=0
[ 10.305305] audit: type=1400 audit(1576958588.989:26451): apparmor=“ALLOWED” operation=“open” profile=“init-systemd//null-/usr/lib/security-misc/permission-hardening//null-/usr/bin/find” name=“/usr/lib/python3/dist-packages/OpenGL/EGL/NOK/pycache/” pid=721 comm=“find” requested_mask=“r” denied_mask=“r” fsuid=0 ouid=0
[ 10.305895] audit: type=1400 audit(1576958588.989:26452): apparmor=“ALLOWED” operation=“open” profile=“init-systemd//null-/usr/lib/security-misc/permission-hardening//null-/usr/bin/find” name=“/usr/lib/python3/dist-packages/OpenGL/EGL/pycache/” pid=721 comm=“find” requested_mask=“r” denied_mask=“r” fsuid=0 ouid=0
[ 10.306437] audit: type=1400 audit(1576958588.989:26453): apparmor=“ALLOWED” operation=“open” profile=“init-systemd//null-/usr/lib/security-misc/permission-hardening//null-/usr/bin/find” name=“/usr/lib/python3/dist-packages/OpenGL/EGL/EXT/” pid=721 comm=“find” requested_mask=“r” denied_mask=“r” fsuid=0 ouid=0
[ 10.306960] audit: type=1400 audit(1576958588.989:26454): apparmor=“ALLOWED” operation=“open” profile=“init-systemd//null-/usr/lib/security-misc/permission-hardening//null-/usr/bin/find” name=“/usr/lib/python3/dist-packages/OpenGL/EGL/EXT/pycache/” pid=721 comm=“find” requested_mask=“r” denied_mask=“r” fsuid=0 ouid=0
[ 10.307604] audit: type=1400 audit(1576958588.993:26455): apparmor=“ALLOWED” operation=“open” profile=“init-systemd//null-/usr/lib/security-misc/permission-hardening//null-/usr/bin/find” name=“/usr/lib/python3/dist-packages/OpenGL/EGL/KHR/” pid=721 comm=“find” requested_mask=“r” denied_mask=“r” fsuid=0 ouid=0
[ 10.308072] audit: type=1400 audit(1576958588.993:26456): apparmor=“ALLOWED” operation=“open” profile=“init-systemd//null-/usr/lib/security-misc/permission-hardening//null-/usr/bin/find” name=“/usr/lib/python3/dist-packages/OpenGL/EGL/KHR/pycache/” pid=721 comm=“find” requested_mask=“r” denied_mask=“r” fsuid=0 ouid=0
[ 10.308764] audit: type=1400 audit(1576958588.993:26457): apparmor=“ALLOWED” operation=“open” profile=“init-systemd//null-/usr/lib/security-misc/permission-hardening//null-/usr/bin/find” name=“/usr/lib/python3/dist-packages/OpenGL/EGL/ANDROID/” pid=721 comm=“find” requested_mask=“r” denied_mask=“r” fsuid=0 ouid=0


[ 10.303738] audit: type=1400 audit(1576958588.989:26448): apparmor=“ALLOWED” operation=“open” profile=“init-systemd//null-/usr/lib/security-misc/permission-hardening//null-/usr/bin/find” name=“/usr/lib/python3/dist-packages/OpenGL/EGL/VERSION/” pid=721 comm=“find” requested_mask=“r” denied_mask=“r” fsuid=0 ouid=0
[ 10.304240] audit: type=1400 audit(1576958588.989:26449): apparmor=“ALLOWED” operation=“open” profile=“init-systemd//null-/usr/lib/security-misc/permission-hardening//null-/usr/bin/find” name=“/usr/lib/python3/dist-packages/OpenGL/EGL/VERSION/pycache/” pid=721 comm=“find” requested_mask=“r” denied_mask=“r” fsuid=0 ouid=0
[ 10.304832] audit: type=1400 audit(1576958588.989:26450): apparmor=“ALLOWED” operation=“open” profile=“init-systemd//null-/usr/lib/security-misc/permission-hardening//null-/usr/bin/find” name=“/usr/lib/python3/dist-packages/OpenGL/EGL/NOK/” pid=721 comm=“find” requested_mask=“r” denied_mask=“r” fsuid=0 ouid=0
[ 10.305305] audit: type=1400 audit(1576958588.989:26451): apparmor=“ALLOWED” operation=“open” profile=“init-systemd//null-/usr/lib/security-misc/permission-hardening//null-/usr/bin/find” name=“/usr/lib/python3/dist-packages/OpenGL/EGL/NOK/pycache/” pid=721 comm=“find” requested_mask=“r” denied_mask=“r” fsuid=0 ouid=0
[ 10.305895] audit: type=1400 audit(1576958588.989:26452): apparmor=“ALLOWED” operation=“open” profile=“init-systemd//null-/usr/lib/security-misc/permission-hardening//null-/usr/bin/find” name=“/usr/lib/python3/dist-packages/OpenGL/EGL/pycache/” pid=721 comm=“find” requested_mask=“r” denied_mask=“r” fsuid=0 ouid=0
[ 10.306437] audit: type=1400 audit(1576958588.989:26453): apparmor=“ALLOWED” operation=“open” profile=“init-systemd//null-/usr/lib/security-misc/permission-hardening//null-/usr/bin/find” name=“/usr/lib/python3/dist-packages/OpenGL/EGL/EXT/” pid=721 comm=“find” requested_mask=“r” denied_mask=“r” fsuid=0 ouid=0
[ 10.306960] audit: type=1400 audit(1576958588.989:26454): apparmor=“ALLOWED” operation=“open” profile=“init-systemd//null-/usr/lib/security-misc/permission-hardening//null-/usr/bin/find” name=“/usr/lib/python3/dist-packages/OpenGL/EGL/EXT/pycache/” pid=721 comm=“find” requested_mask=“r” denied_mask=“r” fsuid=0 ouid=0
[ 10.307604] audit: type=1400 audit(1576958588.993:26455): apparmor=“ALLOWED” operation=“open” profile=“init-systemd//null-/usr/lib/security-misc/permission-hardening//null-/usr/bin/find” name=“/usr/lib/python3/dist-packages/OpenGL/EGL/KHR/” pid=721 comm=“find” requested_mask=“r” denied_mask=“r” fsuid=0 ouid=0
[ 10.308072] audit: type=1400 audit(1576958588.993:26456): apparmor=“ALLOWED” operation=“open” profile=“init-systemd//null-/usr/lib/security-misc/permission-hardening//null-/usr/bin/find” name=“/usr/lib/python3/dist-packages/OpenGL/EGL/KHR/pycache/” pid=721 comm=“find” requested_mask=“r” denied_mask=“r” fsuid=0 ouid=0
[ 10.308764] audit: type=1400 audit(1576958588.993:26457): apparmor=“ALLOWED” operation=“open” profile=“init-systemd//null-/usr/lib/security-misc/permission-hardening//null-/usr/bin/find” name=“/usr/lib/python3/dist-packages/OpenGL/EGL/ANDROID/” pid=721 comm=“find” requested_mask=“r” denied_mask=“r” fsuid=0 ouid=0

1 Like

It shows every single thing apparmor allowed the program to access and when using a full system policy, it becomes a huge mess. The ALLOWED messages is the main reason why verbose boot takes so long.

They usually won’t be important so you can just exclude them with grep -v ALLOWED.

Permission hardening might need too many permissions and just bloat the shell script profile. It should probably get its own.

1 Like

Maybe displace would be better for this than str_replace.

1 Like
1 Like
1 Like
1 Like

Should /etc/rc*.d also be protected?

1 Like
1 Like

We’d also need to remove CAP_CHOWN so they can’t just do chown root -R /home and access the home directories.

1 Like

Quite a lot new profiles to review and test. :slight_smile: Thanks!

Due to the high the risk of regressions, I’ll set to apparmor complain mode for a few days or weeks (firewall, sdwdate)? That would simplify testing a lot. Then things could move to testers repository a lot faster which has been blocked from updating due to a lot recent hardening (mount options…).

Once all missing permissions are added these can be set to default (enforce mode).

This might generally be a good apparmor strategy. Confine new things in complain mode, mass deploy (stable repository) and then gather user reports.

If /dev/pts action is needed, also these other consoles /dev/tty and the Qubes specific one are required? Existing or new abstraction perhaps?

1 Like

That sounds like a good idea. I’ve tested all the new profiles and they work fine for me so there probably won’t be too many missing permissions.

I don’t think so. pts is the only one I got errors about.

A consoles abstraction already exists.

1 Like

Surely.

Users could install other init systems too and thereby break things? Is our approach of blacklisting things in /etc efficient? I think there are more malicious config options than we can image / research.

Not aae but VirusForget. Did you know $HOME/.pam_environment? Not popular but can be abused depending on threat model. Just an example.

What “legitimate” changes in /etc root should be able to do? Perhaps better restrict /etc/** or /** and then whitelist opt-in?

1 Like

Other init systems aren’t supported anyway. The profile only confines /lib/systemd/systemd.

A whitelist in /etc would be preferred but that would break all legitimate configuration which might cause too much breakage.

I don’t know what that is.

Code paths are some times different for gateway vs workstation and also Non-Qubes-Whonix vs Qubes-Whonix. Hard to foresee all cases. Quite a few issues for sdwdate profile. See sdwdate apparmor profile:

sdwdate and sdwdate-gui development thread - #363 by Patrick

Also networking Qubes works different.

1 Like

Oh. I only tested in in the Gateway on KVM. I forgot to test on other things.

Could you make that a drop-in instead please?

/lib/systemd/system/networking.service.d/30_apparmor_profile_everything.conf
and then change only what’s required to change:

[Service]
ExecStart=/sbin/networking up
ExecStop=/sbin/networking down

That saves a config-package-dev displace.

/sbin/networking maybe too unspecific? Perhaps better to use /sbin/networking-apparmor-everything or /sbin/networking-aae to make it more specific and clear for reviewers?

and license header.

Qubes-Whonix /lib/systemd/system/qubes-whonix-network.service uses Alias=networking.service thereby does not benefit from this. And Remove CAP_NET_ADMIN capability would break Qubes-Whonix networking /usr/lib/qubes-whonix/init/network-proxy-setup.

1 Like

Are you sure that would work? networking.service already has ExecStart and ExecStop options.

I can’t fix that since I don’t have Qubes. I doubt the script would work enough for me to create a profile for it.

1 Like

Did everything you asked.

https://github.com/madaidan/apparmor-profile-everything/blob/net_admin/lib/systemd/system/networking.service.d/30_apparmor_profile_everything.conf

https://github.com/madaidan/apparmor-profile-everything/blob/net_admin/sbin/networking-aae

1 Like

Yes. systemd drop-in support is amazing. Hard to ask for better features. It explicitly supports that use case. It supports to totally replace/overwrite existing keywords or expand these too.

Just noticed. I made a mistake. The actual syntax for a drop-in is this:

[Service]
ExecStart=
ExecStart=/sbin/networking up
ExecStop=
ExecStop=/sbin/networking down

The first ExecStart= tells systemd to clear all previous ExecStart keywords. Otherwise it would keep the existing one and only expand, i.e multiple ExecStart=.

1 Like