Skip to content

Commit

Permalink
chore: Update dependencies and refactor code structure
Browse files Browse the repository at this point in the history
  • Loading branch information
LeChatP committed Sep 12, 2024
1 parent 20d6410 commit cf219a6
Show file tree
Hide file tree
Showing 19 changed files with 422 additions and 126 deletions.
11 changes: 10 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -109,8 +109,13 @@ section = "admin"
priority = "optional"
assets = [
["target/release/sr", "usr/bin/sr", "0555"],
["target/release/chsr", "usr/bin/chsr", "0555"]
["target/release/chsr", "usr/bin/chsr", "0555"],
["target/man/sr.8.gz", "usr/share/man/man8/sr.8.gz", "0644"],
["target/man/chsr.8.gz", "usr/share/man/man8/chsr.8.gz", "0644"],
["target/man/fr/sr.8.gz", "usr/share/man/fr/man8/sr.8.gz", "0644"],
["target/man/fr/chsr.8.gz", "usr/share/man/fr/man8/chsr.8.gz", "0644"]
]
preserve-symlinks = true
conf-files = ["/etc/pam.d/sr", "/etc/security/rootasrole.json"]
maintainer-scripts = "target/release/"
extended-description = "RootAsRole is a project to allow Linux/Unix administrators to delegate their administrative tasks access rights to multiple co-administrators through RBAC model and Linux Capabilities features."
Expand All @@ -121,6 +126,10 @@ assets = [
{ source = "target/release/chsr", dest = "/usr/bin/chsr", user = "root", group = "root", mode = "0555" },
{ source = "resources/rh/rh_sr_pam.conf", dest = "/etc/pam.d/sr", user = "root", group = "root", mode = "0644", config = true },
{ source = "resources/rootasrole.json", dest = "/etc/security/rootasrole.json", user = "root", group = "root", mode = "0644", config = true },
{ source = "target/man/sr.8.gz", dest = "/usr/share/man/man8/sr.8.gz", user = "root", group = "root", mode = "0644", doc = true },
{ source = "target/man/chsr.8.gz", dest = "/usr/share/man/man8/chsr.8.gz" , user = "root", group = "root", mode = "0644", doc = true },
{ source = "target/man/fr/sr.8.gz", dest = "/usr/share/man/fr/man8/sr.8.gz", user = "root", group = "root", mode = "0644", doc = true },
{ source = "target/man/fr/chsr.8.gz", dest = "/usr/share/man/fr/man8/chsr.8.gz", user = "root", group = "root", mode = "0644", doc = true }
]
post_install_script = "resources/rh/postinst.sh"
post_install_script_prog = [ "/bin/sh", "-c" ]
Expand Down
13 changes: 13 additions & 0 deletions book/src/HISTORY.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# HISTORY

## 1.0.0 (August 2018)

RootAsRole initiated by SIERA IRIT CNRS research team with Ahmad Samer WASAN as owner of the proof of concept. It is presented for the first time at "Le capitole du libre" in Toulouse. A paper is published%%cite{wazanRootAsRoleSecureAlternative2021}.

## 2.0.0 (August 2019)

RootAsRole is still a proof of concept but now proposes an eBPF subprogram to obtain the capabilities of a generic command. A paper is published at Computer and Security%%cite{wazanRootAsRoleSecurityModule2022}.

## 3.0.0 (September 2024)

RootAsRole direction is delegated to Eddie BILLOIR, a SIERA PhD student that contributed to the project all along its courses. It is now entirely rewritten in Rust, the eBPF subprogram is now in a separate project called RootAsRole-capable. The project takes a new direction and aims to be production ready with a massive reconception of every tools, a new configuration file format and complete documentation.
1 change: 1 addition & 0 deletions book/src/SUMMARY.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
# Summary

[Introduction](README.md)
[History](HISTORY.md)

# User Guide

Expand Down
94 changes: 94 additions & 0 deletions resources/man/en_US.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
% RootAsRole(8) System Manager's Manual
% Version 3.0.0
% September 2024

# NAME
RootAsRole - An alternative to sudo/su commands that adheres to the principle of least privilege and provides more secure memory management.

# SYNOPSIS
- **sr** [__OPTIONS__] [__COMMAND__]...
- **chsr** [__ARGUMENTS__]

**chsr**'s arguments follow a grammar available at <https://github.com/LeChatP/RootAsRole/tree/main/src/chsr/cli/cli.pest>

# DESCRIPTION
**RootAsRole** is a tool for administrators that provides a structured role-based access control (RBAC) system to delegate administrative tasks and access rights. It specifically supports __Linux capabilities(7)__ to minimize user privileges.

The Role-Based Access Control (RBAC) model is based on sets of permissions assigned to users or groups. In RootAsRole, a role is a set of administrative tasks assigned to users. Tasks are commands with specific rights. Rights can include changing the user, changing the group, or/and using Linux capabilities.

The **sr** command allows the execution of commands using a role. It requires a command to be executed as a mandatory parameter. It is also possible to specify a role and a task to select.

There are cases where several tasks correspond to a user's command input. In such cases, sr will select the most precise and least privileged task. The notion of precision is based on how closely the RootAsRole policy matches the user's command. The more the user's profile matches the policy, the higher the level of precision. The same applies to the precision of the user's command compared to its specification in the policy. Similarly, the task with fewer privileges will be prioritized over a task with higher privileges, but only if the tasks are equally precise. Despite this intelligent selection, confusion can still arise, and an error message will be returned.

Example of a confusion case: Two roles are assigned in the same way to a user, and among these roles, two tasks are entirely equivalent, but the configured environment variable are different for these two tasks. In this case, sr will display the error message "Permission denied" and log a warning that configuration must be fixed. This case should not happen if administrators are using **chsr**, the configuration tool.

It is possible to change the user's prompt using the **-p** option. It is also possible to view the executor's rights using the **-i** option. The displayed information is very limited for the user. Otherwise, administrator can use **chsr** to obtain the complete policy.

The **chsr** command is used to configure RootAsRole and its access control policy. It allows configuring roles, tasks, and permissions. The configuration is stored in the **/etc/security/rootasrole.json** file. If the file system supports it, the file is made immutable, requiring the CAP_LINUX_IMMUTABLE privilege to use **chsr**. The default RootAsRole policy grants to the installer the possibility to use **chsr** with the necessary privileges.

The storage mode of the access control policy can be configured. By default, RootAsRole uses a JSON file. It is possible to change the storage mode by manually modifying the **/etc/security/rootasrole.json** file.

Regarding authentication, RootAsRole uses Pluggable Authentication Module (PAM). The **/etc/pam.d/sr** file can be configured to change authentication behavior.

The core of RootAsRole implements RBAC-0, a simplified version of RBAC. By default, it adds features in the form of plugins to implement certain RBAC-1 functionalities. RBAC-0 simply implements roles, tasks, and permissions. Plugins add role hierarchy and separation of duties. Plugins can only be implemented directly in the project. Another plugin allows testing the checksum of executed files.

# OPTIONS

**\-r, --role** &lt;ROLE&gt;
Choose a specific role.



**\-t, --task** &lt;TASK&gt;
Choose a specific task within a role (requires --role)


**\-p, --prompt** &lt;PROMPT&gt;
Prompt to display when authenticating.


**\-i, --info**
Display rights of the executor. Information displayed is very limited.


**\-h, --help**
Print help (see more with '--help')


**\-v, --version**
Print version information

# EXAMPLES

**sr reboot**
Execute the reboot command (if the policy allows it).

**sr -r dac chmod 644 /etc/foo/bar**
Execute the command chmod 644 /etc/foo/bar with the role dac (if the policy has a dac role and a task that allows the chmod command).

# HISTORY

You can find the history of RootAsRole in the website <https://lechatp.github.io/HISTORY.html>.

# SECURITY RISKS

RootAsRole is a security tool that can give a user full control of the system. An administrator can write an access control policy that gives too many privileges to a user. A Perl-compatible regular expression (pcre2) library is very complex and may accept unexpected special characters.

It can be challenging to determine the necessary privileges for a command. For this, you can use the "capable" tool available at <https://github.com/LeChatP/RootAsRole-capable/> to determine the required capabilities for a command. However, this tool might give too many capabilities. It is recommended to verify if the capabilities are truly necessary, as in most cases, they are not. It is discouraged to use "capable" in production, as it is only for testing purposes.

# SUPPORT

For help, please visit <https://github.com/LeChatP/RootAsRole/discussions> or <https://github.com/LeChatP/RootAsRole/issues> if you find a bug.

# DISCLAIMER

This program is provided "as is" without any warranty, to the extent permitted by law. The authors disclaim any responsibility for the quality or suitability of the program for a particular purpose. You use this program at your own risk. In case of problems, you are responsible for any necessary repairs or corrections. For more details, please refer to the GNU GPL version 3 or later <https://gnu.org/licenses/gpl.html>.

# AUTHOR
This manual was written by Eddie BILLOIR <[email protected]>

# LICENSE
GPLv3+: GNU GPL version 3 or later <https://gnu.org/licenses/gpl.html>.

# SEE ALSO
Linux capabilities(7), sudo(8), su(1)
84 changes: 84 additions & 0 deletions resources/man/fr_FR.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
% RootAsRole(8) Manuel de l'administrateur système
% Version 3.0.0
% Septembre 2024

# NAME
RootAsRole - Une alternative pour les commandes sudo/su respectant le principe du moindre privilège et une gestion de la mémoire plus sécurisée.

# SYNOPSIS
- **sr** [__OPTIONS__] [__COMMAND__]...
- **chsr** [__ARGUMENTS__]
Les arguments suivent une grammaire disponible dans le code source à l'adresse <https://github.com/LeChatP/RootAsRole/tree/main/src/chsr/cli/cli.pest>

# DESCRIPTION
**RootAsRole** est un outil pour les administrateurs qui fournit un système structuré de contrôle d'accès basé sur les rôles (RBAC) pour déléguer les tâches administratives et les droits d'accès. Il prend notamment en charge les __Linux capabilities(7)__ pour minimiser les privilèges des utilisateurs.

Le modèle de Roles Based Access Control (RBAC) est basé sur des ensembles de permissions assignées à des utilisateurs ou des groupes. Pour RootAsRole, un rôle est un ensemble de tâches administratives assignées à des utilisateurs. Les tâches sont des commandes avec des droits à utiliser. Les droits peuvent être un changement d'utilisateur, un changement de groupe ou/et des Linux capabilities.

La commande **sr** permet d'exécuter des commandes en utilisant un rôle. Il prends en paramètre obligatoire une commande à exécuter. Il est également possible de spécifier un rôle et une tâche à sélectionner.

Il existe des cas où deux tâches correspondent à la commande d'un utilisateur. Dans ce cas, sr va sélectionner la tâche la plus précise et la moins privilégiée. La notion de précision est basée sur la précision de la politique RootAsRole comparée à l'occurence de la commande utilisateur. Plus le profil utilisateur et correspond à la politique, plus le niveau de précision est élevé. Il en est de même pour la précision de la commande de l'utilisateur vis-à-vis de sa spécification dans la politique. Pareillement, moins les droits sont élevés pour une tâche, plus la tâche sera prioritaire par rapport à une autre tâche. Le cas de la tâche moins privilégié n'est qu'uniquement si les tâches sont déjà avec le même niveau de précision. Malgré cette sélection intelligente, il reste des cas de confusion, ceux-ci renvoient un message d'erreur.

Exemple d'un cas de confusion : Deux rôles sont assignés de la même manière à un utilisateur, parmi ces rôles, deux tâches sont totalement équivalentes mais les variables d'environment sont différents. Dans ce cas, sr affiche le message d'erreur "Permission denied" et fais un message warning dans les logs.

Il est possible de changer le prompt de l'utilisateur en utilisant l'option **-p**. Il est également possible de voir les droits de l'exécuteur en utilisant l'option **-i**. Les informations affichées sont très limitées.

La commande **chsr** sert à configurer RootAsRole et sa politique de contrôle d'accès. Elle permet de configurer les rôles, les tâches et les permissions. La configuration est stockée dans le fichier **/etc/security/rootasrole.json**. Si le système de fichier le permet, le fichier est rendu immuable, il faut alors le privilège CAP_LINUX_IMMUTABLE pour utiliser **chsr**. Pour cela, la politique par défaut de RootAsRole donne la permission à l'installateur d'utiliser **chsr** avec les privilèges nécessaires.

Il est possible de configurer le mode de stockage de la politique de contrôle d'accès. Par défaut, RootAsRole utilise un fichier JSON. Il est possible de changer le mode de stockage en modifiant manuellement le fichier **/etc/security/rootasrole.json**.

Concernant l'authentification, RootAsRole utilise PAM. Il est possible de configurer le fichier **/etc/pam.d/sr** pour changer le comportement de l'authentification.

Le coeur de RootAsRole implémente RBAC-0, une version simplifiée de RBAC. Par défaut il ajoute des fonctionnalités sous forme de plugins pour implémenter certaines fonctionnalités de RBAC-1. RBAC-0 implémente simplement les rôles, les tâches et les permissions. Les plugins ajoutent la hiérarchie de rôles et séparation des devoirs. Les plugins sont uniquement implémentable directement dans le projet. Il y a également un autre plugin qui permet de tester la somme de contrôle des fichiers exécutés.



# OPTIONS

- **\-r, --role** <ROLE>
Role to select
- **\-t, --task** <TASK>
Task to select (--role required)
- **\-p, --prompt** <PROMPT>
Prompt to display
- **\-i, --info**
Display rights of executor
- **\-h, --help**
Print help (see more with '--help')
- **\-V, --version**
Print version information

# EXAMPLES

- **sr reboot**
Execute the command reboot. (If the policy is defined and allowed as well)

- **sr -r dac chmod 644 /etc/foo/bar**
Execute the command chmod 644 /etc/foo/bar with the role dac (If the policy has a role dac and a task that allows chmod command)

# HISTORIQUE

Vous pouvez trouver l'historique de RootAsRole sur le site web <https://lechatp.github.io/RootAsRole/HISTORY.html>.

# RISQUES DE SÉCURITÉ

RootAsRole est un outil de sécurité qui peut donner le contrôle complet du système à un utilisateur. Un administrateur peut écrire une politique de contrôle d'accès qui donne des droits trop élevés à un utilisateur. Une expression régulière perl (pcre2) est une librairie très complexe et peut accepter des caractères spéciaux inattendus.

Il peut être difficile de déterminer les droits nécessaire pour une commande. Pour cela, il est possible d'utiliser l'outil "capable" disponible sur <https://github.com/LeChatP/RootAsRole-capable/> pour déterminer les capabilities nécessaires pour une commande. Cependant, il est également possible que cette commande donne trop de capabilities. Il est donc recommandé de vérifier si les capabilities sont bien nécessaires car dans la plupart des cas, les capabilities ne sont pas nécessaires. Il est fortement déconseillé d'utiliser cet outil en production.

# SUPPORT

Pour obtenir de l'aide, veuillez consulter <https://github.com/LeChatP/RootAsRole/discussions> ou <https://github.com/LeChatP/RootAsRole/issues> si vous avez trouvé un bogue.

# CLAUSE DE NON-RESPONSABILITÉ

Ce programme est fourni « en l'état », sans aucune garantie, dans la limite permise par la loi. Les auteurs déclinent toute responsabilité quant à la qualité ou l'adéquation du programme à un usage particulier. Vous utilisez ce programme à vos propres risques. En cas de problème, vous êtes responsable des réparations ou corrections nécessaires. Pour plus de détails, veuillez consulter la licence GNU GPL version 3 ou ultérieure <https://gnu.org/licenses/gpl.html>.

# AUTEUR
Ce manuel a été écrit par Eddie BILLOIR <[email protected]>

# LICENCE
License GPLv3+: GNU GPL version 3 or later <https://gnu.org/licenses/gpl.html>.

# VOIR AUSSI
Linux capabilities(7), sudo(8), su(1)
22 changes: 10 additions & 12 deletions xtask/src/configure.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,15 +34,13 @@ fn is_running_in_container() -> bool {
// Check cgroups for container-specific patterns
if let Ok(file) = File::open("/proc/1/cgroup") {
let reader = io::BufReader::new(file);
for line in reader.lines() {
if let Ok(line) = line {
if line.contains("docker")
|| line.contains("kubepods")
|| line.contains("lxc")
|| line.contains("containerd")
{
return true;
}
for line in reader.lines().map_while(Result::ok) {
if line.contains("docker")
|| line.contains("kubepods")
|| line.contains("lxc")
|| line.contains("containerd")
{
return true;
}
}
}
Expand Down Expand Up @@ -226,7 +224,7 @@ fn retrieve_real_user() -> Result<Option<nix::unistd::User>, anyhow::Error> {
if let Ok(sudo_user) = env::var("SUDO_USER") {
let user =
nix::unistd::User::from_name(&sudo_user).context("Failed to get the sudo user")?;
return Ok(user);
Ok(user)
} else {
let ruid = getresuid()?.real;
let user = nix::unistd::User::from_uid(ruid).context("Failed to get the real user")?;
Expand Down Expand Up @@ -257,9 +255,9 @@ pub fn configure(os: Option<OsTarget>) -> Result<(), anyhow::Error> {
os
} else {
OsTarget::detect()
.and_then(|t| {
.map(|t| {
info!("Detected OS is : {}", t);
Ok(t)
t
})
.context("Failed to detect the OS")?
};
Expand Down
14 changes: 7 additions & 7 deletions xtask/src/deploy/debian.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use std::process::{Command, ExitStatus};
use anyhow::Context;

use crate::{
install::{self, dependencies::install_dependencies, InstallDependenciesOptions, Profile},
installer::{self, dependencies::install_dependencies, InstallDependenciesOptions, Profile},
util::{detect_priv_bin, get_os, OsTarget},
};

Expand All @@ -19,20 +19,20 @@ pub fn make_deb(
priv_bin: &Option<String>,
) -> Result<(), anyhow::Error> {
let os = get_os(os)?;
let priv_bin = priv_bin.clone().or(detect_priv_bin());
dependencies(&os, priv_bin.clone())?;

dependencies(&os, priv_bin.clone().or(detect_priv_bin()))?;

install::dependencies(InstallDependenciesOptions {
installer::dependencies(InstallDependenciesOptions {
os: Some(os),
install_dependencies: true,
dev: true,
priv_bin: priv_bin.clone(),
})?;
install::build(&install::BuildOptions {
installer::build(&installer::BuildOptions {
profile,
toolchain: install::Toolchain::default(),
toolchain: installer::Toolchain::default(),
clean_before: false,
privbin: Some("sudo".to_string()),
privbin: priv_bin,
})?;
setup_maint_scripts()?;

Expand Down
2 changes: 1 addition & 1 deletion xtask/src/deploy/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use std::{collections::HashSet, process::Command};

use clap::Parser;

use crate::{install::Profile, util::OsTarget};
use crate::{installer::Profile, util::OsTarget};

mod debian;
mod redhat;
Expand Down
Loading

0 comments on commit cf219a6

Please sign in to comment.