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>
This commit is contained in:
shadowdaoandClaude Opus 5.5 committed 2026-10-21 12:53:24 -07:00
1 parent b2bec5b3ee
commit 18f65c6d84
10 files changed
+411 -134

No files matched your search

+5 -3
View File
@@ -1,15 +1,17 @@
FROM almalinux/10-base
# OPTIONAL internal package cache, e.g. --build-arg PKG_CACHE=http://192.168.1.40
# (CT130 pkg-cache). Unset = upstream repositories exactly as before. Repo files
# OPTIONAL internal package cache, e.g. --build-arg PKG_CACHE=https://192.168.1.40
# (CT130 pkg-cache, https only). Unset = upstream repositories. Release RPMs are
# GPG-verified against keys/pkg-cache/ either way. Repo files
# are restored at the end of every RUN, so no layer keeps the cache address.
# See scripts/pkg-cache-repos.sh.
ARG PKG_CACHE=
COPY ./scripts/pkg-cache-repos.sh /usr/local/sbin/pkg-cache-repos.sh
COPY ./keys/pkg-cache/ /usr/local/share/pkg-cache/
# Install Apache and minimal dependencies (no PHP at all)
RUN /usr/local/sbin/pkg-cache-repos.sh rpm && \
dnf install -y $(/usr/local/sbin/pkg-cache-repos.sh release-urls | cut -d' ' -f1) && \
/usr/local/sbin/pkg-cache-repos.sh release-install epel && \
/usr/local/sbin/pkg-cache-repos.sh rpm && \
dnf update -y && \
dnf install -y httpd mod_ssl openssl iproute cronie procps curl && \