Skip to content

Commit

Permalink
Merge pull request #3116 from Bravo555/docs/tedge-write
Browse files Browse the repository at this point in the history
docs: Add tedge-write documentation page
  • Loading branch information
Bravo555 authored Sep 18, 2024
2 parents 61fdb06 + 8adcbc7 commit a4a57ae
Show file tree
Hide file tree
Showing 4 changed files with 88 additions and 5 deletions.
9 changes: 5 additions & 4 deletions crates/core/tedge_write/src/bin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,13 @@ use camino::Utf8PathBuf;
use clap::Parser;
use tedge_utils::atomic::MaybePermissions;

/// A binary used for writing to files which `tedge` user does not have write permissions for, using
/// sudo.
/// tee-like helper for writing to files which `tedge` user does not have write permissions to.
///
/// To be used in combination with sudo, passing the file content via standard input.
#[derive(Debug, Clone, PartialEq, Eq, Parser)]
#[command(about, version, long_about = None)]
#[command(about, version, long_about)]
pub struct Args {
/// A canonical path to a file which will be written to.
/// A canonical path to a file to which standard input will be written.
///
/// If the file does not exist, it will be created with the specified owner/group/permissions.
/// If the file does exist, it will be overwritten, but its owner/group/permissions will remain
Expand Down
5 changes: 4 additions & 1 deletion crates/core/tedge_write/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,10 @@
//! - an implementation of the `tedge-write` binary
//! - tedge-write API meant to be called by other tedge-components
//!
//! https://github.com/thin-edge/thin-edge.io/issues/2456
//! # References
//!
//! - https://github.com/thin-edge/thin-edge.io/issues/2456
//! - docs/src/references/tedge-write.md

const TEDGE_WRITE_BINARY: &str = "tedge-write";

Expand Down
2 changes: 2 additions & 0 deletions docs/src/references/agent/tedge-configuration-management.md
Original file line number Diff line number Diff line change
Expand Up @@ -216,6 +216,8 @@ Upon receiving a configuration update command, the agent performs the following
1. It performs a `GET` request to the `tedgeUrl` specified in the command to retrieve the content.
2. The agent then uses the `type` information (`mosquitto`) to to look up the target path from the `tedge-configuration-plugin.toml` file
and applies the new configuration content to the corresponding `path`(`/etc/mosquitto/mosquitto.conf`).
If `tedge` user/group does not have write permissions to the path and its parent directory,
[`tedge-write`](../tedge-write.md) will be used in combination with `sudo` for permission elevation.

Throughout the process, the agent updates the command status via MQTT
by publishing a retained message to the same `<root>/<identifier>/cmd/config_update/<id>` topic
Expand Down
77 changes: 77 additions & 0 deletions docs/src/references/tedge-write.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
---
title: tedge-write
tags: [Reference, Configuration, CLI]
description: Granting thin-edge write access to protected files
---

**tedge-write** is a `tee`-like helper %%te%% component used by **tedge-agent** for privilege elevation.

tedge-agent spawns a `tedge-write` process when it needs to write to files that `tedge`
user/group has no write permissions to (e.g. system files or files owned by other packages), for
example when writing an updated configuration file as part of [`config_update` operation][1].
`tedge-agent` will first try to write to a file directly and only retry using `tedge-write` if
direct write fails due to `tedge` user/group not having write permissions to either the file itself
or its parent directory.

[1]: agent/tedge-configuration-management.md#handling-config-update-commands

## Permission elevation

`tedge-write` relies on `sudo` to grant the process write and execute permissions to the target
file's parent directory.

For example, when using following `sudoers` entry:

```sudoers title="file: /etc/sudoers.d/tedge"
tedge ALL = (ALL) NOPASSWD: /usr/bin/tedge-write /etc/*
```

Permissions are granted when:

- calling user is `tedge`
- binary is `/usr/bin/tedge-write`
- the 1st argument is `/etc/*`, i.e. the files `tedge-write` will be writing to are inside `/etc`

The entry grants privileges without authentication, which is required when `tedge-write` is spawned
by `tedge-agent`.


:::note

When %%te%% is installed using any one of the standard installation methods, the sudoers entry is
automatically created under `/etc/sudoers.d/tedge`, but in non-standard setups the sudoers
configuration may need to be updated manually.

Feel free to customise the sudoers entry according to your requirements, but make sure the entry
correctly grants privileges to all required files and a full and valid path to `tedge-write` binary
is used.

See [`sudoers(5)`][2] for additional details.

:::

[2]: https://www.man7.org/linux/man-pages/man5/sudoers.5.html

If you prefer to disable this permission elevation mechanism or don't want to use `sudo`, set the
tedge config `sudo.enable` setting to `false`. `tedge-write` will still get spawned, but without
`sudo`.

```sh
sudo tedge config set sudo.enable false
```

## Details

Write permission to the parent directory is required to guarantee config updates are atomic.


While updating a file, `tedge-write` will perform an atomic write, i.e. it will write to a temporary
file, set file ownership and mode, and finally rename the temporary into the final file.
If the target file already exists, its original ownership/mode will be preserved and optionally
provided new values will be ignored.


## Command help

```sh command="tedge-write --help" title="tedge-write --help"
```

0 comments on commit a4a57ae

Please sign in to comment.