docs: initial documentation website.
This commit is contained in:
parent
3c3f164e91
commit
ecf82c7176
17 changed files with 1143 additions and 0 deletions
128
docs/development/guidelines.md
Normal file
128
docs/development/guidelines.md
Normal file
|
|
@ -0,0 +1,128 @@
|
|||
---
|
||||
title: Guidelines
|
||||
---
|
||||
|
||||
## Common structure
|
||||
|
||||
AppArmor profiles can be written without any specific guidelines. However,
|
||||
when you work with over 1400 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 improvement
|
||||
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 **must**
|
||||
follow the guidelines 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 subcategories
|
||||
- Put the block with the longer rules (`files`, `dbus`) after the other blocks
|
||||
|
||||
### The file blocks
|
||||
|
||||
The file block should be sorted 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 have `mr`, `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
|
||||
|
||||
|
||||
The dbus block should be sorted as follow:
|
||||
|
||||
- The system bus should be sorted *before* the session bus
|
||||
- The bind rules should be sorted *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 omitted.
|
||||
|
||||
### Profiles rules
|
||||
|
||||
`bin, sbin & lib`
|
||||
|
||||
: - 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/`.
|
||||
|
||||
`Variables`
|
||||
|
||||
: Always use the apparmor variables.
|
||||
|
||||
`Sort`
|
||||
|
||||
: In a rule block, the rule shall be alphabetically sorted.
|
||||
|
||||
`Sub profile`
|
||||
|
||||
: Sub profile should comes at the end of a profile.
|
||||
|
||||
`Similar purpose`
|
||||
|
||||
: When some file access share similar purpose, they may be sorted together. Eg:
|
||||
```
|
||||
/etc/machine-id r,
|
||||
/var/lib/dbus/machine-id r,
|
||||
```
|
||||
|
||||
|
||||
## Additional recommended documentation
|
||||
|
||||
* [The AppArmor Core Policy Reference](https://gitlab.com/apparmor/apparmor/-/wikis/AppArmor_Core_Policy_Reference)
|
||||
* [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
|
||||
99
docs/development/index.md
Normal file
99
docs/development/index.md
Normal file
|
|
@ -0,0 +1,99 @@
|
|||
---
|
||||
title: Development
|
||||
---
|
||||
|
||||
# Development
|
||||
|
||||
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.
|
||||
|
||||
??? info "How to contribute"
|
||||
|
||||
1. If you don't have git on your machine, [install it][git].
|
||||
2. Fork this repo by clicking on the fork button on the top of this page.
|
||||
3. Clone the repository and go to the directory:
|
||||
```sh
|
||||
git clone https://github.com/this-is-you/apparmor.d.git
|
||||
cd apparmor.d
|
||||
```
|
||||
4. Create a branch:
|
||||
```
|
||||
git checkout -b my_contribution
|
||||
```
|
||||
5. Make the changes and commit:
|
||||
```
|
||||
git add <files changed>
|
||||
git commit -m "A message for sum up my contribution"
|
||||
```
|
||||
6. Push changes to GitHub:
|
||||
```
|
||||
git push origin my_contribution
|
||||
```
|
||||
7. 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.
|
||||
|
||||
|
||||
## Project rules
|
||||
|
||||
`Rule 1: Mandatory Access Control`
|
||||
|
||||
: 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 areas.
|
||||
|
||||
`Rule 2: Do not break a program`
|
||||
|
||||
: 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 always
|
||||
exhaustive of the program features and required permissions.
|
||||
|
||||
`Rule 3: Do not confine everything`
|
||||
|
||||
: Some programs should not be confined by a MAC policy.
|
||||
|
||||
|
||||
|
||||
## Add a profile
|
||||
|
||||
!!! danger "Warning"
|
||||
|
||||
Following the [profile guidelines](guidelines) 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 of the confined program,
|
||||
Here is the bare minimum for the program `foo`:
|
||||
``` sh
|
||||
# apparmor.d - Full set of apparmor profiles
|
||||
# Copyright (C) 2023 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>
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
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.
|
||||
|
||||
|
||||
[git]: https://help.github.com/articles/set-up-git/
|
||||
|
||||
[flags]: https://github.com/roddhjav/apparmor.d/blob/master/dists/flags/main.flags
|
||||
[profiles-a-f]: https://github.com/roddhjav/apparmor.d/blob/master/apparmor.d/profiles-a-f
|
||||
[groups]: https://github.com/roddhjav/apparmor.d/blob/master/apparmor.d/groups
|
||||
173
docs/development/structure.md
Normal file
173
docs/development/structure.md
Normal file
|
|
@ -0,0 +1,173 @@
|
|||
---
|
||||
title: Structure
|
||||
---
|
||||
|
||||
Description of common structure found across various AppArmor profiles
|
||||
|
||||
|
||||
## Program to not confine
|
||||
|
||||
Some programs should not be confined by themselves. For example, tools such as
|
||||
`ls`, `rm`, `diff` or `cat` do not have profile 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 theater.
|
||||
|
||||
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 are not required?
|
||||
3. This breaks the principle of mandatory access control.
|
||||
See the [first rule of this project][project-rules] that 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: `/{,usr/}bin/diff rPx,` 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 {
|
||||
```
|
||||
|
||||
* In `pass`, as it is a dependency of pass. Here `diff` inherit pass profile
|
||||
and has the same access than the pass profile, so it will be allowed to diff
|
||||
password files because more than a generic `diff` it is a `diff` 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"
|
||||
/{usr/,}bin/diff rix,
|
||||
```
|
||||
|
||||
**What if I still want to protect these programs?**
|
||||
|
||||
You do not protect this program. *Protect the usage you have of these tools*.
|
||||
In practice, it means that you should put your development's terminal in a
|
||||
sandbox managed with [Toolbox]
|
||||
|
||||
!!! example "To sum up"
|
||||
|
||||
1. Do not create profile for programs such as: `rm`, `ls`, `diff`, `cd`, `cat`
|
||||
2. Do not create profile for the shell: `bash`, `sh`, `dash`, `zsh`
|
||||
3. Use [Toolbox].
|
||||
|
||||
[project-rules]: /development/#project-rules
|
||||
[Toolbox]: https://containertoolbx.org/
|
||||
|
||||
|
||||
|
||||
## 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, to allow download directory access, instead of writing:
|
||||
```sh
|
||||
owner @{HOME}/@{XDG_DOWNLOAD_DIR}/{,**} rw,
|
||||
```
|
||||
|
||||
You should write:
|
||||
```sh
|
||||
include <abstractions/user-download-strict>
|
||||
```
|
||||
|
||||
|
||||
## 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/master/apparmor.d/groups/children
|
||||
|
||||
Here is an overview of the current children profile:
|
||||
|
||||
1. **`child-open`**: To opens resources. Instead of allowing the run of all
|
||||
software in `/{usr/,}bin/`, the purpose of this profile is to list all GUI
|
||||
program 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.
|
||||
|
||||
2. **`child-pager`**: Simple access to pager such as `pager`, `less` and `more`.
|
||||
This profile supposes 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 some as sometime 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/15e33a1fe6654f67a187cd5157c9968061b9511e/apparmor.d/groups/virt/libvirtd#L179-L184)
|
||||
``` aa linenums="179"
|
||||
@{run}/udev/data/c23[4-9]:[0-9]* r, # For dynamic assignment range 234 to 254
|
||||
@{run}/udev/data/c24[0-9]:[0-9]* r,
|
||||
@{run}/udev/data/c25[0-4]:[0-9]* r,
|
||||
@{run}/udev/data/c3[0-9]*:[0-9]* r, # For dynamic assignment range 384 to 511
|
||||
@{run}/udev/data/c4[0-9]*:[0-9]* r,
|
||||
@{run}/udev/data/c5[0-9]*:[0-9]* r,
|
||||
```
|
||||
|
||||
[kernel]: https://raw.githubusercontent.com/torvalds/linux/master/Documentation/admin-guide/devices.txt
|
||||
|
||||
|
||||
## Full system policy
|
||||
|
||||
!!! quote
|
||||
|
||||
AppArmor is also capable of being used for full system policy
|
||||
where processes are by default not running under the `unconfined`
|
||||
profile. This might be useful for high security environments or
|
||||
embedded systems.
|
||||
|
||||
*Source: [AppArmor Wiki][apparmor-wiki]*
|
||||
|
||||
This feature is only enabled when the `--full` option is passed to
|
||||
the `configure` script. The profiles for full system policies are maintained in
|
||||
the **[`_full`][_full]** group. It consists of two extra main profiles:
|
||||
|
||||
1. **`init`**: For systemd as PID 1
|
||||
2. **`systemd`**: For systemd as user
|
||||
|
||||
All core required applications that need to be started by systemd (both as user
|
||||
or root) need to be present in these profiles.
|
||||
|
||||
!!! danger
|
||||
|
||||
Full system policy is still under early development, do not run it outside a
|
||||
development VM! **You have been warned!!!**
|
||||
|
||||
|
||||
[apparmor-wiki]: https://gitlab.com/apparmor/apparmor/-/wikis/FullSystemPolicy
|
||||
[_full]: https://github.com/roddhjav/apparmor.d/blob/master/apparmor.d/groups/_full
|
||||
Loading…
Add table
Add a link
Reference in a new issue