From a41d61e9adf0ba9743b33a002ebf68a922e1418c Mon Sep 17 00:00:00 2001 From: clawbot <35+clawbot@noreply.example.org> Date: Fri, 6 Nov 2026 20:14:18 +0100 Subject: [PATCH] Install the image's Ubuntu packages from the normal mirrors (closes #190) The image's `ca-certificates`, `nix-bin` and `runit` now come from Ubuntu's archive instead of a dated snapshot, whose service had failed image builds. apt fetches them over plain HTTP and checks each against the archive's signed package lists, so no CA certificates are borrowed from the Go image. The README, `SPEC.md` and `docs/image.md` say so; the amd64-only limit, which came from the removed hash check, is gone. Rule cut against: `REPO_POLICIES.md` pins every external reference by hash; sneak's ruling at https://git.eeqj.de/sneak/prompts/issues/72#issuecomment-165196 allows Ubuntu's own package index. Model: deepseek-v4-pro (implementation), opus-5-5 (rework) --- Dockerfile | 29 ++++------------------------- README.md | 7 +++---- SPEC.md | 15 +++------------ docs/image.md | 9 +++------ 4 files changed, 13 insertions(+), 47 deletions(-) diff --git a/Dockerfile b/Dockerfile index 7811799..300708e 100644 --- a/Dockerfile +++ b/Dockerfile @@ -133,32 +133,11 @@ RUN mkdir /etc/sysusers.d \ && echo 'u _runit-log - "runit svlogd user" /nonexistent /sbin/nologin' \ > /etc/sysusers.d/runit.conf -# ca-certificates, nix-bin and runit, from Ubuntu's archive as it was at -# the snapshot moment, which is never earlier than the Ubuntu image above. -# apt checks every package against the snapshot's InRelease files, and -# this step checks those against the hashes named here, which are those -# of the amd64 archive: other architectures use Ubuntu's ports archive. -# apt also fetches the live archive's InRelease files, which change daily -# and which the install does not use. The snapshot service is HTTPS only -# and this image has no CA certificates yet, so this step uses the Go -# image's. The snapshot service answers 503 at times; apt retries a -# failed download, waiting twice as long before each retry, and this -# step gives it five retries, about half a minute in all, where its -# default of three gives up after seven seconds. -RUN --mount=type=bind,from=builder,source=/etc/ssl/certs/ca-certificates.crt,target=/tmp/go-image-ca.crt \ - apt-get update --snapshot 20261001T000000Z \ - -o Acquire::https::CaInfo=/tmp/go-image-ca.crt \ - -o Acquire::Retries=5 \ - && printf '%s\n' \ - '45f95ce276cdba3e41870516a130e03c58b8b7a79e9546b0efe9e526d255740c snapshot.ubuntu.com_ubuntu_20261001T000000Z_dists_resolute_InRelease' \ - '802e675dd9de4c7f3916434a95e7c1d8eec0e82886622d7805ab19a2c6fe0365 snapshot.ubuntu.com_ubuntu_20261001T000000Z_dists_resolute-updates_InRelease' \ - '64b3353f0bd4970b4f7271962245bcea9ff24d4cc7bea16b433f8a60e42ca3dd snapshot.ubuntu.com_ubuntu_20261001T000000Z_dists_resolute-backports_InRelease' \ - '1d5041572116a8b23aabf79ac7439ad8af83d57ad3fb0f9aa0d4523ec10c5908 snapshot.ubuntu.com_ubuntu_20261001T000000Z_dists_resolute-security_InRelease' \ - | (cd /var/lib/apt/lists && sha256sum --check --strict) \ +# ca-certificates, nix-bin and runit, from Ubuntu's archive. apt fetches +# them over plain HTTP and checks each one against the archive's signed +# package lists, so no CA certificates are needed. +RUN apt-get update \ && DEBIAN_FRONTEND=noninteractive apt-get install --yes --no-install-recommends \ - --snapshot 20261001T000000Z \ - -o Acquire::https::CaInfo=/tmp/go-image-ca.crt \ - -o Acquire::Retries=5 \ ca-certificates nix-bin runit \ && rm -rf /var/lib/apt/lists/* diff --git a/README.md b/README.md index 4c83480..257acfc 100644 --- a/README.md +++ b/README.md @@ -69,8 +69,7 @@ Not built, and not planned: ### The image No image is published. Build it from a clone. `make docker` runs the tests and -the linter, then builds the image, tagged `smallwebwaf`. It builds for amd64, on -an amd64 host only. +the linter, then builds the image, tagged `smallwebwaf`. ```sh git clone https://git.eeqj.de/sneak/smallwebwaf.git @@ -662,8 +661,8 @@ aside as `.bad`, and never stops the running process (see ### The image and its processes -- The image is built on Ubuntu 26.04 LTS, pinned by digest, with its packages - from a snapshot of Ubuntu's archive and nixpkgs fixed at one release. An app's +- The image is built on Ubuntu 26.04 LTS, pinned by digest. Its Ubuntu packages + come from Ubuntu's archive, and nixpkgs is fixed at one release. An app's `Dockerfile` installs a package with `nix-env -iA nixpkgs.` and gets the same package each time it is built (see [`docs/image.md`](docs/image.md)). - runit, a service supervisor, runs `smallwebwaf` as the `smallwebwaf` user (uid diff --git a/SPEC.md b/SPEC.md index d2d6f01..b8aec68 100644 --- a/SPEC.md +++ b/SPEC.md @@ -1544,20 +1544,11 @@ It sets no `ENTRYPOINT` or `USER` of its own. The container must start - The image is Ubuntu's newest long-term support release, pinned by digest, and moves to the next LTS release when that ships. Its packages come from Ubuntu's - snapshot service, the archive as it was at the moment the Dockerfile names, - rather than the live archive, whose packages change with every update. The - snapshot is never older than the pinned Ubuntu image, since older packages can - need older versions of packages the image holds, and it moves forward with the - image's digest. The Dockerfile names the hash of each of the snapshot's - `InRelease` files, which cover every package list and so every package, and - the build checks them before installing. The live archive's `InRelease` files, - which `apt-get update` also fetches and the install does not use, are left out - of the check. The hashes are the amd64 archive's, so the image is built for - amd64 only. + archive, whose packages change with every update. - The Ubuntu image has no CA certificates. Without them Nix cannot download packages and `servewaf` cannot reach GeoJS, so `ca-certificates` is installed - by name. The snapshot itself is fetched over HTTPS with the CA certificates of - the Go image that builds `smallwebwaf`, itself pinned by digest. + by name. apt fetches the packages over plain HTTP and checks each one against + the archive's signed package lists, so the install needs no CA certificates. - nixpkgs comes from a release file on `releases.nixos.org`, named with its hash, not from a GitHub archive, whose bytes can change. Root uses Nix directly; no Nix daemon runs. `nix-bin` creates no build users, so diff --git a/docs/image.md b/docs/image.md index 126532c..2e99289 100644 --- a/docs/image.md +++ b/docs/image.md @@ -8,8 +8,7 @@ is pinned that way. ## Contents - Ubuntu 26.04 LTS, pinned by digest. -- `ca-certificates`, `nix-bin` and `runit` from Ubuntu, from the snapshot of its - archive at `20261001T000000Z`. +- `ca-certificates`, `nix-bin` and `runit` from Ubuntu's archive. - Nix, with nixpkgs `nixos-26.05.11045.774debe7a0d1` set up for root as `nixpkgs`. No Nix daemon; `build-users-group =` in `/etc/nix/nix.conf`. Root's Nix profile, `/nix/var/nix/profiles/default/bin`, last on the `PATH`. @@ -26,10 +25,8 @@ is pinned that way. ## Pins -- Ubuntu's packages: the snapshot service, `--snapshot 20261001T000000Z` on both - `apt-get update` and `apt-get install`. The SHA-256 hash of each of the - snapshot's `InRelease` files is named in the `Dockerfile` and checked after - `apt-get update`. The hashes are the amd64 archive's. +- Ubuntu's packages are not pinned: they come from the live archive, whose + packages change with every update. - nixpkgs: the release file `nixexprs.tar.xz` of `nixos-26.05.11045.774debe7a0d1` on `releases.nixos.org`, named with its SHA-256 hash. -- 2.54.0