# 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.