Files
worker/README.md
Gleb Tv e987f24903
Все проверки выполнены успешно
CI / test (push) Successful in 2m32s
Docker / Build and publish worker image (push) Successful in 18m17s
fix(worker): harden control-plane lifecycle
- reconnect safely after token rotation and retry leased results
- reject malformed tasks and remove production cluster debug mutation
- validate environment files and require immutable container images

BREAKING CHANGE: Docker install, deploy, and Compose now require an
immutable repository@sha256 image reference.
2026-07-19 23:11:43 +03:00

211 строки
8.0 KiB
Markdown

# RSMon Worker
Standalone distributed monitoring worker for [rsmon.ru](https://rsmon.ru). It
connects to the RSMon control plane over WebSocket, executes checks locally,
delivers delegated notifications, and reports results back to the service.
This repository is **source available, not open source**. Building and running
the worker with rsmon.ru and private research/evaluation are permitted. See
[LICENSE](LICENSE) for the complete terms.
## Requirements
- A worker token created in the rsmon.ru worker settings.
- Outbound HTTPS/WebSocket access to rsmon.ru.
- Chromium for browser-backed HTTP checks when running the binary directly.
- `CAP_NET_RAW` or an unprivileged ICMP configuration for ping checks.
## Build
Go 1.26 or newer is required.
```bash
make build
./bin/rsmon-worker --version
```
The binary reads `.env` from its working directory when present. The minimum
configuration is `RSMON_URL`, `RSMON_TOKEN`, `WORKER_LOGIN`, and
`WORKER_PASSWORD`.
## Docker Compose
```bash
cp .env.example .env
# Edit .env and set the worker token and operator-console password.
docker compose up -d
docker compose logs -f worker
```
Compose constructs an immutable image reference from
`RSMON_WORKER_IMAGE_DIGEST`. Set that variable in `.env` to the published
64-character lowercase digest before running Compose; a mutable tag cannot be
selected through this configuration.
The operator console is bound to `127.0.0.1:27401` by default. Set
`WORKER_BIND_IP` only when a firewall or TLS reverse proxy protects the port.
Persistent web and cluster state is stored in the `worker-data` volume.
## Docker
```bash
IMAGE='reg.rsxx.ru/rsmon/rsmon-worker@sha256:<published-64-character-digest>'
docker pull "$IMAGE"
docker run --rm \
--cap-add NET_RAW \
--env-file .env \
-p 127.0.0.1:27401:27401 \
-v rsmon-worker-data:/var/lib/rsmon-worker \
"$IMAGE"
```
Published images have tags for discovery:
- `sha-<12-character-commit>` for every push;
- `latest` for `master`;
- the `v*` release ref, with Docker-invalid characters replaced by `-`.
Resolve a trusted published tag through the registry, then deploy the resulting
`repository@sha256:...` digest. Tags are mutable and are not accepted by the
installer or deploy command; Compose requires the resolved digest to be
configured explicitly.
The Gitea workflow reads `HARBOR_REGISTRY`, `HARBOR_USER`, and
`HARBOR_PASSWORD`. `HARBOR_REGISTRY` may be a host such as `reg.rsxx.ru` or an
HTTP(S) URL; the workflow strips the scheme and trailing slash before composing
Docker image references. The Harbor project is appended separately as `rsmon`.
## systemd
Install host dependencies first. On Debian or Ubuntu:
```bash
sudo apt-get update
sudo apt-get install -y ca-certificates chromium libcap2-bin tzdata
```
Build and install with a token file so the token does not enter shell history or
the process list:
```bash
make build
printf '%s\n' 'WORKER_TOKEN' > worker-token
chmod 600 worker-token
sudo ./bin/rsmon-worker install --token-file worker-token
rm worker-token
```
`install` copies the running binary to `/usr/local/bin/rsmon-worker`, writes the
mode-0600 configuration at `/etc/rsmon-worker/worker.env`, installs a simple
root-run systemd unit, and enables and starts it. Use `--url` to override
`https://rsmon.ru`, `--binary` to install another binary, or `--no-start` to
configure without starting. When using `--env-file`, installation verifies its
`RSMON_URL` and `RSMON_TOKEN` before changing the host. Environment files use
portable `KEY=VALUE` lines (plus blank lines and `#` comments); quoting,
interpolation, whitespace in values, and YAML-style assignments are rejected
because systemd and Docker interpret them differently.
The Docker alternative pulls the prebuilt image and installs a systemd unit
that runs it:
```bash
sudo ./bin/rsmon-worker install --docker --token-file worker-token \
--image 'reg.rsxx.ru/rsmon/rsmon-worker@sha256:<published-64-character-digest>'
```
Docker installation requires `--image` with an immutable
`repository@sha256:<64-lowercase-hex-characters>` reference. This is a breaking
change: prior `--docker` invocations that relied on the `latest` default, or
passed only a tag, now fail before Docker is invoked or any host file is changed.
The token can also be passed as `--token` or `--api-key`, but that can expose it
through shell history and process inspection. The legacy repository-based
installer remains available:
```bash
sudo ./scripts/install-systemd.sh --binary ./rsmon-worker --env ./worker.env
```
Operational commands:
```bash
systemctl status rsmon-worker
journalctl -u rsmon-worker -f
sudo systemctl restart rsmon-worker
```
The service runs as root, reads secrets from
`/etc/rsmon-worker/worker.env`, and can execute ICMP checks without additional
capability setup.
## SSH deployment
`deploy` uploads the selected worker binary and a temporary mode-0600
configuration over SSH, then runs the binary's `install` command through root or
`sudo`. The remote host needs Linux, systemd, `base64`, and either root SSH or
sudo access.
```bash
./bin/rsmon-worker deploy \
--host worker.example.com \
--user deploy \
--identity-file ~/.ssh/id_ed25519 \
--token-file worker-token
```
Add `--docker` to install remotely by uploading only the configuration and
systemd unit, then running `docker pull` on the target. This mode does not upload
or execute the local worker binary, so the local and remote architectures may
differ. It also requires `--image repository@sha256:...`; tag-only references
are rejected before connecting to the remote host.
The default SSH port is 22 and the default RSMon URL is `https://rsmon.ru`.
Encrypted keys use `--key-passphrase-file`; password authentication uses
`--password-file`; password-protected sudo uses `--sudo-password-file`. Direct
secret flags are supported for interactive convenience but file options are
safer for automation.
SSH host keys are checked against `~/.ssh/known_hosts` by default. Use
`--known-hosts PATH` or pin `--host-key-fingerprint SHA256:...`. The explicit
`--insecure-host-key` option disables host authentication and should only be
used in a trusted disposable environment.
## Configuration
| Variable | Required | Default | Purpose |
| --- | --- | --- | --- |
| `RSMON_URL` | yes | `https://rsmon.ru` for health only | Control-plane base URL. |
| `RSMON_TOKEN` | yes | none | Worker bearer token. |
| `WORKER_HOST` | no | `0.0.0.0` | Operator-console bind address. |
| `WORKER_PORT` | no | `27401` | Operator-console port. |
| `WORKER_URL` | no | none | Public URL advertised to the control plane. |
| `WORKER_LOGIN` | yes | none | Operator-console basic-auth login. |
| `WORKER_PASSWORD` | yes | none | Operator-console basic-auth password. |
| `RSMON_WEBAPP_DATA_DIR` | no | user data directory | SQLite and local UI state. |
| `WORKER_CLUSTER_ENABLED` | no | `false` | Enable the optional Raft cluster. |
| `WORKER_CLUSTER_ID` | with cluster | none | Unique Raft node ID. |
| `WORKER_CLUSTER_PORT` | no | `WORKER_PORT+10000` | Raft transport port. |
| `WORKER_CLUSTER_PEERS` | no | none | Comma-separated `node@host:port` peers. |
| `WORKER_CLUSTER_DATA_DIR` | with cluster | none | Persistent Raft state directory. |
The public liveness endpoint is `GET /healthz`; the image probes it with
`rsmon-worker liveness`. `rsmon-worker health` separately checks the configured
control plane's `/up` endpoint for connectivity diagnostics.
## Implementation Documentation
Worker architecture, protocol, inventory, private-worker isolation, network
diagnostics, web console, and critical-cluster work are specified in
[`docs/README.md`](docs/README.md). These documents replace worker-owned planning
material formerly kept in the RSMon control-plane repository and include a
source migration ledger.
## Security
- Do not commit `.env`, worker tokens, or operator-console credentials.
- Expose the operator console only on loopback or behind authenticated TLS.
- Each worker should have its own control-plane token.
- Keep `/etc/rsmon-worker/worker.env` mode `0600`.
Report security issues privately through the contact channel at rsmon.ru.