9.0 KiB
Contributing
You want to contribute to apparmor.d
, thank a lot for this. Feedbacks,
contributors, pull requests are all very welcome. You will find in this page all
the useful information needed to contribute.
How to contribute?
- If you don't have git on your machine, install it.
- Fork this repo by clicking on the fork button on the top of this page.
- Clone the repository and go to the directory:
git clone https://github.com/this-is-you/apparmor.d.git cd apparmor.d
- Create a branch:
git checkout -b my_contribution
- Make the changes and commit:
git add <files changed> git commit -m "A message for sum up my contribution"
- Push changes to GitHub:
git push origin my_contribution
- Submit your changes for review: If you go to your repository on GitHub, you'll see a Compare & pull request button, fill and submit the pull request.
Projects rules
A few rules:
- As these are mandatory access control policies only what it explicitly required should be authorized. Meaning, you should not allow everything (or a large area) and blacklist some sub area.
- A profile should not break a normal usage of the confined software. It can be complex as simply running the program for your own use case is not alway exhaustive of the program features and required permissions.
Add a profile
-
To add a new profile
foo
, add the filefoo
inapparmor.d/profile-a-f
. If your profile is part of a large group of profiles, it can also go inapparmor.d/groups
. -
Write the profile content, the rules depend of the confined program, Here is the bare minimum for the program
foo
:
# apparmor.d - Full set of apparmor profiles
# Copyright (C) 2022 You <your@email>
# SPDX-License-Identifier: GPL-2.0-only
abi <abi/3.0>,
include <tunables/global>
@{exec_path} = /{usr/,}bin/foo
profile foo @{exec_path} {
include <abstractions/base>
@{exec_path} mr,
include if exists <local/foo>
}
-
You can automatically set the complain flag on your profile by editing the file
dists/flags/main.flags
and adding a new line with:foo complain
-
Build & install for your distribution.
Profile Guidelines
A common structure
AppArmor profiles can be written without any specific guidelines. However, when you work with over 1200 profiles, you need a common structure among all the profiles.
The logic behind it is that if a rule is present in a profile, it should only be in one place, making profile review easier.
For example, if a program needs to run executables binary. The rules allowing it
can only be in a specific rule block (just after the @{exec_path} mr,
rule). It
is therefore easy to ensure some profile features such as:
- A profile has access to a given resource
- A profile enforces a strict write xor execute (W^X) policy.
It also improves compatibilities and makes personalization easier thanks to the use of more variables
Guidelines
Note
: This profile guideline is still evolving, feel free to propose improvment as long as it does not vary too much from the existing rules.
In order to ensure a common structure across the profiles, all new profile should try to follow the guideline presented here.
The rules in the profile should be sorted in rule block as follow:
- include
- set rlimit
- capability
- network
- mount
- remount
- umount
- pivot_root
- change_profile
- signal
- ptrace
- unix
- dbus
- file
- Local include
This rule order is taken from AppArmor with minor changes as we tend to:
- Divide the file block in multiple sub categories
- Put the block with the longer rules (files, dbus) after the other blocks
The file block
Try to sort the file rules as follow:
@{exec_path} mr
, the entry point of the profile- The binaries and library required:
/{usr/,}bin/
,/{usr/,}lib/
,/opt/
... It is the only place where you can havemr
,rix
,rPx
,rUx
,rPUX
rules. - The shared resources:
/usr/share
... - The system configuration:
/etc
... - The system data:
/var
... - The user data:
owner @{HOME}/
... - The user configuration, cache and in general all dotfiles
- Temporary and runtime data:
/tmp/
,@{run}/
,/dev/shm/
... - Sys files:
@{sys}/
... - Proc files:
@{PROC}/
... - Dev files:
/dev/
... - Deny rules:
deny
...
The dbus block
Try to sort the dbus rules as follow:
- The system bus should be sorted before the session bus
- The bind rules should be sorred after the send & receive rules
For DBus, try to determine peer's label when possible. E.g.:
dbus send bus=session path=/org/freedesktop/DBus
interface=org.freedesktop.DBus
member={RequestName,ReleaseName}
peer=(name=org.freedesktop.DBus, label=dbus-daemon),
If there is no predictable label it can be omited.
Other rules
- Do not use:
/usr/lib
or/usr/bin
but/{usr/,}bin/
or/{usr/,}lib/
. - Do not use:
/usr/sbin
or/sbin
but/{usr/,}{s,}bin/
. - Always use the apparmor variables.
- In a rule block, the rule shall be alphabetically sorted.
- Subprofile should comes at the end of a profile.
- When some file access share similar purpose, they may be sorted together. Eg:
/etc/machine-id r, /var/lib/dbus/machine-id r,
The included tool aa-log
can be useful to explore the apparmor log
Abstractions
This project and the apparmor profile official project provide a large selection of abstractions to be included in profiles. They should be used.
For instance, instead of writting:
owner @{HOME}/@{XDG_DOWNLOAD_DIR}/{,**} rw,
to allow download directory access, you should write
include <abstractions/user-download-strict>
AppArmor variables
Included variables:
@{PROC}=/proc/
@{run}=/run/ /var/run/
@{sys}=/sys/
- The home root:
@{HOMEDIRS}=/home/
- The home directories:
@{HOME}=@{HOMEDIRS}/*/ /root/
- Process id(s):
@{pid}
,@{pids}
- User id:
@{uid}
- Thread id:
@{tid}
- Classic XDG user directories:
- Desktop:
@{XDG_DESKTOP_DIR}="Desktop"
- Download:
@{XDG_DOWNLOAD_DIR}="Downloads"
- Templates:
@{XDG_TEMPLATES_DIR}="Templates"
- Public:
@{XDG_PUBLICSHARE_DIR}="Public"
- Documents:
@{XDG_DOCUMENTS_DIR}="Documents"
- Music:
@{XDG_MUSIC_DIR}="Music"
- Pictures:
@{XDG_PICTURES_DIR}="Pictures"
- Videos:
@{XDG_VIDEOS_DIR}="Videos"
- Desktop:
Additional variables available with this project:
- Libexec:
- On Archlinux:
@{libexec}=/{usr/,}lib
- On Debian/Ubuntu:
@{libexec}=/{usr/,}libexec
- On Archlinux:
- Mountpoints root:
@{MOUNTDIRS}=/media/ @{run}/media/ /mnt/
- Common mountpoints:
@{MOUNTS}=@{MOUNTDIRS}/*/
- Universally unique identifier:
@{uuid}=[0-9a-fA-F]*-[0-9a-fA-F]*-[0-9a-fA-F]*-[0-9a-fA-F]*-[0-9a-fA-F]*
- Hexadecimal:
@{hex}=[0-9a-fA-F]*
- Extended XDG user directories:
- Books:
@{XDG_BOOKS_DIR}="Books"
- Projects:
@{XDG_PROJECTS_DIR}="Projects"
- Screenshots:
@{XDG_SCREENSHOTS_DIR}="@{XDG_PICTURES_DIR}/Screenshots"
- Sync:
@{XDG_SYNC_DIR}="Sync"
- Torrents:
@{XDG_TORRENTS_DIR}="Torrents"
- Vm:
@{XDG_VM_DIR}=".vm"
- Wallpapers:
@{XDG_WALLPAPERS_DIR}="@{XDG_PICTURES_DIR}/Wallpapers"
- Books:
- Extended XDG dotfiles:
- SSH:
@{XDG_SSH_DIR}=".ssh"
- GPG:
@{XDG_GPG_DIR}=".gnupg"
- Cache:
@{XDG_CACHE_HOME}=".cache"
- Config:
@{XDG_CONFIG_HOME}=".config"
- Data:
@{XDG_DATA_HOME}=".local/share"
- Bin:
@{XDG_BIN_HOME}=".local/bin"
- Lib:
@{XDG_LIB_HOME}=".local/lib"
- SSH:
- Full path of the user configuration directories
- Cache:
@{user_cache_dirs}=@{HOME}/@{XDG_CACHE_HOME}
- Config:
@{user_config_dirs}=@{HOME}/@{XDG_CONFIG_HOME}
- Bin:
@{user_bin_dirs}=@{HOME}/@{XDG_BIN_HOME}
- Lib:
@{user_lib_dirs}=@{HOME}/@{XDG_LIB_HOME}
- Cache:
- Full path user directories
- Books:
@{user_books_dirs}=@{HOME}/@{XDG_BOOKS_DIR} @{MOUNTS}/@{XDG_BOOKS_DIR}
- Documents:
@{user_documents_dirs}=@{HOME}/@{XDG_DOCUMENTS_DIR} @{MOUNTS}/@{XDG_DOCUMENTS_DIR}
- Download:
@{user_download_dirs}=@{HOME}/@{XDG_DOWNLOAD_DIR} @{MOUNTS}/@{XDG_DOWNLOAD_DIR}
- Music:
@{user_music_dirs}=@{HOME}/@{XDG_MUSIC_DIR} @{MOUNTS}/@{XDG_MUSIC_DIR}
- Pictures:
@{user_pictures_dirs}=@{HOME}/@{XDG_PICTURES_DIR} @{MOUNTS}/@{XDG_PICTURES_DIR}
- Projects:
@{user_projects_dirs}=@{HOME}/@{XDG_PROJECTS_DIR} @{MOUNTS}/@{XDG_PROJECTS_DIR}
- Public:
@{user_publicshare_dirs}=@{HOME}/@{XDG_PUBLICSHARE_DIR} @{MOUNTS}/@{XDG_PUBLICSHARE_DIR}
- Sync:
@{user_sync_dirs}=@{HOME}/@{XDG_SYNC_DIR} @{MOUNTS}/*/@{XDG_SYNC_DIR}
- Templates:
@{user_templates_dirs}=@{HOME}/@{XDG_TEMPLATES_DIR} @{MOUNTS}/@{XDG_TEMPLATES_DIR}
- Torrents:
@{user_torrents_dirs}=@{HOME}/@{XDG_TORRENTS_DIR} @{MOUNTS}/@{XDG_TORRENTS_DIR}
- Videos:
@{user_videos_dirs}=@{HOME}/@{XDG_VIDEOS_DIR} @{MOUNTS}/@{XDG_VIDEOS_DIR}
- Vm:
@{user_vm_dirs}=@{HOME}/@{XDG_VM_DIR} @{MOUNTS}/@{XDG_VM_DIR}
- Books: