mirror of
https://git.quad4.io/RNS-Things/MeshChatX.git
synced 2026-07-29 11:49:28 +00:00
Add documentation for running MeshChatX in Firejail and Bubblewrap sandboxes on Linux
This commit is contained in:
@@ -0,0 +1,164 @@
|
||||
# MeshChatX on Linux: Firejail and Bubblewrap
|
||||
|
||||
This page shows how to run `meshchat` under **Firejail** or **Bubblewrap** (`bwrap`) on Linux. Use this when you install MeshChatX natively (wheel, package, or Poetry) and want an extra layer of filesystem and process isolation compared to running the binary directly.
|
||||
|
||||
These tools do **not** replace a full virtual machine or hardware-enforced boundary. They reduce exposure of your home directory and other paths the process can write to, when you configure them with tight whitelists or bind mounts.
|
||||
|
||||
**Containers:** If you already run MeshChatX with Docker or Podman, that is a different isolation model; this document is aimed at **host-installed** `meshchat`.
|
||||
|
||||
## Prerequisites
|
||||
|
||||
Install one or both from your distribution:
|
||||
|
||||
- **Firejail:** package name is usually `firejail`.
|
||||
- **Bubblewrap:** package name is usually `bubblewrap`; the binary is `bwrap`.
|
||||
|
||||
You need a working `meshchat` on your `PATH` (for example after `pipx install`, `pip install --user`, or a distro package).
|
||||
|
||||
Pick a **dedicated data directory** for sandboxed runs so you do not mix permissions or policies with a non-sandboxed install. The examples below use:
|
||||
|
||||
```bash
|
||||
DATA="${XDG_DATA_HOME:-$HOME/.local/share}/meshchatx-sandbox"
|
||||
mkdir -p "$DATA/storage" "$DATA/.reticulum"
|
||||
```
|
||||
|
||||
Adjust paths if you prefer another location.
|
||||
|
||||
## Firejail
|
||||
|
||||
Firejail applies a profile (or defaults) on top of your command. For MeshChatX you typically want:
|
||||
|
||||
- **Network** left available so Reticulum and the web UI can work (do not use `--net=none` unless you know you need it).
|
||||
- **Writable** only your chosen data directory (and anything else the app truly needs).
|
||||
|
||||
### Installed `meshchat` (pip, pipx, or system package)
|
||||
|
||||
```bash
|
||||
DATA="${XDG_DATA_HOME:-$HOME/.local/share}/meshchatx-sandbox"
|
||||
mkdir -p "$DATA/storage" "$DATA/.reticulum"
|
||||
|
||||
firejail --quiet \
|
||||
--whitelist="$DATA" \
|
||||
meshchat --headless --host 127.0.0.1 \
|
||||
--storage-dir="$DATA/storage" \
|
||||
--reticulum-config-dir="$DATA/.reticulum"
|
||||
```
|
||||
|
||||
If the default profile blocks something MeshChatX needs, you can start from a looser base and tighten later, for example:
|
||||
|
||||
```bash
|
||||
firejail --noprofile --whitelist="$DATA" \
|
||||
meshchat --headless --host 127.0.0.1 \
|
||||
--storage-dir="$DATA/storage" \
|
||||
--reticulum-config-dir="$DATA/.reticulum"
|
||||
```
|
||||
|
||||
`--noprofile` disables many Firejail restrictions; treat it as a stepping stone, not the final hardening.
|
||||
|
||||
### From source with Poetry
|
||||
|
||||
Poetry needs the project tree and the virtualenv. Example:
|
||||
|
||||
```bash
|
||||
cd /path/to/reticulum-meshchatX
|
||||
DATA="${XDG_DATA_HOME:-$HOME/.local/share}/meshchatx-sandbox"
|
||||
VENV="$(poetry env info -p)"
|
||||
mkdir -p "$DATA/storage" "$DATA/.reticulum"
|
||||
|
||||
firejail --quiet \
|
||||
--whitelist="$(pwd)" \
|
||||
--whitelist="$VENV" \
|
||||
--whitelist="$DATA" \
|
||||
poetry run meshchat --headless --host 127.0.0.1 \
|
||||
--storage-dir="$DATA/storage" \
|
||||
--reticulum-config-dir="$DATA/.reticulum"
|
||||
```
|
||||
|
||||
You may need extra `--whitelist=` entries if Poetry or dependencies read config elsewhere (for example under `$HOME/.config`).
|
||||
|
||||
### USB serial (RNode or similar)
|
||||
|
||||
If Reticulum talks to a radio over a serial device, Firejail may need explicit access to TTY devices, for example:
|
||||
|
||||
```bash
|
||||
firejail --noblacklist=/dev/ttyACM0 --noblacklist=/dev/ttyUSB0 \
|
||||
...
|
||||
```
|
||||
|
||||
Use the device nodes your system actually exposes (`dmesg`, `ls /dev/tty*`).
|
||||
|
||||
## Bubblewrap (`bwrap`)
|
||||
|
||||
Bubblewrap does not ship profiles; you list every mount and option. The pattern below keeps the **whole root filesystem read-only**, mounts a **writable tmpfs** on `/tmp`, and makes **only** your data directory writable at its normal path. **Network namespaces are not changed**, so Reticulum and TCP/UDP behave like an unsandboxed process unless you add `--unshare-net` (which usually breaks mesh networking).
|
||||
|
||||
### Installed `meshchat`
|
||||
|
||||
```bash
|
||||
DATA="${XDG_DATA_HOME:-$HOME/.local/share}/meshchatx-sandbox"
|
||||
mkdir -p "$DATA/storage" "$DATA/.reticulum"
|
||||
|
||||
exec bwrap \
|
||||
--die-with-parent \
|
||||
--new-session \
|
||||
--proc /proc \
|
||||
--dev /dev \
|
||||
--ro-bind / / \
|
||||
--tmpfs /tmp \
|
||||
--bind "$DATA" "$DATA" \
|
||||
--uid "$(id -u)" --gid "$(id -g)" \
|
||||
meshchat --headless --host 127.0.0.1 \
|
||||
--storage-dir="$DATA/storage" \
|
||||
--reticulum-config-dir="$DATA/.reticulum"
|
||||
```
|
||||
|
||||
Notes:
|
||||
|
||||
- If `meshchat` lives only inside a venv that is **not** under `$DATA`, the read-only root still allows **reading** that path; you do not have to bind-mount the venv separately unless you also need writes there.
|
||||
- Distributions that merge `/` and `/usr` (merged-usr) still work with `--ro-bind / /` on typical glibc setups. If `bwrap` fails with missing library paths, add the extra `--ro-bind` lines your distro documents (for example `/lib64`).
|
||||
|
||||
### From source with Poetry
|
||||
|
||||
Bind the repository and the Poetry venv read-only, and keep `DATA` writable:
|
||||
|
||||
```bash
|
||||
cd /path/to/reticulum-meshchatX
|
||||
DATA="${XDG_DATA_HOME:-$HOME/.local/share}/meshchatx-sandbox"
|
||||
VENV="$(poetry env info -p)"
|
||||
mkdir -p "$DATA/storage" "$DATA/.reticulum"
|
||||
PROJ="$(pwd)"
|
||||
|
||||
exec bwrap \
|
||||
--die-with-parent \
|
||||
--new-session \
|
||||
--proc /proc \
|
||||
--dev /dev \
|
||||
--ro-bind / / \
|
||||
--tmpfs /tmp \
|
||||
--bind "$DATA" "$DATA" \
|
||||
--ro-bind "$PROJ" "$PROJ" \
|
||||
--ro-bind "$VENV" "$VENV" \
|
||||
--uid "$(id -u)" --gid "$(id -g)" \
|
||||
--setenv PATH "$VENV/bin:$PATH" \
|
||||
--chdir "$PROJ" \
|
||||
poetry run meshchat --headless --host 127.0.0.1 \
|
||||
--storage-dir="$DATA/storage" \
|
||||
--reticulum-config-dir="$DATA/.reticulum"
|
||||
```
|
||||
|
||||
`poetry` itself must be reachable on `PATH` inside the sandbox (often under `/usr` or `$HOME/.local/bin`, both visible with `--ro-bind / /`). If `poetry run` fails because it cannot read `~/.config/poetry`, add a read-only bind for that directory or invoke the venv interpreter directly instead of `poetry run`:
|
||||
|
||||
```bash
|
||||
exec bwrap \
|
||||
... same mounts as above ... \
|
||||
--setenv PATH "$VENV/bin:$PATH" \
|
||||
--chdir "$PROJ" \
|
||||
meshchat --headless --host 127.0.0.1 \
|
||||
--storage-dir="$DATA/storage" \
|
||||
--reticulum-config-dir="$DATA/.reticulum"
|
||||
```
|
||||
|
||||
(Use the `meshchat` script or `python -m` entry point from `$VENV/bin` if your install exposes it there.)
|
||||
|
||||
### USB serial under Bubblewrap
|
||||
|
||||
You may need a clearer view of devices than the minimal `--dev /dev` provides. Options include `--dev-bind /dev /dev` (broader device exposure) or binding only the specific character device. Balance convenience against attack surface.
|
||||
Reference in New Issue
Block a user