Commit Graph
4 Commits
Author SHA1 Message Date
shadowdaoandClaude Opus 5.5 d1547f3418 ci: pin base images by digest resolved directly from Docker Hub
With the pkg-cache BuildKit mirror on, `FROM almalinux/10-base` was resolved
by tag through the cache, so a compromised cache could substitute the image.

Each job using the mirror now looks up the base tag's digest DIRECTLY at
registry-1.docker.io (.gitea/scripts/resolve-base-image.sh, HTTPS, HEAD on
the manifest, regex-validated) and builds FROM image@sha256:... via the
BASE_IMAGE build-arg, so the mirror can only serve content-addressed blobs.
If the lookup fails, the mirror is NOT used for that job and the tag is pulled
straight from Docker Hub. The digest is resolved every run (no manual bumps);
local builds default to the tag.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-22 06:58:16 -07:00
shadowdaoandClaude Opus 5.5 2b9e7f302c ci: enable PKG_CACHE via a TLS probe that falls back to upstream; host repo tool
- build-push.yaml: Build-and-Push, Build-FPM-Images, Build-Shared-httpd
  and Build-Shared-OLS probe https://192.168.1.40 and :5000 with the
  pinned pkg-cache CA (5 s timeouts). When the cache answers they pass
  PKG_CACHE and configure the BuildKit Docker Hub mirror (ca=). When it
  doesn't, they build from upstream exactly as before and emit a warning.
  Fallback measured from the runner bridge: refused <1 s, silent drop 10 s.
- scripts/host/pkgcache-host-repos.sh: apply/revert/status for WHP hosts.
  Each rewritten repo uses baseurl=<cache> <origin> as the real fallback;
  mirrorlist/metalink stay commented because measured dnf ignores baseurl
  when they are present. Keeps gpgcheck=1 / repo_gpgcheck=1 and backs up
  every file. Tested on 192.168.1.148, including cache-down and
  silent-drop fallback.
- docs: runner firewall rule (applied), measured fallback results.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-21 16:46:03 -07:00
shadowdaoandClaude Opus 5.5 18f65c6d84 fix(pkg-cache): HTTPS-only cache, GPG-verified release RPMs, strict restore
Security review follow-up for the opt-in PKG_CACHE path:

- PKG_CACHE must be https:// (http is refused). The cache's certificate
  comes from a name-constrained internal CA (keys/pkg-cache/ca.crt, valid
  only for 192.168.1.40 / pkg-cache.*). The CA is trusted only by the
  rewritten repos (dnf sslcacert bundle, apt per-host CaInfo) and only
  for the duration of the RUN.
- epel-release / remi-release are no longer installed straight from a
  URL. release-install downloads them over HTTPS, checks the package name,
  imports the signing keys committed in keys/pkg-cache/ and requires
  `rpm -K` "signatures OK", then installs with localpkg_gpgcheck=1. This
  applies with and without the cache.
- Rewritten repos get gpgcheck=1. Remi and AlmaLinux also get
  repo_gpgcheck=1, since both sign repomd.xml. EPEL does not publish a
  repomd signature, so it relies on end-to-end HTTPS.
- restore also deletes files it created and any new repo/apt file that
  still references the cache, then fails the build if a reference remains
  under /etc/yum.repos.d, /etc/dnf or /etc/apt.
- docs: trust model, replay risk, proposed openssl/httpd/ImageMagick
  minimum-version gates, TLS registry mirror (BuildKit ca= / dockerd
  certs.d, no insecure-registries).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-21 12:53:24 -07:00
shadowdaoandClaude Opus 5.5 b2bec5b3ee feat(build): opt-in PKG_CACHE build arg for the internal package cache
Adds scripts/pkg-cache-repos.sh and wires it into Dockerfile,
Dockerfile.fpm, Dockerfile.shared-httpd and Dockerfile.shared-ols. With
--build-arg PKG_CACHE=http://192.168.1.40 (CT130 pkg-cache), dnf/apt go
through the LAN cache. That cache fetches from the Remi/EPEL/AlmaLinux/
Ubuntu/LiteSpeed origins over HTTPS, with fallback tiers and
stale-on-error. Without the arg the script is a no-op and builds are
unchanged.

- rpm: each baseurl becomes "<cache>/<prefix>/... <origin>/...", so dnf
  fails over to the origin if the cache dies mid-build
- every RUN restores the original repo files before it ends, so no
  shipped layer carries the LAN address
- EPEL/Remi release RPMs come from the cache when it is set
- the php.net version gates are untouched

Dockerfile.litespeed/.lsphp are not wired yet (see docs/pkg-cache.md).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-21 12:29:54 -07:00