docs: add development workflow.

This commit is contained in:
Alexandre Pujol 2024-10-02 01:08:06 +01:00
parent baad12a754
commit 9112c6466d
No known key found for this signature in database
GPG Key ID: C5469996F0DF68EC
13 changed files with 514 additions and 275 deletions

View File

@ -1,3 +1,5 @@
*[MAC]: Mandatory Access Control
*[W^X]: Write XOR Execute
*[FSP]: Full System Policy
*[AppArmor tunables]: AppArmor global variables

View File

@ -181,9 +181,9 @@ All profiles use the variables defined above. Therefore, you can personalize the
@{user_pkg_dirs}+=@{user_cache_dirs}/yay/
```
### Mountpoints
### Mount points
Common mountpoints are defined in the `@{MOUNTS}` variable. If you mount a disk on a different location, you can add it to the `@{MOUNTS}` variable.
Common mount points are defined in the `@{MOUNTS}` variable. If you mount a disk on a different location, you can add it to the `@{MOUNTS}` variable.
**Example**
@ -202,6 +202,6 @@ All supported file browsers (`nautilus`, `dolphin`, `thunar`) are configured to
### Games
In order to not allow access to user data, game profiles use the `@{XDG_GAMESSTUDIO_DIR}` variable. It may needs to be expanded with other game studio directory. The default is `@{XDG_GAMESSTUDIO_DIR}="unity3d"`.
In order to not allow access to user data, game profiles use the `@{XDG_GAMESSTUDIO_DIR}` variable. It may need to be expanded with other game studio directory. The default is `@{XDG_GAMESSTUDIO_DIR}="unity3d"`.
The `@{XDG_GAMES_DIR}` variable is used to define the game directory such as steam storage directory. If your steam storage is on another drive/mountpoint, you should personalize `@{user_games_dirs}` instead.
The `@{XDG_GAMES_DIR}` variable is used to define the game directory such as steam storage directory. If your steam storage is on another drive, you should personalize `@{user_games_dirs}` instead.

View File

@ -137,7 +137,8 @@ A minimal set of rules for profiles including internal `pkexec`. Like `app/sudo`
### **`app/systemctl`**
An alternative solution for [child-systemctl](structure.md#children-profiles), when the child profile provides too much/not enough access. This abstraction should be used by a sub profile as follows:
An alternative solution for [child-systemctl](internal.md#children-profiles), when the child profile provides too much/not enough access. This abstraction should be used by a sub profile as follows:
```sh
@{bin}/systemctl rCx -> systemctl,

View File

@ -11,7 +11,7 @@ The logic behind it is that if a rule is present in a profile, it should only be
For example, if a program needs to run executable binaries then 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.
* A profile enforces a strict [write xor execute](https://en.wikipedia.org/wiki/W%5EX) (W^X) policy.
It also improves compatibilities and makes personalization easier thanks to the use of more variables.
@ -132,14 +132,3 @@ If there is no predictable label it can be omitted.
```
Does not help, and if generalized it would add a lot of complexity to any profiles.
## Additional recommended documentation
* [The AppArmor Core Policy Reference](https://gitlab.com/apparmor/apparmor/-/wikis/AppArmor_Core_Policy_Reference)
* [The openSUSE Documentation](https://doc.opensuse.org/documentation/leap/security/html/book-security/part-apparmor.html)
* https://documentation.suse.com/sles/12-SP5/html/SLES-all/cha-apparmor-intro.html
* [The AppArmor.d man page](https://man.archlinux.org/man/apparmor.d.5)
* [F**k AppArmor](https://presentations.nordisch.org/apparmor/#/)
* [A Brief Tour of Linux Security Modules](https://www.starlab.io/blog/a-brief-tour-of-linux-security-modules)
[write xor execute]: https://en.wikipedia.org/wiki/W%5EX

View File

@ -4,31 +4,38 @@ title: Development
If you're looking to contribute to `apparmor.d` you can get started by going to the project [GitHub repository](https://github.com/roddhjav/apparmor.d/)! All contributions are welcome no matter how small. In this page you will find all the useful information needed to contribute to the apparmor.d project.
??? info "How to contribute pull requests"
??? info "How to contribute pull requests?"
1. If you don't have git on your machine, [install it](https://help.github.com/articles/set-up-git/).
2. Fork this repo by clicking on the fork button on the top of the [project GitHub][project] page.
3. Clone the forked repository and go to the directory:
1. Fork this repo by clicking on the fork button on the top of the [project GitHub](https://github.com/roddhjav/apparmor.d) page.
1. [Generate a new SSH key]( https://docs.github.com/en/authentication/connecting-to-github-with-ssh/generating-a-new-ssh-key-and-adding-it-to-the-ssh-agent) and add it to your GitHub account.
1. Clone the forked repository and go to the directory:
```sh
git clone https://github.com/your-github-username/apparmor.d.git
git clone git@github.com:your-github-username/apparmor.d.git
cd apparmor.d
```
4. Create a branch:
1. Create a branch:
```
git checkout -b my_contribution
```
5. Make the changes and commit:
1. Make the changes and commit:
```
git add <files changed>
git commit -m "A message to sum up my contribution"
```
6. Push changes to GitHub:
1. Push changes to GitHub:
```
git push origin my_contribution
```
7. Submit your changes for review: If you go to your repository on GitHub,
1. 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.
<div class="grid cards" markdown>
- :material-arrow-right: &nbsp; **[See the workflow to write profiles](workflow.md)**
</div>
## Project rules
@ -55,48 +62,11 @@ If you're looking to contribute to `apparmor.d` you can get started by going to
your devices or for your use case.
## Add a profile
## Additional recommended documentation
!!! danger "Warning"
Following the [profile guidelines](guidelines.md) is **mandatory** for all new profiles.
1. To add a new profile `foo`, add the file `foo` in [`apparmor.d/profile-a-f`][profiles-a-f].
If your profile is part of a large group of profiles, it can also go in
[`apparmor.d/groups`][groups].
2. Write the profile content, the rules depend on the confined program,
Here is the bare minimum for the program `foo`:
``` sh
# apparmor.d - Full set of apparmor profiles
# Copyright (C) 2024 You <your@email>
# SPDX-License-Identifier: GPL-2.0-only
abi <abi/3.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
```
3. You can automatically set the `complain` flag on your profile by editing the file [`dists/flags/main.flags`][flags] and add a new line with: `foo complain`
4. Build & install for your distribution.
[project]: https://github.com/roddhjav/apparmor.d
[flags]: https://github.com/roddhjav/apparmor.d/blob/main/dists/flags/main.flags
[profiles-a-f]: https://github.com/roddhjav/apparmor.d/blob/main/apparmor.d/profiles-a-f
[groups]: https://github.com/roddhjav/apparmor.d/blob/main/apparmor.d/groups
* [The AppArmor Core Policy Reference](https://gitlab.com/apparmor/apparmor/-/wikis/AppArmor_Core_Policy_Reference)
* [The openSUSE Documentation](https://doc.opensuse.org/documentation/leap/security/html/book-security/part-apparmor.html)
* https://documentation.suse.com/sles/12-SP5/html/SLES-all/cha-apparmor-intro.html
* [The AppArmor.d man page](https://man.archlinux.org/man/apparmor.d.5)
* [F**k AppArmor](https://presentations.nordisch.org/apparmor/#/)
* [A Brief Tour of Linux Security Modules](https://www.starlab.io/blog/a-brief-tour-of-linux-security-modules)

View File

@ -1,66 +0,0 @@
---
title: Installation
---
## Development Install
!!! warning
Do **not** install this 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. You have been warned!
See `debian/`, `PKGBUILD` and `dists/apparmor.d.spec`.
=== ":material-arch: Archlinux"
```sh
make pkg
```
=== ":material-ubuntu: Ubuntu"
```sh
make dpkg
```
=== ":material-debian: Debian"
```sh
make dpkg
```
=== ":simple-suse: openSUSE"
```sh
make rpm
```
=== ":material-docker: Docker"
For any system with docker installed you can simply build the package with:
```sh
make package dist=<distribution>
```
Then you can install the package with `dpkg`, `pacman` or `rpm`.
## Profile flags
Flags for all profiles in this project are tracked under the [`dists/flags`](https://github.com/roddhjav/apparmor.d/tree/main/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`](https://github.com/roddhjav/apparmor.d/blob/main/dists/flags/main.flags)** and add the following line:
```sh
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`:
```sh
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`](https://github.com/roddhjav/apparmor.d/tree/main/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).

View File

@ -74,7 +74,7 @@ All the images come pre-configured with the latest version of `apparmor.d` insta
**Usage**
On all images, `aa-update` can be used to rebuild and install the latest version of the profiles. `p`, `pf`, and `pu` are two preconfigured aliases of `ps` that show the security status of processes. `htop` is also configured to show this status.
On all images, `aa-update` can be used to rebuild and install the latest version of the profiles. `p`, `pf`, and `pu` are two pre-configured aliases of `ps` that show the security status of processes. `htop` is also configured to show this status.
## Tests
@ -118,7 +118,7 @@ Start the tests and collect the results
**Tests manifest**
A basic set of test is generated on initialisation. More tests can be manually written in yaml file. They must have the following structure:
A basic set of test is generated on initialization. More tests can be manually written in yaml file. They must have the following structure:
```yaml
- name: acpi

View File

@ -0,0 +1,203 @@
---
title: Internal
---
## Profile Context
These are context helper to be used for in sub profile, they aim at providing a minimal set of rules for a given program. The calling profile only needs to add rules dependant of its use case.
See [abstractions/app](abstractions.md#context-helper) for more information.
## Open Resources
The standard way to allow opening resources such as URL, pictures, video, in this project is to use one of the `child-open` profile available in the [`children`](https://github.com/roddhjav/apparmor.d/blob/main/apparmor.d/groups/children) group.
**Example:**
```sh
@{open_path} rPx -> child-open,
```
### Manual
Directly using any of the following:
- `@{bin}/* PUx,`
- `include <abstractions/app-launcher-user>`
- `include <abstractions/app-launcher-root>`
Allow every installed program to be started from the current program with or without profile. This is a very permissive rule and should be avoided if possible. They are however legitimately needed for program launcher.
### **`child-open`**
Instead of allowing the ability to run all software in `@{bin}/`, the purpose of this profile is to list all GUI programs that can open resources. Ultimately, only sandbox manager programs such as `bwrap`, `snap`, `flatpak`, `firejail` should be present here. Until this day, this profile will be a controlled mess.
??? quote "[children/child-open](https://github.com/roddhjav/apparmor.d/blob/main/apparmor.d/groups/children/child-open)"
``` aa
# Sandbox managers
@{bin}/bwrap rPUx,
@{bin}/firejail rPUx,
@{bin}/flatpak rPx,
@{bin}/snap rPx,
# Labeled programs
@{archive_viewers_path} rPUx,
@{browsers_path} rPx,
@{document_viewers_path} rPUx,
@{emails_path} rPUx,
@{file_explorers_path} rPx,
@{help_path} rPx,
@{image_viewers_path} rPUx,
@{offices_path} rPUx,
@{text_editors_path} rPUx,
# Others
@{bin}/blueman-tray rPx,
@{bin}/discord{,-ptb} rPx,
@{bin}/draw.io rPUx,
@{bin}/dropbox rPx,
@{bin}/element-desktop rPx,
@{bin}/extension-manager rPx,
@{bin}/filezilla rPx,
@{bin}/flameshot rPx,
@{bin}/gimp* rPUx,
@{bin}/gnome-calculator rPUx,
@{bin}/gnome-disk-image-mounter rPx,
@{bin}/gnome-disks rPx,
@{bin}/gnome-software rPx,
@{bin}/gwenview rPUx,
@{bin}/kgx rPx,
@{bin}/qbittorrent rPx,
@{bin}/qpdfview rPx,
@{bin}/smplayer rPx,
@{bin}/steam-runtime rPUx,
@{bin}/telegram-desktop rPx,
@{bin}/transmission-gtk rPx,
@{bin}/viewnior rPUx,
@{bin}/vlc rPUx,
@{bin}/xbrlapi rPx,
# Backup
@{lib}/deja-dup/deja-dup-monitor rPx,
@{browsers_path} rPx,
@{help_path} rPx,
```
### **`child-open-browsers`**
This version of child-open only allow to open browsers.
??? quote "[children/child-open-browsers](https://github.com/roddhjav/apparmor.d/blob/main/apparmor.d/groups/children/child-open-browsers)"
``` aa
@{browsers_path} rPx,
```
### **`child-open-help`**
This version of child-open only allow to open browsers and help programs.
??? quote "[children/child-open-help](https://github.com/roddhjav/apparmor.d/blob/main/apparmor.d/groups/children/child-open-help)"
``` aa
@{browsers_path} rPx,
@{help_path} rPx,
```
### **`child-open-strict`**
This version of child-open only allow to open browsers & folders:
??? quote "[children/child-open-strict](https://github.com/roddhjav/apparmor.d/blob/main/apparmor.d/groups/children/child-open-strict)"
``` aa
@{browsers_path} Px,
@{file_explorers_path} Px,
```
!!! warning
Although needed to not break a program, wrongly used these profiles can lead to confinment escape.
## Children profiles
Usually, a child profile is in the [`children`](https://github.com/roddhjav/apparmor.d/blob/main/apparmor.d/groups/children) group. They have the following note:
!!! quote
Note: This profile does not specify an attachment path because it is intended to be used only via `"Px -> child-open"` exec transitions from other profiles.
<!-- ### **`child-dpkg`**
### **`child-dpkg-divert`** -->
### **`child-modprove-nvidia`**
Used internally by the `nvidia` abstraction.
### **`child-pager`**
Simple access to pagers such as `pager`, `less` and `more`. This profile assumes the pager is reading its data from stdin, not from a file on disk. Supported pagers are: `sensible-pager`, `pager`, `less`, and `more`.
It can be as follows in a profile:
```
@{pager_path} rPx -> child-pager,
```
### **`child-systemctl`**
Common `systemctl` action. Do not use it too much as most of the time you will need more privilege than what this profile is giving you.
It is recommended to transition [in a subprofile](abstractions.md#appsystemctl) everything that is not generic and that may require some access (so restart, enable...), while `child-systemctl` can handle the more basic tasks.
## User Confinement [:material-police-badge-outline:{ .pg-red }](../full-system-policy.md "Only for Full System Policy (FSP)")
!!! warning "TODO"
## No New Privileges
[**No New Privileges**](https://www.kernel.org/doc/html/latest/userspace-api/no_new_privs.html) is a flag preventing a newly started program to get more privileges than its parent process. This is a **good thing** for security. And it is commonly used in systemd unit files (when possible). This flag also prevents transitions to other profiles because it could be less restrictive than the parent profile (no `Px` or `Ux` allowed).
The possible solutions are:
* The easiest (and unfortunately less secure) workaround is to ensure the programs do not run with no new privileges flag by disabling `NoNewPrivileges` in the systemd unit (or any other [options implying it](https://man.archlinux.org/man/core/systemd/systemd.exec.5.en#SECURITY)).
* Inherit the current confinement (`ix`)
* [Stacking](#stacking)
## Stacking
[Stacking](https://gitlab.com/apparmor/apparmor/-/wikis/AppArmorStacking) of two or more profile is the strict intersection them. It is a way to ensure that a profile never becomes more permissive than the intersection of all profiles in the stack. It provides several abilities to the policy author:
- It can be used to ensure that confinement never becomes more permissive.
- To reduce the permissions of a generic profile on a specific task.
- To provide both system level and container and user level policy (when combined with policy namespaces).
!!! note ""
[apparmor.d/groups/browsers/chromium](https://github.com/roddhjav/apparmor.d/blob/b51576139b3ed3125aaa3ea4d737a77baac0f00e/apparmor.d/groups/browsers/chromium#L25)
``` aa linenums="23"
profile chromium @{exec_path} {
...
@{lib_dirs}/chrome_crashpad_handler rPx -> chromium//&chromium-crashpad-handler,
...
}
```
## Udev rules
See the **[kernel docs](https://raw.githubusercontent.com/torvalds/linux/master/Documentation/admin-guide/devices.txt)** to check the major block and char numbers used in `/run/udev/data/`.
Special care must be given as sometimes udev numbers are allocated dynamically by the kernel. Therefore, the full range must be allowed:
!!! note ""
[apparmor.d/groups/virt/libvirtd](https://github.com/roddhjav/apparmor.d/blob/b2af7a631a2b8aca7d6bdc8f7ff4fdd5ec94220e/apparmor.d/groups/virt/libvirtd#L188)
``` aa linenums="179"
@{run}/udev/data/c@{dynamic}:@{int} r, # For dynamic assignment range 234 to 254, 384 to 511
```

View File

@ -0,0 +1,78 @@
---
title: Recommendations
---
## Renaming of profiles
For security reason, once loaded into the kernel, a profile cannot get fully removed. Therefore, by renaming a profile, you create a second profile with the same attachment. AppArmor will not be able to determine witch one to use leading to breakage.
A reboot is required to fully remove the profile from the kernel.
## Programs to not confine
Some programs should not be confined by themselves. For example, tools such as `ls`, `rm`, `diff` or `cat` do not have profiles in this project. Let's see why.
These are general tools that in a general context can legitimately access any file in the system. Therefore, the confinement of such tools by a global profile would at best be minimal at worst be a security theatre.
It gets even worse. Let's say, we write a profile for `cat`. Such a profile would need access to `/etc/`. We will add the following rule:
```sh
/etc/{,**} rw,
```
However, as `/etc` can contain sensitive files, we now want to explicitly prevent access to these sensitive files. Problems:
1. How do we know the exhaustive list of *sensitive files* in `/etc`?
2. How do we ensure access to these sensitive files is not required?
3. This breaks the principle of mandatory access control.
See the [first rule of this project](index.md#project-rules) which is to only allow
what is required. Here we allow everything and blacklist some paths.
It creates even more issues when we want to use this profile in other profiles. Let's take the example of `diff`. Using this rule: `@{bin}/diff rPx,` this will restrict access to the very generic and not very confined `diff` profile. Whereas most of the time, we want to restrict `diff` to some specific file in our profile:
* In `dpkg`, an internal child profile (`rCx -> diff`), allows `diff` to only access etc config files:
!!! note ""
[apparmor.d/apparmor.d/groups/apt/dpkg](https://github.com/roddhjav/apparmor.d/blob/accf5538bdfc1598f1cc1588a7118252884df50c/apparmor.d/groups/apt/dpkg#L123)
``` aa linenums="123"
profile diff {
include <abstractions/base>
include <abstractions/consoles>
@{bin}/ r,
@{bin}/pager mr,
@{bin}/less mr,
@{bin}/more mr,
@{bin}/diff mr,
owner @{HOME}/.lesshs* rw,
# Diff changed config files
/etc/** r,
# For shell pwd
/root/ r,
}
```
* As it is a dependency of pass, `diff` inherits the `pass' profile and has the same access as the pass profile, so it will be allowed to diff password files because more than a generic `diff`, it is a `diff` "version" for the pass password manager:
!!! note ""
[apparmor.d/apparmor.d/profiles-m-r/pass](https://github.com/roddhjav/apparmor.d/blob/accf5538bdfc1598f1cc1588a7118252884df50c/apparmor.d/profiles-m-r/pass#L20
)
``` aa linenums="20"
@{bin}/diff rix,
```
**What if I still want to protect these programs?**
You do not protect these programs. *Protect the usage you have of these programs*. In practice, it means that you should put your terminal in a sandbox managed environment with a sandboxing tool such as Toolbox.
!!! example "To sum up"
1. Do not create a profile for programs such as: `rm`, `ls`, `diff`, `cd`, `cat`
2. Do not create a profile for the shell: `bash`, `sh`, `dash`, `zsh`
3. Use [Toolbox](https://containertoolbx.org/)

View File

@ -1,133 +0,0 @@
---
title: Structure
---
Description of common structure found across various AppArmor profiles
## Programs to not confine
Some programs should not be confined by themselves. For example, tools such as `ls`, `rm`, `diff` or `cat` do not have profiles in this project. Let's see why.
These are general tools that in a general context can legitimately access any file in the system. Therefore, the confinement of such tools by a global profile would at best be minimal at worst be a security theatre.
It gets even worse. Let's say, we write a profile for `cat`. Such a profile would need access to `/etc/`. We will add the following rule:
```sh
/etc/{,**} rw,
```
However, as `/etc` can contain sensitive files, we now want to explicitly prevent access to these sensitive files. Problems:
1. How do we know the exhaustive list of *sensitive files* in `/etc`?
2. How do we ensure access to these sensitive files is not required?
3. This breaks the principle of mandatory access control.
See the [first rule of this project](index.md#project-rules) which is to only allow
what is required. Here we allow everything and blacklist some paths.
It creates even more issues when we want to use this profile in other profiles. Let's take the example of `diff`. Using this rule: `@{bin}/diff rPx,` this will restrict access to the very generic and not very confined `diff` profile. Whereas most of the time, we want to restrict `diff` to some specific file in our profile:
* In `dpkg`, an internal child profile (`rCx -> diff`), allows `diff` to only access etc config files:
!!! note ""
[apparmor.d/apparmor.d/groups/apt/dpkg](https://github.com/roddhjav/apparmor.d/blob/accf5538bdfc1598f1cc1588a7118252884df50c/apparmor.d/groups/apt/dpkg#L123)
``` aa linenums="123"
profile diff {
include <abstractions/base>
include <abstractions/consoles>
@{bin}/ r,
@{bin}/pager mr,
@{bin}/less mr,
@{bin}/more mr,
@{bin}/diff mr,
owner @{HOME}/.lesshs* rw,
# Diff changed config files
/etc/** r,
# For shell pwd
/root/ r,
}
```
* As it is a dependency of pass, `diff` inherits the `pass' profile and has the same access as the pass profile, so it will be allowed to diff password files because more than a generic `diff`, it is a `diff` "version" for the pass password manager:
!!! note ""
[apparmor.d/apparmor.d/profiles-m-r/pass](https://github.com/roddhjav/apparmor.d/blob/accf5538bdfc1598f1cc1588a7118252884df50c/apparmor.d/profiles-m-r/pass#L20
)
``` aa linenums="20"
@{bin}/diff rix,
```
**What if I still want to protect these programs?**
You do not protect these programs. *Protect the usage you have of these programs*. In practice, it means that you should put your terminal in a sandbox managed environment with a sandboxing tool such as Toolbox.
!!! example "To sum up"
1. Do not create a profile for programs such as: `rm`, `ls`, `diff`, `cd`, `cat`
2. Do not create a profile for the shell: `bash`, `sh`, `dash`, `zsh`
3. Use [Toolbox].
[Toolbox]: https://containertoolbx.org/
## Open Resources
The standard way to allow opening resource in this project is to use one of the
child-open profile. Eg: `@{open_path} rPx -> child-open,`
They are available in the [`children`][children] group.
* **`child-open`**: Instead of allowing the ability to run all software in `@{bin}/`, the purpose of this profile is to list all GUI programs that can open resources. Ultimately, only sandbox manager programs such as `bwrap`, `snap`, `flatpak`, `firejail` should be present here. Until this day, this profile will be a controlled mess.
* **`child-open-browsers`**: This version of child-open only allow to open browsers.
* **`child-open-help`**: This version of child-open only allow to open browsers and help programs.
* **`child-open-strict`**: This version of child-open only allow to open browsers & folders.
## Children profiles
Usually, a child profile is in the [`children`][children] group. They have the following note:
!!! quote
Note: This profile does not specify an attachment path because it is intended to be used only via `"Px -> child-open"` exec transitions from other profiles.
[children]: https://github.com/roddhjav/apparmor.d/blob/main/apparmor.d/groups/children
Here is an overview of the current children profile:
2. **`child-pager`**: Simple access to pagers such as `pager`, `less` and `more`. This profile assumes the pager is reading its data from stdin, not from a file on disk.
3. **`child-systemctl`**: Common `systemctl` action. Do not use it too much as most of the time you will need more privilege than what this profile is giving you.
## Udev rules
See the **[kernel docs][kernel]** to check the major block and char numbers used in `/run/udev/data/`.
Special care must be given as sometimes udev numbers are allocated dynamically by the kernel. Therefore, the full range must be allowed:
!!! note ""
[apparmor.d/groups/virt/libvirtd](https://github.com/roddhjav/apparmor.d/blob/b2af7a631a2b8aca7d6bdc8f7ff4fdd5ec94220e/apparmor.d/groups/virt/libvirtd#L188)
``` aa linenums="179"
@{run}/udev/data/c@{dynamic}:@{int} r, # For dynamic assignment range 234 to 254, 384 to 511
```
[kernel]: https://raw.githubusercontent.com/torvalds/linux/master/Documentation/admin-guide/devices.txt
## No New Privileges
[**No New Privileges**](https://www.kernel.org/doc/html/latest/userspace-api/no_new_privs.html) is a flag preventing a newly started program to get more privileges than its parent process. This is a **good thing** for security. And it is commonly used in systemd unit files (when possible). This flag also prevents transitions to other profiles because it could be less restrictive than the parent profile (no `Px` or `Ux` allowed).
The possible solutions are:
* The easiest (and unfortunately less secure) workaround is to ensure the programs do not run with no new privileges flag by disabling `NoNewPrivileges` in the systemd unit (or any other [options implying it](https://man.archlinux.org/man/core/systemd/systemd.exec.5.en#SECURITY)).
* Inherit the current confinement (`ix`)
* [Stacking](https://gitlab.com/apparmor/apparmor/-/wikis/AppArmorStacking)

View File

@ -0,0 +1,195 @@
---
title: Workflow
---
**Workflow to write profiles**
<div class="grid cards" markdown>
- :material-file-document: &nbsp; **[Write a blanck profile](#add-a-blank-profile)**
</div>
<div class="grid cards" markdown>
- :material-download: &nbsp; **[Install the profile](#individual-profile)**
</div>
<div class="grid cards" markdown>
- :material-test-tube: &nbsp; **[Profile the program](#program-profiling)**
</div>
<div class="grid cards" markdown>
- :octicons-law-16: &nbsp; **[Respect the profile guidelines](guidelines.md)**
</div>
## Add a blank profile
1. To add a new profile `foo`, add the file `foo` in [`apparmor.d/profile-a-f`](https://github.com/roddhjav/apparmor.d/blob/main/apparmor.d/profiles-a-f).
If your profile is part of a large group of profiles, it can also go in
[`apparmor.d/groups`](https://github.com/roddhjav/apparmor.d/blob/main/apparmor.d/groups).
2. Write the profile content, the rules depend on the confined program,
Here is the bare minimum for the program `foo`:
``` sh
# apparmor.d - Full set of apparmor profiles
# Copyright (C) 2024 You <your@email>
# SPDX-License-Identifier: GPL-2.0-only
abi <abi/3.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
=== ":material-arch: Archlinux"
```sh
make pkg
```
=== ":material-ubuntu: Ubuntu"
```sh
make dpkg
```
=== ":material-debian: Debian"
```sh
make dpkg
```
=== ":simple-suse: openSUSE"
```sh
make rpm
```
=== ":material-docker: Docker"
For any system with docker installed you can simply build the package with:
```sh
make package dist=<distribution>
```
Then you can install the package with `dpkg`, `pacman` or `rpm`.
### Individual profile
**Format**
```sh
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](#development-package) or [stable](../install.md)).
## 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.
1. Run **[`aa-log -r`](../usage.md#apparmor-log)**. It will:
- Convert the logs to AppArmor rules.
- Detect if flags such as `attach_disconnected` are needed.
- Convert all common paths to **[variables](../variables.md)**.
1. From `aa-log` output, you can:
- Copy the rules to the profile.
- Replace some rules with **[abstractions](abstractions.md)** as 80% of the rules should already be covered by an abstraction.
1. Then, [update the profile](#individual-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.
1. Run **[`aa-log`](../usage.md#apparmor-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
<div class="grid cards" markdown>
- :material-function: &nbsp; **[Use the abstractions](abstractions.md)**
- :simple-files: &nbsp; **[Learn how to open resources](internal.md#open-resources)**
- :fontawesome-solid-bus-simple: &nbsp; **[Learn how Dbus rules are handled](dbus.md)**
- :material-sign-direction: &nbsp; **[Learn about directives `#aa:`](directives.md)**
- :octicons-law-16: &nbsp; **[Follow the profile guidelines](guidelines.md)**
- :octicons-light-bulb-16: &nbsp; **[See other recommendations](recommendations.md)**
</div>
!!! danger "Warning"
Following the [profile guidelines](guidelines.md) is **mandatory** for all profiles. PRs that do not follow the guidelines will not get merged.
### Tools
* **[aa-notify](https://wiki.archlinux.org/title/AppArmor#Get_desktop_notification_on_DENIED_actions)** is a tool that will allow you to get notified on every apparmor log.
* **[aa-logprof](https://man.archlinux.org/man/aa-logprof.8)** 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](guidelines.md).
* **[aa-complain](https://man.archlinux.org/man/aa-complain.8), 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`](https://github.com/roddhjav/apparmor.d/tree/main/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`](https://github.com/roddhjav/apparmor.d/blob/main/dists/flags/main.flags)** and add the following line:
```sh
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`:
```sh
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`](https://github.com/roddhjav/apparmor.d/tree/main/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).

View File

@ -131,7 +131,7 @@ To work as intended, userland services started by `systemd --user` **should** ha
!!! info
To be allowed to run, additional root or user services may need to add extra rules inside the `usr/systemd.d` or `usr/systemd-user.d` directory. For example, when installing a new privileged service `foo` with [stacking](development/structure.md#no-new-privileges) you may need to add the following to `/etc/apparmor.d/usr/systemd.d/foo`:
To be allowed to run, additional root or user services may need to add extra rules inside the `usr/systemd.d` or `usr/systemd-user.d` directory. For example, when installing a new privileged service `foo` with [stacking](development/internal.md#no-new-privileges) you may need to add the following to `/etc/apparmor.d/usr/systemd.d/foo`:
```
@{lib}/foo rPx -> systemd//&foo,
```

View File

@ -152,14 +152,14 @@ nav:
- recovery.md
- Development:
- development/index.md
- Architecture:
- development/install.md
- Profiles:
- development/workflow.md
- development/guidelines.md
- development/structure.md
- Profile:
- development/abstractions.md
- development/internal.md
- development/directives.md
- development/dbus.md
- development/recommendations.md
- Tests:
- development/tests.md
- development/integration.md