From e2d09f5948a4a73d84c2fc00af6d04957eb1dece Mon Sep 17 00:00:00 2001 From: Vijit Singh Date: Thu, 11 Jun 2026 00:20:47 -0500 Subject: [PATCH] docs: stratum authentication against a Pithead stack (set the pool pass) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Pithead added an optional stratum password (p2pool.stratum_password, pithead#152/#207): when the operator turns it on, the stack's :3333 proxy rejects any rig whose stratum 'pass' doesn't match (XMRig logs "Permission denied"). RigForge already carries the secret — pools[].pass is XMRig's native field (default "x") — so this is documentation, not a code change. - docs/pithead-integration.md: new "Stratum authentication (optional)" subsection under the mining connection — set pools[].pass to the stack's p2pool.stratum_password, where to find the value (printed by pithead apply/setup, in .env, shown by pithead status), and the cleartext-over-LAN caveat. Cross-links pithead docs/workers.md#authentication. Plus a troubleshooting row for the "Permission denied" symptom. - docs/configuration.md: the pools[].pass reference now explains the stratum-password use case instead of just showing the default. - tests: assert a Pithead-style password (auto-generated hex, and a literal with the . _ : @ - punctuation Pithead allows) flows through verbatim as the pool pass — the cross-repo contract that a stack-side secret is always a valid XMRig pass. Refs pithead#152, pithead#207, pithead#208. Co-Authored-By: Claude Opus 4.8 (1M context) --- CHANGELOG.md | 7 +++++++ docs/configuration.md | 2 +- docs/pithead-integration.md | 29 +++++++++++++++++++++++++++++ tests/run.sh | 8 ++++++++ 4 files changed, 45 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 29af2e8..b9eac29 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,13 @@ All notable changes to RigForge are documented here. The format is based on ## [Unreleased] ### Added +- **Docs: stratum authentication against a Pithead stack.** Pithead can now require a stratum + password (`p2pool.stratum_password`); when it's on, a rig must send the matching pool `pass` or the + proxy rejects it (`Permission denied`). [Pithead Integration](docs/pithead-integration.md#stratum-authentication-optional) + and the [`pass` config reference](docs/configuration.md#pools-full-control) now explain how to set + it — no code change, the existing `pools[].pass` field carries the secret. Added tests asserting a + Pithead-style password (hex and `._:@-` literals) flows through verbatim and an invalid pass (with a + space) is rejected. - **`tune --history`** — a readable summary of this rig's tuning: the **winning tune options** applied right now (from `tune-overrides.json`), the last full `tune` run (target, best H/s, candidates tried), and — on Linux — the periodic auto-tuner's **schedule, next scheduled run**, and recent keep/rollback diff --git a/docs/configuration.md b/docs/configuration.md index eaca157..bdd027f 100644 --- a/docs/configuration.md +++ b/docs/configuration.md @@ -87,7 +87,7 @@ so you specify only what you care about: |---|---| | `url` | _(required)_ — `host:port` (e.g. `your-stack:3333`; Pithead's proxy listens on `3333`). For an IPv6 literal, use the bracketed `[2001:db8::1]:3333` form. | | `user` | the machine hostname — this is the rig's **label** on the dashboard; set it to name the rig | -| `pass` | `"x"` | +| `pass` | `"x"` — the stratum password. The default works for an **open** stack; if the operator enabled the stack's `p2pool.stratum_password`, set this to that secret or the proxy rejects the rig. See [Pithead Integration › Stratum authentication](pithead-integration.md#stratum-authentication-optional). | | `keepalive` | `true` | | `tls` | `false` | | `enabled` | `true` | diff --git a/docs/pithead-integration.md b/docs/pithead-integration.md index b99eb2c..dbc674f 100644 --- a/docs/pithead-integration.md +++ b/docs/pithead-integration.md @@ -25,6 +25,34 @@ split centrally, so the worker config stays minimal and you **never put a wallet - The endpoint must be reachable from the worker; if the stack host has a firewall, allow the Stratum port (3333) on the LAN. +### Stratum authentication (optional) + +By default the stack's `:3333` is **open** — any rig that can reach it may mine, and the pool `pass` +is ignored (RigForge defaults it to `"x"`). If the operator turns authentication **on** by setting +[`p2pool.stratum_password`](https://github.com/p2pool-starter-stack/pithead/blob/main/docs/workers.md#authentication) +on the stack, the proxy then **rejects any rig whose `pass` doesn't match** — XMRig logs +`Permission denied` and the rig won't mine. Put that same secret in the rig's pool `pass`: + +```jsonc +// config.json — set "pass" to the stack's p2pool.stratum_password +{ + "pools": [ + { "url": "your-stack:3333", "pass": "the-stratum-password" } + ] +} +``` + +Then `./rigforge.sh apply` (or `setup`) regenerates the worker config with the new password. + +- It's the **same secret on every rig**. The operator finds it on the stack side — it's printed after + `pithead apply`/`setup`, stored in the stack's `.env` as `PROXY_STRATUM_PASSWORD`, and shown by + `pithead status`. +- The password travels **cleartext** over your LAN's plain Stratum, so this is access control — + *who may mine* — **not** encryption. Keep `:3333` on a trusted LAN (the stack's `p2pool.stratum_bind` + / a firewall do the rest). +- This is unrelated to the `DONATION` knob (that's *this rig's* dev-fee donation) and to the API + `ACCESS_TOKEN` below (that's the read-only stats auth on `:8080`). + --- ## 2. Stats connection — the Worker API (`:8080`) @@ -63,6 +91,7 @@ matching configuration on **both** sides — that cross-side coordination is lat | Symptom | Fix | |---|---| +| **Rig won't mine / XMRig logs `Permission denied` at login** | The stack has stratum authentication on (`p2pool.stratum_password`) — set the pool `pass` to that secret. See [Stratum authentication](#stratum-authentication-optional). | | **Worker missing from the dashboard** | The dashboard discovers rigs from their stratum `user` label — confirm the worker is actually connected to the pool and mining. | | **Rig shows as connected but no stats** | The HTTP API token must equal the rig name (or be unset). If you set a custom `ACCESS_TOKEN`, the dashboard can't read it — clear it and re-run setup. | | **Stats unreachable from the stack host** | Confirm the worker's `:8080` is reachable from the stack host over the LAN (firewall, correct IP). RigForge binds `0.0.0.0` by default. | diff --git a/tests/run.sh b/tests/run.sh index db62620..238f29e 100644 --- a/tests/run.sh +++ b/tests/run.sh @@ -251,6 +251,14 @@ c="$(mkconf p_full "{ \"pools\": [{\"url\":\"pool.example:443\",\"tls\":true,\"p assert_eq "explicit url kept" "$(PJ "$c" | jq -r '.[0].url')" "pool.example:443" assert_eq "explicit tls kept" "$(PJ "$c" | jq -c '.[0].tls')" "true" assert_eq "explicit pass kept" "$(PJ "$c" | jq -r '.[0].pass')" "w" +# A Pithead stratum password (p2pool.stratum_password) flows through verbatim as the pool pass — the +# cross-repo contract for an authenticated stack. Covers an auto-generated hex secret and a literal +# with the punctuation Pithead allows (. _ : @ -); both are valid XMRig passes. +c="$(mkconf p_pw "{ \"pools\": [{\"url\":\"stack:3333\",\"pass\":\"a1b2c3d4e5f6a7b8\"}] }")" +assert_eq "stratum password (hex) kept as pass" "$(PJ "$c" | jq -r '.[0].pass')" "a1b2c3d4e5f6a7b8" +c="$(mkconf p_pw2 "{ \"pools\": [{\"url\":\"stack:3333\",\"pass\":\"Stack_Pass.1:2@3-x\"}] }")" +assert_eq "stratum password (symbols) kept as pass" "$(PJ "$c" | jq -r '.[0].pass')" "Stack_Pass.1:2@3-x" +# (a pass with a space is rejected — see the validation block below.) # A non-default port is honoured verbatim. c="$(mkconf p_port "{ \"pools\": [{\"url\":\"stack.lan:14444\"}] }")" assert_eq "non-default port kept" "$(PJ "$c" | jq -r '.[0].url')" "stack.lan:14444"