diff --git a/README.md b/README.md index 07d7b23..3993d9c 100644 --- a/README.md +++ b/README.md @@ -18,11 +18,44 @@ by the `hledger` command line tool: ## Installation -Follow the [plugin installation guide](https://meta.discourse.org/t/install-a-plugin/19157). +The plugin requires the `hledger` executable on the server. -The plugin requires the `hledger` executable on the server. Install it with -your package manager (for example `apt-get install hledger`) and point the -`hledger path` site setting at it if it is not on the default `PATH`. +### Default Docker deployment + +The recommended self-hosted setup runs Discourse in a container built from an +`app.yml` file ([install guide](https://github.com/discourse/discourse/blob/main/docs/INSTALL-cloud.md)). +Add the plugin and the `hledger` package to `/var/discourse/containers/app.yml`: + +```yaml +hooks: + after_code: + - exec: + cd: $home/plugins + cmd: + - git clone https://gitea.kosmos.org/raucao/discourse-hledger.git + - exec: + cd: $home + cmd: + - apt-get update + - DEBIAN_FRONTEND=noninteractive apt-get install -y hledger +``` + +Then rebuild the container to apply the changes: + +```sh +cd /var/discourse +./launcher rebuild app +``` + +The `after_code` hook runs on every rebuild, so the plugin and `hledger` stay +installed across rebuilds. + +### Other installs + +Follow the [plugin installation guide](https://meta.discourse.org/t/install-a-plugin/19157). +Install `hledger` with your package manager (for example +`apt-get install hledger`) and point the `hledger path` site setting at it if it +is not on the default `PATH`. ### Docker development environment @@ -60,10 +93,32 @@ are linked; anything else stays plain text. ## Security -Journals are untrusted input. The plugin runs `hledger` with a scrubbed -environment, a private working directory, a hard timeout, resource limits and -an output cap, and it rejects `include` directives so a journal cannot read -arbitrary server files. +Journals are untrusted input. The plugin runs `hledger` as an unprivileged +subprocess with a scrubbed environment, a private working directory, a hard +timeout, CPU, file-size and memory limits and an output cap, and it rejects +`include` directives so a journal cannot read arbitrary server files. + +Defenses are layered: Discourse authorization, a per-IP rate limit and the +global rate limit, the journal size and line limits, the execution timeout, the +resource limits and the output cap. + +For installations where untrusted users can create public topics, additionally +sandbox `hledger` at the OS or container level — for example a systemd unit with +`ProtectSystem=strict`, `ProtectHome=true`, `PrivateTmp=true`, +`NoNewPrivileges=true`, `RestrictAddressFamilies=AF_UNIX`, `MemoryMax=` and +`TasksMax=`, or a dedicated container runtime. Those controls are stronger than +in-process resource limits. + +### Relevant settings + +- `hledger max journal bytes` and `hledger max journal lines` limit the size of + an accepted journal. +- `hledger timeout seconds` limits the wall-clock time of each `hledger` + invocation. +- `hledger memory limit mb` caps the process memory (`0` disables it). +- `hledger max output bytes` caps the captured output. +- `hledger global rate limit per minute` throttles report generation across all + users (`0` disables it). ## Development