Commit Graph

5 Commits

Author SHA1 Message Date
roof 238db60702 feat: secure build phase 1 — cosign cell-side image verification (warn default) + Dockerfile validation
Unit Tests / test (push) Successful in 13m28s
- config/cosign/cosign.pub: public verification key committed to repo (safe);
  cosign private key lives in /home/roof/.pic-secrets/ and is NEVER committed
- api/config_manager.py: image_verification config block (modes: off|warn|enforce,
  default: warn) so existing deployments are unaffected until images are signed
- api/service_composer.py: cosign verify before pull/up; enforce aborts the
  operation, warn logs and proceeds, off skips entirely; also fixes the prior
  unsafe proceed-on-pull-failure path
- api/service_store_manager.py: store-image digest requirement (warn default,
  reject under enforce)
- api/Dockerfile: cosign binary copied from the official cosign image
- docker-compose.yml: config/cosign/ bind-mounted into cell-api container
- install.sh: ensure/verify bundled cosign pubkey on new cell installs
- api/manifest_validator.py: validate_build_context() — Dockerfile lint
- tests: full coverage for config modes, composer verify paths, store digest
  guard, and validate_build_context

Verification defaults to warn so nothing breaks in production until images are
signed (phase 2). Private key stored outside git at /home/roof/.pic-secrets/.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-06-11 03:53:47 -04:00
roof f4b8d5c4f7 harden containers: drop WG privileged, slim images, digest pins; fix WG path + empty chrony.conf
Unit Tests / test (push) Successful in 12m16s
Security — WireGuard:
- Replace linuxserver/wireguard (privileged + SYS_MODULE + /lib/modules) with a
  bespoke alpine image (wireguard/Dockerfile + entrypoint.sh): CAP_NET_ADMIN only,
  119 MB → 14.7 MB. Modern kernels (≥5.6) have WireGuard built in; no module
  loading required. Kernel-fallback comment left in compose for rare old kernels.

Security — supply-chain digest pins:
- CoreDNS image pinned by SHA-256 digest in docker-compose.yml.
- api/Dockerfile: python:3.11-slim and docker:27-cli pinned by digest.
- webui/Dockerfile: node:20-alpine and nginxinc/nginx-unprivileged:alpine pinned.
- ntp/Dockerfile: alpine:3.20 pinned by digest.
- wireguard/Dockerfile: alpine:3.20 pinned by digest.

Security — webui non-root:
- Switch from nginx:alpine (root, port 80) to nginxinc/nginx-unprivileged:alpine
  (port 8080, runs as nginx uid 101). Compose port mapping and all Caddy upstream
  references updated: cell-webui:80 → cell-webui:8080 everywhere.

API layer reduction (561 MB → 245 MB):
- Multi-stage api/Dockerfile: docker CLI copied from docker:27-cli stage instead
  of being installed via apt from Docker's external repo (removes GPG key fetch,
  lsb-release, gnupg, two apt-get update rounds). --no-install-recommends on
  remaining apt install. mkdir folded into the same RUN layer.

Bug fix — WireGuard config path mismatch:
- setup_cell.py wrote wg0.conf to config/wireguard/wg0.conf but wireguard_manager
  and the new entrypoint expect config/wireguard/wg_confs/wg0.conf (the standard
  wg-quick sub-directory). Fixed by creating the wg_confs/ sub-dir and writing
  there; REQUIRED_DIRS updated to pre-create it.

Bug fix — empty chrony.conf:
- config/ntp/chrony.conf was 0 bytes (pre-existing gap); added a real config
  (pool.ntp.org + Cloudflare, allow 172.20/10.0, local stratum 10, driftfile,
  makestep, rtcsync). NTP compose service now builds from ./ntp instead of
  pulling alpine:latest and running apk at every container start.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-06-10 14:07:54 -04:00
roof 9d7d74f3f4 fix: full-tunnel default, real host routing table, peer config tunnel mode
- WireGuard default changed to full tunnel (0.0.0.0/0) — all peer traffic
  routes through PIC server so internet latency matches server's clean 41ms
- UI tunnel toggle now defaults to Full tunnel
- API /peers/config accepts allowed_ips param so UI toggle wires through
- Routing page reads real host routes via /proc/1/net/route (pid: host)
  instead of mock data; shows ens18/192.168.31.1 correctly
- Add iproute2 + util-linux to API Dockerfile

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-20 15:20:55 -04:00
Constantin f0b6d1cff1 wip: make work Services Status 2025-09-13 14:23:31 +03:00
Constantin 2277b11563 init 2025-09-12 23:04:52 +03:00