Repository navigation
First-run setup never offers the SOCKS proxy it already supports: an .onion pool is unreachable unless the operator hand-edits config.json #520
Description
What's missing
#400 gave a pool a socks5 key and shipped it in v1.17.0. Nothing in the product ever mentions
it to an operator who is not reading config.reference.json. First-run setup asks two questions,
writes a two-key pool, and an operator who typed an .onion address into the first one gets a
miner that cannot connect and no indication why.
This is the DIY install path only. On the Pithead appliance RigForge runs verify-only
(RIGFORGE_APPLIANCE=1) and its config.json is generated by Pithead, so this wizard never runs
there — that side is tracked in the Pithead repo.
What setup does today
ensure_config_exists() (rigforge.sh:269-352) asks exactly two things:
rigforge.sh:289—Enter your pool URL (host:port, e.g. your-stack:3333):, re-prompted up to
SETUP_URL_TRIES(3) and host-validated before the write (rigforge.sh:304-314). That
hostname regex,^[A-Za-z0-9]([A-Za-z0-9.-]*[A-Za-z0-9])?$, already accepts a v3.onion.rigforge.sh:327— the stratum password.
Then it writes {pools: [{url, pass?}]} with jq -n (rigforge.sh:334-336). There is no third
question, and nothing downstream notices that the URL it just accepted is unreachable without a
proxy.
Everything else is already in place: _validate_host_port() (rigforge.sh:384-419) is shared
between url and socks5; parse_config() re-attaches the key (rigforge.sh:468-474);
generate_xmrig_config() passes pool fields through verbatim; tests/run.sh:359-450 covers the
parse and validation cases including an onion pool with a proxy.
The change
Two small things, plus the docs.
1. Setup infers the proxy from an .onion pool URL. The wizard is deliberately short and an
.onion address is already an unambiguous answer to "this needs Tor" — so when the entered URL's
host ends in .onion, default socks5 to 127.0.0.1:9050, say so on screen, and let the
operator override it. No new question for the LAN operator, who is almost everyone.
The alternative — always ask a third question — is worse: it is wrong to answer for every LAN rig,
and it invites a value where null is correct.
2. doctor checks the proxy is actually there. RigForge points the miner at a proxy; it does
not run one, and it should not start. But when a pool has socks5 set, doctor can say whether
anything is listening on that address and whether the miner is connected — today a missing local
tor is indistinguishable from a wrong pool address, from a dead stratum, from a bad password.
This is the whole difference between "install tor and it works" and a debugging session.
3. The docs currently say the opposite. Four places tell the operator Tor is not needed, which
was true before onion stratums existed and is now the first thing they read:
docs/pithead-integration.md:24— "they do not need Tor"docs/pithead-integration.md:169— "Workers run on a trusted LAN and need no Tor"docs/getting-started.md:28— "Workers run on a trusted LAN and do not need Tor"docs/hardware.md:20— "workers do not need Tor"docs/faq.md:114— "Does the worker need Tor?"
The honest answer becomes: not on a LAN, which is the normal case; yes, and you install and run it
yourself, if your pool is an onion.
Scope — what stays out
RigForge does not install, start, or supervise a Tor client, on any platform. It is bare-metal and
single-purpose, the proxy is the operator's to arrange, and #400 settled this. An appliance rig's
Tor client is the Pithead image's job. This issue adds a prompt, a check, and honest docs — no
new dependency and no new daemon.
No ADR needed: 0001 and 0002 exist for the control path and remote upgrade, both of which changed
the trust model. This changes neither.
Testing
All of it fits the existing unit tier — tests/run.sh, no network, no Tor.
| Proof | Where |
|---|---|
an .onion pool URL in setup writes a pool with the inferred socks5, and the operator's override wins |
tests/run.sh (drive ensure_config_exists on a piped stdin, as the existing setup tests do) |
a clearnet pool URL writes no socks5 key — the minimal config stays byte-identical to today |
tests/run.sh |
| a rejected/re-prompted URL still persists nothing (the existing #344 property, unchanged) | tests/run.sh |
doctor reports a socks5 pool whose proxy is not listening, and is quiet when it is |
tests/run.sh with a loopback listener |
tests/e2e/linux.sh needs no new leg: the container e2e proves setup runs, and this adds no
runtime dependency it would have to install.
Related, in the Pithead repo:
- Let rigs on other networks mine over Tor: an opt-in onion for the stratum, default off — plus the appliance rig's half of dialling it pithead#1319 — the umbrella for mining over Tor.
- Publish the stratum as an onion service, default off — the server half of #1319 pithead#2437 — publishing the stratum as an onion (the server half).
- The appliance rig cannot dial an onion stratum: no Tor client on the box, no
socks5in the generated config, and a preflight that cannot reach one pithead#2438 — the appliance rig's Tor client and generated config.
Activity
pithead-developer commentedon Sep 24, 2026
Investigation brief (operator pre-read, 2026-09-23) — corrected
Still present on develop head (dcdbc7e, 2026-09-08).
ensure_config_exists()(rigforge.sh:269-352) only prompts for pool URL and password and writes{pools:[{url,pass?}]}(rigforge.sh:334-336) — no.oniondetection, no socks5 offer. Everything downstream already supports it: shared validator_validate_host_port(comment block from rigforge.sh:384, function body at 390-419),parse_configre-attach (rigforge.sh:468-474), both landed with #400/#408 (merged as PR #404/#411, v1.17.0).doctor()(rigforge.sh:5439-5480) still has no check for whether a configured socks5 proxy is actually listening — confirmed nosocks5reference anywhere indoctor(). The 5 "no Tor needed" doc lines the issue names are unchanged and verified verbatim (docs/pithead-integration.md:24,169; docs/getting-started.md:28; docs/hardware.md:20; docs/faq.md:114). No PR references #520; not a duplicate.Root cause: the wizard was never revisited when #400 added
socks5plumbing — it still only ever writes the two original keys.Fix shape: three independent pieces, matches the issue's own plan — (1) in the wizard, default
socks5=127.0.0.1:9050when the entered host ends in.onion, let the operator override, write it through the existing jq path; (2) add one guarded TCP-dial check indoctor()for a configured socks5 address; (3) fix the 5 doc lines. Each is a handful of lines plus atests/run.shcase, per the issue's own testing table.Evidence tier: tier-1 is sufficient — confirmed rigforge's own tier4-e2e (
tests/e2e-pithead.sh, driven by bench-ci'stiers/rigforge/tier4-e2e.sh) has phasesconnect|worker-api|api-impact|network|stratum-auth|dashboard|dev-feeonly; none exercise setup or doctor, and none touch Tor/onion. The fix changes no control-plane, deploy, or Tor-daemon-supervision surface (RigForge never runs Tor itself;doctor()'s new check is a passive, advisory TCP dial, not a change to what runs on a box). Existing container e2e already covers setup.Rulings needed: (a) doctor's proxy check advisory-only vs. hard-fail — recommend advisory, matching the existing API-refresh check; (b) env-var override for the onion default vs. interactive-prompt-only — recommend prompt-only, smaller diff.
Triage: KEEP at its current milestone. rigforge#520 is already filed under v2.x - post-GA (frozen until GA per current release policy), which matches its own status: real, low-risk, ready to implement, already has full validator plumbing to build on, not a 2.0.0 blocker (no data loss, no Tari-fork interaction, and the DIY setup wizard's own scope note says it never runs against a fresh appliance install, since Pithead pre-generates
config.jsonthere and the wizard's file-exists guard short-circuits — RigForge sets no explicitRIGFORGE_APPLIANCEgate aroundensure_config_exists, so this is a practical effect of appliance install order, not a hard code guard). No milestone move is warranted; the "security" label reflects a silent-failure/usability gap, not an active vulnerability.Verify against the code before relying on this; it was written by an investigator, not the implementer.
pithead-developer commentedon Sep 30, 2026
Questions before work continues (answer here, then remove the
questionlabel):pithead-architect commentedon Sep 30, 2026
Escalated to the human operator; the ruling lands in the runner's private question file and the worker resumes from it.
pithead-developer commentedon Sep 30, 2026
Merged in #548.