Skip to content

Workflow

Workflow to write profiles

Add a blank profile

  1. To add a new profile foo, add the file foo in apparmor.d/profile-a-f. If your profile is part of a large group of profiles, it can also go in apparmor.d/groups.

  2. Write the profile content, the rules depend on the confined program, Here is the bare minimum for the program foo:

    # apparmor.d - Full set of apparmor profiles
    # Copyright (C) 2024 You <your@email>
    # SPDX-License-Identifier: GPL-2.0-only
    
    abi <abi/4.0>,
    
    include <tunables/global>
    
    @{exec_path} = @{bin}/foo
    profile foo @{exec_path} {
      include <abstractions/base>
    
      @{exec_path} mr,
    
      include if exists <local/foo>
    }
    
    # vim:syntax=apparmor
    

Development Install

It is not recommended installing the full project "manually" (with make, sudo make install). The distribution specific packages are intended to be used in development as they include additional rule to ensure compatibility with upstream (see debian/, PKGBUILD and dists/apparmor.d.spec).

Instead, install an individual profile or the development package, the following way.

Development package

make pkg
make dpkg
make dpkg
make rpm

For any system with docker installed you can simply build the package with:

make package dist=<distribution>

Then you can install the package with dpkg, pacman or rpm.

Individual profile

Format

make dev name=<profile-name>
Exampe

Testing the profile pass

make dev name=pass

This:

  • Prebuild the pass profile in complain mode to .build,
  • Install the profile to /etc/apparmor.d/
  • Load the profile by restarting the AppArmor service.

More advanced development, like editing the abstractions or working over multiple profiles at the same time requires installing the full development package.

For this individual profile installation to work, the full package needs to be installed, regardless of the installation method (dev or stable).

Program Profiling

Workflow

To discover the access needed by a program, you can use the following tools:

  1. Star the program in complain mode, let it initialize itself, then close it.

  2. Run aa-log -r. It will:

    • Convert the logs to AppArmor rules.
    • Detect if flags such as attach_disconnected are needed.
    • Convert all common paths to variables.
  3. From aa-log output, you can:

    • Copy the rules to the profile.
    • Replace some rules with abstractions as 80% of the rules should already be covered by an abstraction.
  4. Then, update the profile and start the program again. Use the program as you would normally do, but also try to run all the features of the program, e.g.: open the help, settings, etc.

  5. Run aa-log. Stop the program as long as you get over 100 new rules. Add the rules to the profile.

After 2 or 3 iterations, you should have a working profile.

Recommendations

Warning

Following the profile guidelines is mandatory for all profiles. PRs that do not follow the guidelines will not get merged.

Tools

  • aa-notify is a tool that will allow you to get notified on every apparmor log.

  • aa-logprof is another tool that will help you to generate a profile from logs. However, the logs generated by aa-logprof need to be rewritten to comply with the profile guidelines.

  • aa-complain, aa-enforce are tools to quickly change the mode of a profile.

Development Settings

Profile flags

Flags for all profiles in this project are tracked under the dists/flags directory. It is used for profile that are not considered stable. Files in this directory should respect the following format: <profile> <flags>, flags should be comma separated.

For instance, to move adb in complain mode, edit dists/flags/main.flags and add the following line:

adb complain

Beware, flags defined in this file overwrite flags in the profile. So you may need to add other flags. Example for gnome-shell:

gnome-shell attach_disconnected,mediate_deleted,complain

Ignore profiles

It can be handy to not install a profile for a given distribution. Profiles and directories to ignore are tracked under the dists/ignore directory. Files in this directory should respect the following format: <profile or path>. One ignore by line. It can be a profile name or a directory to ignore (relative to the project root).