Skip to content
Open
Show file tree
Hide file tree
Changes from 9 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# The Docker build context is the repository root (docker/compose.yml sets
# `context: ..`) and both Dockerfiles pull it into the builder stage with
# `COPY . .`. `make docker-build` stages the LND cert and admin macaroon in
# docker/config/lnd/ right before `docker compose build`, so without this entry
# a spend-capable credential would be shipped into the build context and left
# in the builder layer and its cache. .gitignore already keeps it out of git,
# but Docker does not read .gitignore.
docker/config/
docker/.env
4 changes: 2 additions & 2 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,6 @@
- Add a language specifier to every fenced code block. Static analysis (markdownlint MD040) flags blocks without a language identifier. Example: ` ```flutter test ` instead of bare ` ``` `.

## Security & Configuration Tips
- Do not commit populated `settings.toml`. Copy from `settings.tpl.toml` to `~/.mostro/settings.toml` for local runs.
- Protect LND credentials before `make docker-build`.
- Do not commit populated `settings.toml`. Install it from `settings.tpl.toml` with `install -d -m 700 ~/.mostro && install -m 600 settings.tpl.toml ~/.mostro/settings.toml` for local runs: the file carries `nsec_privkey` and the directory also holds `mostro.db`.
- Protect LND credentials before `make docker-build`. The admin macaroon is spend-capable: copy it with `install -m 600` (never plain `cp`, which inherits the source or destination mode) and keep its directory at `0700`.
- Scrub logs that might leak invoices or Nostr keys; rotate secrets promptly if exposed.
44 changes: 35 additions & 9 deletions INSTALL.md
Original file line number Diff line number Diff line change
Expand Up @@ -92,10 +92,11 @@ adduser --disabled-login mostro # keep pressing enter until it ends
cd /opt/mostro
```

Create a new settings file from `/opt/mostro/mostro/settings.tpl.toml` and save it to `/opt/mostro`:
Create a new settings file from `/opt/mostro/mostro/settings.tpl.toml` and save it to `/opt/mostro`. `/opt/mostro` holds `settings.toml`, whose `nsec_privkey` is the daemon's identity, and the `mostro.db` created later, so both the directory and the file are restricted to the service account — `install -m` rather than `cp`, which keeps whatever mode the template happens to have:

```bash
cp /opt/mostro/mostro/settings.tpl.toml /opt/mostro/settings.toml
install -d -m 700 -o mostro -g mostro /opt/mostro
install -m 600 -o mostro -g mostro /opt/mostro/mostro/settings.tpl.toml /opt/mostro/settings.toml
```

Update the file `/opt/mostro/settings.toml` with your favourite editor.
Expand All @@ -108,30 +109,55 @@ Here some parameters you might want to change:
- **nsec_privkey** : Your mostro private key
- **relays** : List of relays you want to connect to

### Protect the admin macaroon

The admin macaroon is a spend-capable credential: any user who can read it has full control of the LND node, including the funds escrowed in Mostro's hold invoices. Access should reach no further than the `mostro` service account created above and the LND account the node already runs as.

If LND runs on this same VPS, grant access through the node's group instead of loosening the file (LND creates `admin.macaroon` with mode `0640`):

```bash
usermod -aG lnd mostro
```

If you copy the macaroon into `/opt/mostro` instead, install it owner-readable only and hand it to the service account — do not use plain `cp`, which keeps whatever mode the source file or an existing destination happens to have:

```bash
install -d -m 700 -o mostro -g mostro /opt/mostro/lnd
install -m 600 -o mostro -g mostro /path/to/lnd/admin.macaroon /opt/mostro/lnd/admin.macaroon
```

Then point `lnd_macaroon_file` at `/opt/mostro/lnd/admin.macaroon`.

## Database

The data is saved in a sqlite db file named by default `mostro.db`, this file is saved on the root directory of the project and can be change just editing the `url` var on the `[database]` section in `settings.toml` file.

Before start building you can initialize the database manually with `sqlx-cli` (optional — `mostrod` creates the file and runs migrations on first connect):
Before start building you can initialize the database manually with `sqlx-cli` (optional — `mostrod` creates the file and runs migrations on first connect).

These commands run as root, so the database ends up owned by root. Hand it to the service account right away: SQLite writes the `-shm`/`-wal` sidecars next to the database, so `mostrod` needs to own the files *and* be able to create new ones in the directory.

```bash
cargo install sqlx-cli --version 0.9.0 --no-default-features --features sqlite
cd /opt/mostro
export DATABASE_URL=sqlite://mostro.db
sqlx database create
sqlx migrate run
chown mostro:mostro /opt/mostro/mostro.db*
```

Check the DB files are there
Check the DB files are there, and that they belong to `mostro`:

```bash
ls -al /opt/mostro
drwxrwxr-x root root 4.0 KB Fri Jun 14 15:52:07 2024 .
drwxr-x--- root root 4.0 KB Sat Jun 15 15:50:32 2024 ..
.rw-r--r-- root root 52 KB Fri May 31 16:35:34 2024 mostro.db
.rw-r--r-- root root 32 KB Sat Jun 15 15:28:23 2024 mostro.db-shm
.rw-r--r-- root root 16 KB Fri Jun 14 15:57:24 2024 mostro.db-wal
drwx------ mostro mostro 4.0 KB Fri Jun 14 15:52:07 2024 .
Comment thread
AndreaDiazCorreia marked this conversation as resolved.
drwxr-x--- root root 4.0 KB Sat Jun 15 15:50:32 2024 ..
.rw-r--r-- mostro mostro 52 KB Fri May 31 16:35:34 2024 mostro.db
.rw-r--r-- mostro mostro 32 KB Sat Jun 15 15:28:23 2024 mostro.db-shm
.rw-r--r-- mostro mostro 16 KB Fri Jun 14 15:57:24 2024 mostro.db-wal
```

If you skip this step, `mostrod` creates the database itself on first connect — as root during the foreground test below. Either way, the `chown -R mostro:mostro /opt/mostro` further down is the backstop that puts the ownership right before the service starts.

## Clean compilation artifacts

Since the instance you are using has little disk space you don't want to waste valuable disk space. Once successfully compiled the compilation artifacts can use up to **2Gb** of space.
Expand Down
12 changes: 9 additions & 3 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ VERSION := $(shell grep "^version = " Cargo.toml | sed "s/version = \"\(.*\)\"/\
docker-build:
@set -o pipefail; \
cd docker && \
mkdir -p config/lnd && \
install -d -m 700 config config/lnd && \
echo "Checking LND files..." && \
echo "LND_CERT_FILE=$${LND_CERT_FILE}" && \
echo "LND_MACAROON_FILE=$${LND_MACAROON_FILE}" && \
Expand All @@ -27,15 +27,20 @@ docker-build:
exit 1; \
fi && \
echo "Copying LND cert and macaroon to docker config" && \
cp -v $${LND_CERT_FILE} config/lnd/tls.cert && \
cp -v $${LND_MACAROON_FILE} config/lnd/admin.macaroon && \
install -m 644 "$${LND_CERT_FILE}" config/lnd/tls.cert && \
install -m 600 "$${LND_MACAROON_FILE}" config/lnd/admin.macaroon && \
Comment thread
AndreaDiazCorreia marked this conversation as resolved.
Comment thread
AndreaDiazCorreia marked this conversation as resolved.
echo "Wrote config/lnd/tls.cert (mode 644) and config/lnd/admin.macaroon (mode 600)" && \
echo "config and config/lnd are mode 700: settings.toml holds nsec_privkey and mostro.db lands there too" && \
echo "Note: the container runs as uid/gid 1000 by default. If your user is not uid 1000," && \
echo ' export MOSTRO_CONTAINER_USER=$$(id -u):$$(id -g) before make docker-up' && \
echo "Building docker image" && \
docker compose build

docker-up:
@set -o pipefail; \
cd docker && \
echo "Copying Nostr relay config" && \
install -d -m 700 config && \
mkdir -p config/relay && \
cp -v ./relay_config.toml config/relay/config.toml && \
echo "Starting services" && \
Expand All @@ -45,6 +50,7 @@ docker-relay-up:
@set -o pipefail; \
cd docker && \
echo "Copying Nostr relay config" && \
install -d -m 700 config && \
mkdir -p config/relay && \
cp -v ./relay_config.toml config/relay/config.toml && \
echo "Starting Nostr relay" && \
Expand Down
20 changes: 14 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -443,9 +443,10 @@ cargo build --release
# Install to system
sudo install target/release/mostrod /usr/local/bin

# Setup configuration
mkdir -p ~/.mostro
cp settings.tpl.toml ~/.mostro/settings.toml
# Setup configuration (0700/0600: settings.toml holds nsec_privkey, and
# mostro.db lands in the same directory)
install -d -m 700 ~/.mostro
install -m 600 settings.tpl.toml ~/.mostro/settings.toml
# Edit ~/.mostro/settings.toml (see Configuration section)

# Initialize database (optional — mostrod also migrates on first connect)
Expand Down Expand Up @@ -479,9 +480,10 @@ Best for: Local testing, development environments, quick experiments
git clone https://github.com/MostroP2P/mostro.git
cd mostro

# Setup configuration
mkdir -p docker/config
cp settings.tpl.toml docker/config/settings.toml
# Setup configuration (0700/0600: the config dir ends up holding nsec_privkey,
# the LND credentials and mostro.db)
install -d -m 700 docker/config
install -m 600 settings.tpl.toml docker/config/settings.toml
# Edit docker/config/settings.toml

# Build and run (provide LND paths as environment variables)
Expand All @@ -495,6 +497,8 @@ This starts:
- Mostro daemon (exposed via configured relays)
- Local Nostr relay (port 7000 by default)

`make docker-build` installs the LND admin macaroon into `docker/config/lnd/` with mode `0600`, since it grants full control of your node, and sets `docker/config` and `docker/config/lnd` to mode `0700` — the same directory holds `settings.toml` and `mostro.db`. The container runs as uid/gid 1000 by default; if your user is not uid 1000, `export MOSTRO_CONTAINER_USER=$(id -u):$(id -g)` so it runs as you and can read those files.

**Stop**: `make docker-down`

For detailed Docker setup, see [docker/README.md](docker/README.md).
Expand Down Expand Up @@ -565,6 +569,8 @@ payment_retries_interval = 60 # seconds between retries

**Required**: LND connection details. Mostro needs admin macaroon for hold invoice management.

**Permissions**: the admin macaroon is a spend-capable credential — anyone who can read it controls the node, including the funds escrowed in Mostro's hold invoices. Keep it readable only by the account running `mostrod`, or by that account and LND's group (`chmod 600` for a private copy, `chmod o=` to keep group access). mostrod logs a warning at startup when the file's `other` permission bits are set.

---

#### Nostr Configuration
Expand All @@ -590,6 +596,8 @@ rana --vanity mostro

**Important**: Never reuse keys between Mostro instances. Each daemon needs a unique identity.

**Permissions**: `settings.toml` holds `nsec_privkey` in plaintext unless you move it to the environment (see below), and `mostro.db` sits in the same directory. Keep both owner-only: `chmod 700` on the settings directory and `chmod 600` on `settings.toml`. mostrod already creates them that way when it has to — both through the interactive setup wizard and through the template copy it makes on a non-interactive first run — but a directory or file you create yourself with `mkdir`, `cp` or `curl` inherits your umask instead, so use `install -d -m 700` and `install -m 600`.

##### Providing the nsec via environment variable

For better separation of secrets from config, Mostro can read the nsec from the
Expand Down
8 changes: 7 additions & 1 deletion docker/ENV_VARIABLES.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,20 @@ This document describes the environment variables used by the Docker setup.
- `LND_MACAROON_FILE`: Path to the LND admin macaroon file on your host system
- Example: `~/.polar/networks/1/volumes/lnd/alice/data/chain/bitcoin/regtest/admin.macaroon`

These files are copied to `docker/config/lnd/` during the build process.
These files are copied to `docker/config/lnd/` during the build process: the cert with mode `0644`, the admin macaroon with mode `0600`, both inside a directory with mode `0700`. The macaroon grants full control of your LND node, so it is never left readable by other users on the host. The `docker/config` root is set to mode `0700` as well, since `settings.toml` (which carries `nsec_privkey`) and `mostro.db` live beside the credentials.

The copies belong to the user that ran the command, and the container runs as uid/gid 1000 by default. If your user is not uid 1000, run the container as yourself with the optional variable below rather than handing the config directory over to uid 1000.

## Optional Variables

- `MOSTRO_RELAY_LOCAL_PORT`: Port number for the local Nostr relay (defaults to 7000)
- Used in `compose.yml` for port mapping
- Example: `export MOSTRO_RELAY_LOCAL_PORT=7000`

- `MOSTRO_CONTAINER_USER`: uid/gid the `mostro` container runs as (defaults to `1000:1000`, the image's `mostrouser`)
- Set it when your host user is not uid 1000, so the container can read the `0600` macaroon and write `mostro.db` in the mounted config directory
- Example: `export MOSTRO_CONTAINER_USER=$(id -u):$(id -g)`

- `MOSTRO_DB_PASSWORD`: Not used (database encryption was removed). Kept in `compose.yml` for backward compatibility; can be omitted or left empty.

## Usage Examples
Expand Down
Loading