diff --git a/docs/abbreviations.md b/docs/abbreviations.md index f99a4f70c..32f567afe 100644 --- a/docs/abbreviations.md +++ b/docs/abbreviations.md @@ -1,3 +1,5 @@ *[MAC]: Mandatory Access Control +*[W^X]: Write XOR Execute +*[FSP]: Full System Policy *[AppArmor tunables]: AppArmor global variables diff --git a/docs/configuration.md b/docs/configuration.md index f2f1d3722..e3fbba5ea 100644 --- a/docs/configuration.md +++ b/docs/configuration.md @@ -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. diff --git a/docs/development/abstractions.md b/docs/development/abstractions.md index 5c6694684..9390945f8 100644 --- a/docs/development/abstractions.md +++ b/docs/development/abstractions.md @@ -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, diff --git a/docs/development/guidelines.md b/docs/development/guidelines.md index 3d83fea5f..f207e58a2 100644 --- a/docs/development/guidelines.md +++ b/docs/development/guidelines.md @@ -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 diff --git a/docs/development/index.md b/docs/development/index.md index c68745e26..2e12a466b 100644 --- a/docs/development/index.md +++ b/docs/development/index.md @@ -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 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. +
+ +- :material-arrow-right:   **[See the workflow to write profiles](workflow.md)** + +
+ ## 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 - -!!! 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 -# SPDX-License-Identifier: GPL-2.0-only - -abi , - -include - -@{exec_path} = @{bin}/foo -profile foo @{exec_path} { - include - - @{exec_path} mr, - - include if exists -} - -# 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 +## Additional recommended documentation -[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) diff --git a/docs/development/install.md b/docs/development/install.md deleted file mode 100644 index 6b1f47581..000000000 --- a/docs/development/install.md +++ /dev/null @@ -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= - ``` - - 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: ` `, 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: ``. One ignore by line. It can be a profile name or a directory to ignore (relative to the project root). diff --git a/docs/development/integration.md b/docs/development/integration.md index f829fb69f..1e5878aa0 100644 --- a/docs/development/integration.md +++ b/docs/development/integration.md @@ -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 diff --git a/docs/development/internal.md b/docs/development/internal.md new file mode 100644 index 000000000..c7dc4af14 --- /dev/null +++ b/docs/development/internal.md @@ -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 ` +- `include ` + +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-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 + ``` diff --git a/docs/development/recommendations.md b/docs/development/recommendations.md new file mode 100644 index 000000000..bbe41bc4e --- /dev/null +++ b/docs/development/recommendations.md @@ -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 + include + + @{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/) diff --git a/docs/development/structure.md b/docs/development/structure.md deleted file mode 100644 index c6b82e29f..000000000 --- a/docs/development/structure.md +++ /dev/null @@ -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 - include - - @{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) diff --git a/docs/development/workflow.md b/docs/development/workflow.md new file mode 100644 index 000000000..7455d97c7 --- /dev/null +++ b/docs/development/workflow.md @@ -0,0 +1,195 @@ +--- +title: Workflow +--- + +**Workflow to write profiles** + +
+ +- :material-file-document:   **[Write a blanck profile](#add-a-blank-profile)** + +
+
+ +- :material-download:   **[Install the profile](#individual-profile)** + +
+
+ +- :material-test-tube:   **[Profile the program](#program-profiling)** + +
+
+ +- :octicons-law-16:   **[Respect the profile guidelines](guidelines.md)** + +
+ + +## 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 +# SPDX-License-Identifier: GPL-2.0-only + +abi , + +include + +@{exec_path} = @{bin}/foo +profile foo @{exec_path} { + include + + @{exec_path} mr, + + include if exists +} + +# 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= + ``` + + Then you can install the package with `dpkg`, `pacman` or `rpm`. + +### Individual profile + +**Format** + +```sh +make dev 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 + +
+ +- :material-function:   **[Use the abstractions](abstractions.md)** +- :simple-files:   **[Learn how to open resources](internal.md#open-resources)** +- :fontawesome-solid-bus-simple:   **[Learn how Dbus rules are handled](dbus.md)** +- :material-sign-direction:   **[Learn about directives `#aa:`](directives.md)** +- :octicons-law-16:   **[Follow the profile guidelines](guidelines.md)** +- :octicons-light-bulb-16:   **[See other recommendations](recommendations.md)** + +
+ +!!! 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: ` `, 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: ``. One ignore by line. It can be a profile name or a directory to ignore (relative to the project root). diff --git a/docs/full-system-policy.md b/docs/full-system-policy.md index d37cf3071..80da55c2a 100644 --- a/docs/full-system-policy.md +++ b/docs/full-system-policy.md @@ -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, ``` diff --git a/mkdocs.yml b/mkdocs.yml index 689785a31..9390b3dde 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -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