https://github.com/oddlama/elewrap
🥙 Controlled static privilege escalation utility with baked-in authentication rules. The most restrictive and lightweight replacement for sudo, doas or please.
https://github.com/oddlama/elewrap
authentication doas please privilege-escalation sudo
Last synced: 4 months ago
JSON representation
🥙 Controlled static privilege escalation utility with baked-in authentication rules. The most restrictive and lightweight replacement for sudo, doas or please.
- Host: GitHub
- URL: https://github.com/oddlama/elewrap
- Owner: oddlama
- License: mit
- Created: 2023-07-02T15:34:07.000Z (over 2 years ago)
- Default Branch: main
- Last Pushed: 2024-11-24T00:31:41.000Z (about 1 year ago)
- Last Synced: 2025-04-09T16:53:56.346Z (10 months ago)
- Topics: authentication, doas, please, privilege-escalation, sudo
- Language: Nix
- Homepage:
- Size: 50.8 KB
- Stars: 19
- Watchers: 3
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
[Building](#building) \| [Installation and Usage](#installation-and-usage-on-nixos) \| [Module options](#%EF%B8%8F-module-options)
## 🥙 Elewrap
This is a tiny setuid wrapper program allowing for controlled elevation of privileges,
similar to sudo, doas or please but with significantly less complexity and no dynamic configuration.
The authentication rules are kept simple and will be baked in at compile-time,
cutting down any attack surface to the absolute bare minimum.
- 🔐 All authentication rules will be baked in.
- ❄️ Provides a NixOS module to easily declare wrappers using elewrap to get rid of sudo.
- 🌱 Tiny and simple program that is easy to audit. [See for yourself](./src/main.rs).
## Building
You can build an elewrap wrapper simply by cloning this repository and running cargo build:
```bash
# Export variables (see below)
$ cargo build
```
To set the authentication rules and target command, you will have to export
some environment variables before building. These variables are available:
| Variable | Type | Default | Description |
|---|---|---|---|
`ELEWRAP_TARGET_USER` | Required | - | The target user to change to before executing the command.
`ELEWRAP_TARGET_COMMAND` | Required | - | The command to execute after changing to the target user. The executable path be absolute. The given string will be split on configured delimiter to allow defining arguments.
`ELEWRAP_TARGET_COMMAND_DELIMITER` | Optional | `"\t"` | The delimiter on which to split the target command.
`ELEWRAP_TARGET_COMMAND_SHA512` | Optional | Unset | If set, authenticates the target binary based on its sha512 hash before executing it.
`ELEWRAP_ALLOWED_USERS` | Optional | Unset (empty list) | A comma separated list of users for which to allow elevation of privileges using this utility. Leave unset for an empty list.
`ELEWRAP_ALLOWED_GROUPS` | Optional | Unset (empty list) | A comma separated list of groups for which to allow elevation of privileges using this utility. Leave unset for an empty list.
`ELEWRAP_PASS_ENVIRONMENT` | Optional | Unset (empty list) | A comma separated list of environment variables which should be allowed to be passed to the target command.
`ELEWRAP_PASS_ARGUMENTS` | Optional | `false` | Whether any additional runtime arguments should be appended to the executed command.
Afterwards, it is recommended to rename the executable to be able to identify the target command in case several wrappers are built.
The ownership of the resulting executable must then be given to `root:root` and the setuid bit must
be set. Ideally, set the permissions `4001` to allow execution by anyone while denying any read or write attempts.
## Installation and Usage on NixOS
This project's flake.nix exposes a module to simplify usage on NixOS.
To use it, add elewrap to your own `flake.nix` and use the module in your nixos system configurations.
```nix
{
inputs = {
nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
elewrap.url = "github:oddlama/elewrap";
elewrap.inputs.nixpkgs.follows = "nixpkgs";
};
outputs = { self, nixpkgs, elewrap }: {
# Add the module to your system(s)
nixosConfigurations.yourhostname = nixpkgs.lib.nixosSystem {
system = "x86_64-linux";
modules = [
./configuration.nix
elewrap.nixosModules.default
];
};
};
}
```
If you use a preinitialized `pkgs` package set, make sure to add `elewrap.overlays.default` to your overlays.
Lets say you now want to allow `telegraf` to run `sensors` with elevated permissions.
This is achieved simply by defining a new wrapper for the target executable in `security.elewrap` and
pointing telegraf to the new executable.
```nix
{ config, ... }: {
# Define a new wrapper to elevate privileges, refer to the module
# options for more information about the options.
security.elewrap.sensors = {
# We already specify the necessary parameters here
# and (by default) ignore any arguments passed at runtime
command = ["${pkgs.lm_sensors}/bin/sensors" "-A" "-u"];
# Run as root
targetUser = "root";
# Only allow telegraf to elevate privileges
allowedUsers = ["telegraf"];
};
# Set the path for the sensors executable to the resulting wrapper
services.telegraf.extraConfig.inputs.sensors.path = config.security.elewrap.sensors.path;
}
```
## ❄️ Module options
## `security.elewrap`
Transparently wraps programs to allow controlled elevation of privileges.
Like sudo, doas or please but the authentication rules are kept simple and will
be baked into the wrapper at compile-time, cutting down any attack surface
to the absolute bare minimum.
## `security.elewrap..path`
| Type | `str` |
|---------|-----|
The resulting wrapper that may be executed by the allowed users and groups
to run the given command with elevated permissions.
## `security.elewrap..command`
| Type | `listOf (either str path)` |
|---------|-----|
| Example | `["${pkgs.lm_sensors}/bin/sensors"]` |
The command that is executed after elevating privileges.
May include arguments. The first element (the executable) must be a path.
## `security.elewrap..targetUser`
| Type | `str` |
|---------|-----|
| Example | `"root"` |
The user to change to before executing the command.
## `security.elewrap..allowedUsers`
| Type | `listOf str` |
|---------|-----|
| Default | `[]` |
| Example | `["user1" "user2"]` |
The users allowed to execute this wrapper.
## `security.elewrap..allowedGroups`
| Type | `listOf str` |
|---------|-----|
| Default | `[]` |
| Example | `["group1" "group2"]` |
The groups allowed to execute this wrapper.
## `security.elewrap..passEnvironment`
| Type | `listOf str` |
|---------|-----|
| Default | `[]` |
| Example | `["SOME_ALLOWED_VAR"]` |
The environment variables in this list will be allowed to be passed
to the target command. Anything else will be erased.
## `security.elewrap..passArguments`
| Type | `listOf str` |
|---------|-----|
| Default | `false` |
Whether any given arguments should be appended to the target command.
This will be added to any static arguments given in the command, if any.
## `security.elewrap..verifySha512`
| Type | `listOf str` |
|---------|-----|
| Default | `true` |
Whether to verify the sha512 of the target executable at runtime before executing it.