Skip to content

Commit 59bddf2

Browse files
authored
Merge pull request #473 from p2pool-starter-stack/release/v1.4.0
release: v1.4.0
2 parents f03eca0 + 2b43e1b commit 59bddf2

66 files changed

Lines changed: 7618 additions & 187 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.gitignore

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,16 @@
11
# Secrets and Env
22
.env
33
.env.new
4+
.env.dryrun
45
.env.apply-incomplete
56
config.json
7+
config.json.bak-control
68
/data/
79
/build/monero/bitmonero.conf
810
/build/tari/config.toml
911
Caddyfile
12+
# One-time first-run epilogue marker (#384), dropped beside .env at runtime.
13+
.pithead-first-run-done
1014
# pithead backup archives bundle .env, config.json, the Caddyfile, and the Tor onion private keys
1115
# into one tarball; secret scanners can't see inside a gzipped tar, so keep the whole dir out (#369).
1216
/backups/

.gitleaks.toml

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,10 @@ useDefault = true
55
[allowlist]
66
description = "Accepted false positives"
77
regexTarget = "line"
8-
# curl auth assembled from shell ENV VARS (e.g. `-u "${USER:-}:${PASS:-}"`) is not a hardcoded
8+
# curl auth assembled from shell ENV VARS (e.g. `-u "${USER:-}:${PASS:-wallet}"`) is not a hardcoded
99
# secret — the upstream `curl-auth-user` rule can't distinguish `${VAR}` from a literal credential.
10-
# This pattern only matches env-var expansions, so a real `-u "admin:hunter2"` is still caught.
10+
# Both sides must be `${VAR:-default}` expansions (default optional), so a real `-u "admin:hunter2"`
11+
# is still caught.
1112
regexes = [
12-
'''-u "\$\{[A-Z_]+:-\}:\$\{[A-Z_]+:-\}"''',
13+
'''-u "\$\{[A-Z_]+:-[^}]*\}:\$\{[A-Z_]+:-[^}]*\}"''',
1314
]

CHANGELOG.md

Lines changed: 216 additions & 0 deletions
Large diffs are not rendered by default.

CODE_OF_CONDUCT.md

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
<!-- markdownlint-disable -->
2+
<!-- Verbatim Contributor Covenant v2.1 (https://www.contributor-covenant.org/version/2/1/code_of_conduct/);
3+
only the enforcement contact is filled in. Do not reword — markdownlint and docs-voice are disabled here. -->
4+
5+
# Contributor Covenant Code of Conduct
6+
7+
## Our Pledge
8+
9+
We as members, contributors, and leaders pledge to make participation in our community a harassment-free experience for everyone, regardless of age, body size, visible or invisible disability, ethnicity, sex characteristics, gender identity and expression, level of experience, education, socio-economic status, nationality, personal appearance, race, caste, color, religion, or sexual identity and orientation.
10+
11+
We pledge to act and interact in ways that contribute to an open, welcoming, diverse, inclusive, and healthy community.
12+
13+
## Our Standards
14+
15+
Examples of behavior that contributes to a positive environment for our community include:
16+
17+
* Demonstrating empathy and kindness toward other people
18+
* Being respectful of differing opinions, viewpoints, and experiences
19+
* Giving and gracefully accepting constructive feedback
20+
* Accepting responsibility and apologizing to those affected by our mistakes, and learning from the experience
21+
* Focusing on what is best not just for us as individuals, but for the overall community
22+
23+
Examples of unacceptable behavior include:
24+
25+
* The use of sexualized language or imagery, and sexual attention or advances of any kind
26+
* Trolling, insulting or derogatory comments, and personal or political attacks
27+
* Public or private harassment
28+
* Publishing others' private information, such as a physical or email address, without their explicit permission
29+
* Other conduct which could reasonably be considered inappropriate in a professional setting
30+
31+
## Enforcement Responsibilities
32+
33+
Community leaders are responsible for clarifying and enforcing our standards of acceptable behavior and will take appropriate and fair corrective action in response to any behavior that they deem inappropriate, threatening, offensive, or harmful.
34+
35+
Community leaders have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, and will communicate reasons for moderation decisions when appropriate.
36+
37+
## Scope
38+
39+
This Code of Conduct applies within all community spaces, and also applies when an individual is officially representing the community in public spaces. Examples of representing our community include using an official e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event.
40+
41+
## Enforcement
42+
43+
Instances of abusive, harassing, or otherwise unacceptable behavior may be reported to the community leaders responsible for enforcement via GitHub's private vulnerability reporting (the **Security** tab → **Report a vulnerability**), the same private channel described in [SECURITY.md](SECURITY.md). All complaints will be reviewed and investigated promptly and fairly.
44+
45+
All community leaders are obligated to respect the privacy and security of the reporter of any incident.
46+
47+
## Enforcement Guidelines
48+
49+
Community leaders will follow these Community Impact Guidelines in determining the consequences for any action they deem in violation of this Code of Conduct:
50+
51+
### 1. Correction
52+
53+
**Community Impact**: Use of inappropriate language or other behavior deemed unprofessional or unwelcome in the community.
54+
55+
**Consequence**: A private, written warning from community leaders, providing clarity around the nature of the violation and an explanation of why the behavior was inappropriate. A public apology may be requested.
56+
57+
### 2. Warning
58+
59+
**Community Impact**: A violation through a single incident or series of actions.
60+
61+
**Consequence**: A warning with consequences for continued behavior. No interaction with the people involved, including unsolicited interaction with those enforcing the Code of Conduct, for a specified period of time. This includes avoiding interactions in community spaces as well as external channels like social media. Violating these terms may lead to a temporary or permanent ban.
62+
63+
### 3. Temporary Ban
64+
65+
**Community Impact**: A serious violation of community standards, including sustained inappropriate behavior.
66+
67+
**Consequence**: A temporary ban from any sort of interaction or public communication with the community for a specified period of time. No public or private interaction with the people involved, including unsolicited interaction with those enforcing the Code of Conduct, is allowed during this period. Violating these terms may lead to a permanent ban.
68+
69+
### 4. Permanent Ban
70+
71+
**Community Impact**: Demonstrating a pattern of violation of community standards, including sustained inappropriate behavior, harassment of an individual, or aggression toward or disparagement of classes of individuals.
72+
73+
**Consequence**: A permanent ban from any sort of public interaction within the community.
74+
75+
## Attribution
76+
77+
This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 2.1, available at [https://www.contributor-covenant.org/version/2/1/code_of_conduct.html][v2.1].
78+
79+
Community Impact Guidelines were inspired by [Mozilla's code of conduct enforcement ladder][Mozilla CoC].
80+
81+
For answers to common questions about this code of conduct, see the FAQ at [https://www.contributor-covenant.org/faq][FAQ]. Translations are available at [https://www.contributor-covenant.org/translations][translations].
82+
83+
[homepage]: https://www.contributor-covenant.org
84+
[v2.1]: https://www.contributor-covenant.org/version/2/1/code_of_conduct.html
85+
[Mozilla CoC]: https://github.com/mozilla/diversity
86+
[FAQ]: https://www.contributor-covenant.org/faq
87+
[translations]: https://www.contributor-covenant.org/translations

CONTRIBUTING.md

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ The workflow for contributing bug fixes, docs changes, and features.
88
there first.
99
- Check the [open issues](https://github.com/p2pool-starter-stack/pithead/issues) for existing
1010
work on the same thing.
11+
- This project follows a [Code of Conduct](CODE_OF_CONDUCT.md); by participating you agree to uphold it.
1112

1213
## Dev environment
1314

@@ -36,11 +37,12 @@ runs `ruff` (plus a few hygiene hooks) on your changed files. If you change depe
3637
make test
3738
```
3839

39-
This runs everything CI does without a server or Docker:
40+
This runs everything CI does that doesn't need a live test server:
4041

4142
- **lint** — every file surface gets a linter/formatter check (`make lint` runs them all; run one
4243
with `make lint-<surface>`): `lint-sh` (shellcheck + shfmt), `lint-py` (ruff), `lint-js` (Biome),
43-
`lint-yaml` (yamllint), `lint-md` (markdownlint), `lint-proto` (buf), `lint-toml` (taplo). The
44+
`lint-yaml` (yamllint), `lint-md` (markdownlint), `lint-docs-voice` (banned-word check),
45+
`lint-proto` (buf), `lint-toml` (taplo). The
4446
non-Python tools run via `npx`/`uvx`/`docker`, so a contributor needs **Node, uv, and Docker**
4547
on PATH (plus `shfmt`); `pre-commit` runs the same checks on changed files. Link-checking
4648
(`lychee`) runs on a weekly schedule, not per-PR.

Makefile

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,9 +39,9 @@ test-integration: ## Run the live config-matrix integration suite (requires a te
3939
lint: lint-sh lint-py lint-js lint-yaml lint-md lint-docs-voice lint-proto lint-toml ## Lint/format-check every surface
4040

4141
lint-sh: ## shellcheck + shfmt over the CLI, build/* container scripts, release + test scripts
42-
shellcheck --severity=warning pithead scripts/*.sh build/*/*.sh tests/stack/run.sh tests/stack/test_compose.sh \
42+
shellcheck --severity=warning pithead pithead-completion.bash scripts/*.sh build/*/*.sh tests/stack/run.sh tests/stack/test_compose.sh \
4343
tests/inventory.sh tests/integration/*.sh tests/integration/mini-stack/*.sh
44-
shfmt -i 4 -d pithead $(shell git ls-files '*.sh')
44+
shfmt -i 4 -d pithead pithead-completion.bash $(shell git ls-files '*.sh')
4545

4646
lint-py: ## ruff lint + format check on all repo Python (ruff runs via uv from the locked dev extra)
4747
uv run --locked --project build/dashboard --extra dev ruff check .

README.md

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -36,8 +36,11 @@ a Tor daemon. The `pithead` script renders config, provisions Tor, and drives do
3636
guide](docs/privacy.md) maps every connection.
3737
- 🔌 **One endpoint for every rig.** Point all workers at a single address on port `3333`. No wallet
3838
address in the miner config; the stack routes the hashrate.
39-
- 📊 **Live dashboard.** Hashrate, the P2Pool/XvB split, the PPLNS window, and per-worker updates,
40-
served over HTTPS on your LAN.
39+
- 📊 **Live dashboard, now with config editing.** Hashrate, the P2Pool/XvB split, the PPLNS window,
40+
and per-worker updates over HTTPS on your LAN. Opt in with `dashboard.control.enabled` to edit
41+
`config.json`, one-click upgrade to a new release, and watch the access + config-change audit logs
42+
from the browser — every change gated host-side behind a login. See
43+
[The Dashboard](docs/dashboard.md).
4144
- 📟 **Telegram operator bot.** Opt-in alerts for a downed node, a worker that dropped off, sync
4245
finishing, low disk, a clearnet leak, or a sustained hashrate drop — plus a daily digest and
4346
read-only commands (`/status`, `/hashrate`, `/workers`, `/earnings`). Routed over Tor. See the
@@ -98,7 +101,7 @@ Full walkthrough: [docs/getting-started.md](docs/getting-started.md)
98101
| **[Getting Started](docs/getting-started.md)** | Prerequisites, install, first-run setup, and what to expect while the node syncs. |
99102
| **[Hardware Requirements](docs/hardware.md)** | Minimum vs. recommended specs for the stack host (CPU, RAM, disk, network), and how to run leaner. (Miner specs live in [RigForge](https://github.com/p2pool-starter-stack/rigforge).) |
100103
| **[Configuration](docs/configuration.md)** | Every `config.json` key, applying changes safely, reusing an existing node, and remote Monero nodes. |
101-
| **[The Dashboard](docs/dashboard.md)** | Sync Mode and a tour of the live operational view. |
104+
| **[The Dashboard](docs/dashboard.md)** | Sync Mode, a tour of the live operational view, and the opt-in control channel: editing config, one-click upgrades, and the audit logs from the browser. |
102105
| **[Connecting Miners](docs/workers.md)** | Point any existing rig at the stack, or spin up a tuned miner with [RigForge](https://github.com/p2pool-starter-stack/rigforge). |
103106
| **[Architecture](docs/architecture.md)** | The nine services, the privacy model, and the algorithmic XvB switching engine. |
104107
| **[Privacy & Network Egress](docs/privacy.md)** | Every off-box connection: what's Tor-routed, what's clearnet today, and how to harden it. |
@@ -191,8 +194,15 @@ Everything runs through `pithead` (`./pithead help` lists it all):
191194
| `./pithead logs [service]` | Follow logs (all, or one service). |
192195
| `./pithead status` | Container status + health-check of every expected service (warns on anything down). |
193196
| `./pithead doctor` | Read-only health report (deps, Docker, AVX2, HugePages, RAM/disk, onion state). |
194-
| `./pithead backup` | Save config, secrets, the Tor onion keys, and the dashboard's database to `backups/` (`--with-chains` adds blockchain data; `-y` / `--yes` skips the prompts). |
195-
| `./pithead restore <archive>` | Restore those files from a backup archive (asks before overwriting; `-y` / `--yes` skips the prompt). |
197+
| `./pithead version` | Print the installed stack version on one line (offline; also `-V` / `--version`). |
198+
| `./pithead backup` | Save config, secrets, the Tor onion keys, and the dashboard's database to a passphrase-encrypted archive under `backups/` (`--with-chains` adds blockchain data; `--no-encrypt` writes plaintext; `-y` / `--yes` skips the prompts). |
199+
| `./pithead restore <archive>` | Restore those files from a backup archive, encrypted or plaintext (asks before overwriting; `-y` / `--yes` skips the prompt). |
200+
| `./pithead rotate-secrets` | Regenerate the stack's internal credentials after a suspected leak — see [Rotating the internal secrets](docs/operations.md#rotating-the-internal-secrets). |
201+
202+
Commands chain in one call (`./pithead apply upgrade` runs both, stopping on the first failure;
203+
nonsense like `up down` is rejected before anything runs), and `source pithead-completion.bash`
204+
adds bash/zsh tab-completion — see
205+
[Operations › Chaining commands](docs/operations.md#chaining-commands).
196206

197207
Full reference: **[Operations & Maintenance](docs/operations.md)**.
198208

SECURITY.md

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,9 +39,62 @@ The stack's defaults:
3939
run with `no-new-privileges` and drop all Linux capabilities; internet-facing and
4040
Docker-socket-facing services also use a read-only root filesystem.
4141
- SHA256-verified, version-pinned binaries.
42+
- Signed releases, verified before upgrade
43+
([#376](https://github.com/p2pool-starter-stack/pithead/issues/376)): every published image
44+
digest and the install bundle carry a cosign key signature made on the release box; only the
45+
public key (`cosign.pub`) is committed, and it ships in every bundle. `pithead upgrade` and the
46+
dashboard's one-click upgrade verify against it before anything is pulled or extracted, and fail
47+
closed while a key is present — a bad signature, a stripped `.sig`, or a missing cosign binary
48+
aborts the upgrade. The bundle check anchors trust in the key *already on disk*, so a malicious
49+
bundle cannot vouch for itself with a swapped key, and because a signature binds bytes rather
50+
than a version, the dashboard upgrade also refuses a bundle whose own `VERSION` does not match
51+
the requested tag — closing a rollback to an older, validly-signed release. Limits: installs
52+
without `cosign.pub` (releases before signing landed) upgrade unverified with a warning; a
53+
compromise of the release box itself — which holds the private key — is outside what a signature
54+
can prove; and the CLI image-verify checks the tag, then pulls it in a separate step (a
55+
verify-then-pull window tracked as a follow-up). See
56+
[Releasing › Signed releases](docs/releasing.md#signed-releases).
4257
- Localhost-only RPC.
4358
- LAN-scoped (and narrowable) stratum port.
4459
- Scoped Docker socket proxies.
4560
- Tor for all node networking.
61+
- A one-way host-control boundary for dashboard config editing and upgrades (`dashboard.control`,
62+
default off): the dashboard container can only *ask* — it writes typed JSON intents into a spool
63+
directory whose other legs (staged configs, results, the audit log) are host-owned and mounted
64+
read-only. A root systemd unit re-validates every intent with pithead's own config validation
65+
and dispatches exactly three fixed actions (`apply --dry-run`, `apply -y`, and a release
66+
upgrade); no string from the container is ever executed. The upgrade intent carries only the
67+
version the operator confirmed: the runner re-derives the target itself from the GitHub release
68+
API (over the stack's Tor SOCKS), refuses any mismatch or non-release tag, and limits attempts
69+
to one per 10 minutes — the container cannot choose an image, tag, or registry. Enabling the
70+
channel without a dashboard password is a validation error, on a published onion it additionally
71+
requires Tor client authorization, and every mutation is audited host-side. Commits are default-denied against an explicit allowlist of
72+
operational settings: a commit that changes any env key off that list — in every direction
73+
(enabling, changing, or disabling) — is refused, as is anything the change preview flags
74+
destructive. Wallets, dashboard auth and onion exposure, the control channel itself, the Tor
75+
egress firewall, clearnet toggles, node endpoints, binds, and every credential are off the
76+
list, and a key added in the future stays un-committable until deliberately listed. Those
77+
edits must be applied from the host CLI; out-of-band approval is tracked in
78+
[#338](https://github.com/p2pool-starter-stack/pithead/issues/338).
79+
- Attack visibility (#349): Caddy writes a JSON access log for every dashboard vhost (LAN and
80+
onion), and the control channel's host-side audit log records who changed what (setting names
81+
only, never values). The dashboard surfaces both read-only — a burst of 401s is the
82+
rotate-the-password signal — and treats every logged field as hostile input: strings are
83+
whitelisted to a safe character set before display, because the access log echoes
84+
attacker-chosen bytes (request paths, attempted usernames) and rendering them raw would hand an
85+
anonymous prober stored XSS against the operator. Both logs are size-bounded (Caddy's native
86+
rolling; a trim-before-append cap in the audit writer). Neither ever records a secret: Caddy
87+
redacts credential headers by default, and the audit writer logs key names only.
88+
89+
### Secret trust boundary for dashboard config editing
90+
91+
When `dashboard.control` is on, the dashboard reads `config.json` through a **read-only bind
92+
mount** to prefill the editor form. The API masks every secret leaf before serving it to the
93+
browser — but that masking protects the *browser*, not the container. The bind mount itself is the
94+
real secret boundary: a backend compromise of the dashboard container can read the plaintext
95+
`config.json` (including the dashboard login and stratum passwords) directly off the mount,
96+
regardless of the API masking. Treat the dashboard container as semi-trusted, keep the onion behind
97+
Tor client authorization, and do not co-host untrusted workloads in that container. Host-side
98+
staged copies that carry merged secrets are written mode 600.
4699

47100
Report any gap in these.

VERSION

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
1.3.1
1+
1.4.0

0 commit comments

Comments
 (0)