Rework `rsmon-worker install` so one host can run several isolated workers and so the installer consumes the full worker env-var set. - main.go now loads .env before dispatching management commands, so install/deploy read the same environment as the runtime. - New --name flag installs a co-located worker as rsmon-worker-<name> with its own binary (/usr/local/bin/rsmon-worker-<name>), config (/etc/rsmon-worker-<name>), data dir (/var/lib/rsmon-worker-<name>), and systemd unit. Named instances require an explicit WORKER_PORT. - Configuration is resolved flags > --env-file > process env/.env (godotenv) > defaults; the resolved set is written as a stable, systemd-safe 0600 env file. - WORKER_LOGIN/WORKER_PASSWORD default to a generated admin password (printed once) when both are unset; XOR is rejected. - The generated unit is now hardened (After=docker.service, CAP_NET_RAW, ProtectSystem=full, ReadWritePaths=data dir) and parameterized by instance; the Docker unit is namespaced by instance too. - install creates the data + config directories and prints a summary (unit, binary, env file, data dir, console URL, generated password). - New flags: --name, --host, --port, --login, --password/--password-file. - Tests: resolvePaths, validateInstanceName, resolveInstallEnv precedence/XOR/port-required, renderEnvFile, validateEnvValue, plus named-instance unit assertions. End-to-end verified by installing and removing a throwaway --name instance. - docs/install.md documents the tool, config sources/precedence, single- and multi-instance flows, the exact actions performed, the generated unit, options, and uninstall.
8.4 KiB
RSMon Worker
Standalone distributed monitoring worker for 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 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_RAWor an unprivileged ICMP configuration for ping checks.
Build
Go 1.26 or newer is required.
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
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
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;latestformaster;- 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
The install subcommand turns a built binary into an enabled systemd service:
it writes a hardened unit, a mode-0600 env file, the data directory, then
enables and starts the worker. It reads configuration from flags, --env-file,
a .env in the working directory, or the process environment (in that order),
and supports several co-located workers per host via --name. The full
reference is in docs/install.md.
Install host dependencies first. On Debian or Ubuntu:
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:
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:
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:
sudo ./scripts/install-systemd.sh --binary ./rsmon-worker --env ./worker.env
Operational commands:
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.
./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. 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.envmode0600.
Report security issues privately through the contact channel at rsmon.ru.