Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,9 @@ per the process in [`docs/releasing.md`](docs/releasing.md).
writes its SQLite history into a host-user-owned volume as root. Caddy and the two Docker
socket proxies additionally run with a read-only root filesystem (ephemeral `tmpfs` for
scratch; Caddy's certs persist in `caddy_data`).
- Log rotation (`json-file`, 10 MB × 3) now applies to **every** service — `caddy`,
`docker-proxy`, and `docker-control` previously fell back to Docker's uncapped default, so
their logs could grow without bound and fill the disk on a long-running host (#123).

### Security

Expand All @@ -70,3 +73,6 @@ per the process in [`docs/releasing.md`](docs/releasing.md).
environment via a script.
- Documented that the stratum port defaults to all interfaces and should be firewalled to the
LAN — see [Connecting Miners › Firewall](docs/workers.md#firewall).
- All externally-pulled base/runtime images are now pinned by immutable `@sha256` digest
(caddy, docker-socket-proxy, the Tari node, and the `ubuntu`/`python`/`alpine` build bases),
so a re-pushed tag or a registry MITM can't silently change the running image (#135).
3 changes: 2 additions & 1 deletion build/dashboard/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
# ==========================================================================
# Shared base: system deps + package metadata + source.
# ==========================================================================
FROM python:3.11-slim AS base
# Pinned by digest (#135) so the python:3.11-slim tag can't be silently re-pointed.
FROM python:3.11-slim@sha256:a3ab0b966bc4e91546a033e22093cb840908979487a9fc0e6e38295747e49ac0 AS base

# System dependencies.
RUN apt-get update && apt-get install -y --no-install-recommends \
Expand Down
3 changes: 2 additions & 1 deletion build/monero/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
FROM ubuntu:24.04
# Pinned by digest (#135) so the ubuntu:24.04 tag can't be silently re-pointed.
FROM ubuntu:24.04@sha256:786a8b558f7be160c6c8c4a54f9a57274f3b4fb1491cf65146521ae77ff1dc54

# Install system dependencies required for downloading, verifying, and configuring the node
# 'gettext-base' provides 'envsubst' for template processing in entrypoint.sh
Expand Down
3 changes: 2 additions & 1 deletion build/p2pool/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
FROM ubuntu:24.04
# Pinned by digest (#135) so the ubuntu:24.04 tag can't be silently re-pointed.
FROM ubuntu:24.04@sha256:786a8b558f7be160c6c8c4a54f9a57274f3b4fb1491cf65146521ae77ff1dc54

ARG P2POOL_VERSION=v4.15.1
ARG P2POOL_HASH=efd8b23579774711a5b86743da980e0936b7c220894063296719116d7f9ba254
Expand Down
4 changes: 3 additions & 1 deletion build/tor/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
FROM alpine:latest
# Pinned by digest (#135). NOTE: still the floating `latest` tag — a follow-up could move this to a
# specific alpine version; the digest already makes the build reproducible regardless.
FROM alpine:latest@sha256:5b10f432ef3da1b8d4c7eb6c487f2f5a8f096bc91145e68878dd4a5019afde11

# Install Tor plus the tools the bootstrap healthcheck needs: netcat (talk to the
# control port) and xxd (hex-encode the auth cookie). --no-cache keeps the image small.
Expand Down
3 changes: 2 additions & 1 deletion build/xmrig-proxy/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
FROM ubuntu:24.04
# Pinned by digest (#135) so the ubuntu:24.04 tag can't be silently re-pointed.
FROM ubuntu:24.04@sha256:786a8b558f7be160c6c8c4a54f9a57274f3b4fb1491cf65146521ae77ff1dc54

# Define XMRig Proxy version and SHA256 hash for binary verification
# Refer to https://github.com/xmrig/xmrig-proxy/releases for validation
Expand Down
12 changes: 8 additions & 4 deletions docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,8 @@ services:

# --- Tari Base Node ---
tari:
image: quay.io/tarilabs/minotari_node:v5.3.1-mainnet
# Pinned by digest (#135) so the v5.3.1-mainnet tag can't be silently re-pointed.
image: quay.io/tarilabs/minotari_node:v5.3.1-mainnet@sha256:824fd6ec21d618805317d7eede374d6782906eeae17d2fc8aaad4df6205f94e0
container_name: tari
restart: unless-stopped
stop_grace_period: 1m
Expand Down Expand Up @@ -288,9 +289,10 @@ services:
# POST stays off, so this proxy can never write — container control goes through the
# separate, tightly-scoped docker-control proxy below.
docker-proxy:
image: tecnativa/docker-socket-proxy:v0.4.2
image: tecnativa/docker-socket-proxy:v0.4.2@sha256:1f3a6f303320723d199d2316a3e82b2e2685d86c275d5e3deeaf182573b47476
container_name: docker-proxy
restart: unless-stopped
logging: *default-logging
security_opt:
- no-new-privileges:true
cap_drop:
Expand Down Expand Up @@ -318,9 +320,10 @@ services:
# (create/kill/exec/reads). Kept separate from the read-only proxy above so opening POST
# here can't widen that proxy's container access.
docker-control:
image: tecnativa/docker-socket-proxy:v0.4.2
image: tecnativa/docker-socket-proxy:v0.4.2@sha256:1f3a6f303320723d199d2316a3e82b2e2685d86c275d5e3deeaf182573b47476
container_name: docker-control
restart: unless-stopped
logging: *default-logging
security_opt:
- no-new-privileges:true
cap_drop:
Expand All @@ -345,9 +348,10 @@ services:
# Bridges the local 127.0.0.1 application binding to the LAN
# Serves HTTPS or HTTP depending on configuration
caddy:
image: caddy:2.11
image: caddy:2.11@sha256:cb9d71ad83182011b79355cd57692686374bd78d6fe327efe0ff8507da03ab13
container_name: caddy
restart: unless-stopped
logging: *default-logging
network_mode: "host"
# Drop all capabilities, then add back only NET_BIND_SERVICE — Caddy serves the dashboard on
# :80/:443 (privileged ports) and would otherwise fail to bind once ALL caps are dropped (#90).
Expand Down
10 changes: 10 additions & 0 deletions tests/stack/test_compose.sh
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,16 @@ expect_present "monerod healthcheck via script" "monerod-healthcheck.sh"
expect_present "p2pool healthcheck via script" "p2pool-healthcheck.sh"
expect_absent "no get_info (creds) in compose healthcheck" "get_info"

# Log rotation (#123): every service must carry the json-file size cap, including caddy and the two
# socket proxies that previously fell back to Docker's uncapped default. All 9 services (monerod is
# present under the local_node profile in this env) render one `max-size` line each.
expect_min "log rotation on every service" "max-size:" 9
# Image digest pinning (#135): the externally-pulled images must reference an immutable @sha256
# digest, not just a mutable tag, so a re-pushed tag can't silently change the running image.
expect_present "tecnativa socket-proxy pinned by digest" "tecnativa/docker-socket-proxy:v0.4.2@sha256:"
expect_present "caddy pinned by digest" "caddy:2.11@sha256:"
expect_present "tari node pinned by digest" "minotari_node:v5.3.1-mainnet@sha256:"

if [ "$fails" -ne 0 ]; then
echo " ✗ $fails hardening check(s) failed"
exit 1
Expand Down
Loading