feat: the keel-web package and its recipe, on Core (0041 step 7) #1

Merged
marcos-mendez merged 6 commits from feat/keel-web-package into master 2026-10-01 18:28:00 -03:00
marcos-mendez commented 2026-10-01 16:30:23 -03:00 (Migrated from github.com)

Step 7 of handbook decision 0041: the keel-web package and its recipe, on the Core layer (bt-layer web --parent core).

  • packages/keel-web: the appliance manifest of Keel Web (the format's worked example) as /usr/share/keel/appliances/web.yaml; /etc/nginx/sites-available/default-anubis, Debian's default site behind Anubis; /usr/lib/keel/overlays/anubis/state.d/50keel-web, the state hook that swaps that front in for Debian's default site while the anubis overlay is enabled, and back; a postrm that takes the front out on purge. Depends on keel-core, the three Web overlays (common#21) and keel (>= 0.15.0).
  • Recipe: plan/main installs keel-web; conf.d/main fails the build unless the image is in the simple state (no Anubis key, no hook record, Anubis disabled, Coraza not linked, Debian's default site enabled).
  • CI as keel-core's: lxc-trixie.yml for build, lintian and package.bats; test-shell.yml at 100 percent; test-appliance.yml with allow_unpublished until the web layer is published.

Needs Keel-Linux/keel#63 (keel 0.15.0 runs the overlays' state hooks: Coraza's, which has no unit, and this package's); merge that first. Keel-Linux/apt's conf/appliances does not list web yet; the test build added web core in its own tree.

Until keel renders the sites of decision 0042, the default site is the one site Keel Web serves, which is why the Anubis front is this package's and not keel's.

Test plan

  • tests/package.bats (20), tests/anubis-front.bats (22), tests/image-conf.bats (10), written first; the three shell files at 100 percent under kcov; lintian clean
  • isolated build on the build host, core then web from this branch (060d14f) and keel#63, staged with keel-release; booted in LXC (results below)

On the built image

  • Simple: Nginx serves the default site (200, the page this recipe ships); Coraza's module not linked, nginx -T has no coraza directive, a Core Rule Set payload gets 200; anubis@keel disabled and inactive. Monit's file: units and probes of sshd, webmin, postfix and nginx only; monit -t passes. A second apply: 0 changes.
  • keel manifest validate passes; keel manifest show web --resolved prints the Web table of 0041 (overlays and ports as the format has them).
  • Cloud simple, set in /etc/keel/instance.yaml and applied with keel spec apply --system (17 changes: CrowdSec's identity and units, Coraza's hook, anubis@keel, then this package's hook): CRS payload 403; Firefox user agent gets Anubis's challenge; Googlebot's user agent from 2001:4860:4801:10::1 gets the page (625 bytes), Googlebot's user agent from the test host is challenged. The Google address was simulated: a test-only conf.d file trusted the build host (set_real_ip_from, real_ip_header X-Forwarded-For, the header case of 0042's web.real_ip), and Anubis logged x-real-ip: 2001:4860:4801:10::1. Monit adds crowdsec, firewall-bouncer, anubis and waf-blocks. A second apply: 0 changes.
  • Back to simple through the spec: the hooks put Debian's default site back and unload Coraza, 13 changes.

Two fixes came from that run: the recipe ships the default page (common's removelist deletes /var/www/html, so the first image answered 404), and the socket Anubis reads is served without gzip, since under Coraza a gzip static answer is empty (Keel-Linux/libnginx-mod-http-coraza#2).

Image: pre-release testing-19.0-1-step7-20261001 of this repository.

After review

  • The front only ever replaces Debian's unedited default link; with no Debian link it changes nothing and says so. The record is written before the link goes.
  • gzip off on the socket is gone: Anubis asks the socket for gzip and passes it on to a client that accepts it (measured), so it cost browsers compression. The empty-gzip bug is handled for every site by Keel-Linux/common#25 (keel-overlay-coraza 0.1.1, now a Depends) and fixed in the module by Keel-Linux/libnginx-mod-http-coraza#3.
  • Merge order: keel#63, common#25, then this. The testing image predates these commits (built from 060d14f).
Step 7 of handbook decision 0041: the `keel-web` package and its recipe, on the Core layer (`bt-layer web --parent core`). - `packages/keel-web`: the appliance manifest of Keel Web (the format's worked example) as `/usr/share/keel/appliances/web.yaml`; `/etc/nginx/sites-available/default-anubis`, Debian's default site behind Anubis; `/usr/lib/keel/overlays/anubis/state.d/50keel-web`, the state hook that swaps that front in for Debian's default site while the `anubis` overlay is enabled, and back; a postrm that takes the front out on purge. Depends on keel-core, the three Web overlays (common#21) and keel (>= 0.15.0). - Recipe: `plan/main` installs `keel-web`; `conf.d/main` fails the build unless the image is in the simple state (no Anubis key, no hook record, Anubis disabled, Coraza not linked, Debian's default site enabled). - CI as keel-core's: `lxc-trixie.yml` for build, lintian and `package.bats`; `test-shell.yml` at 100 percent; `test-appliance.yml` with `allow_unpublished` until the web layer is published. Needs Keel-Linux/keel#63 (keel 0.15.0 runs the overlays' state hooks: Coraza's, which has no unit, and this package's); merge that first. Keel-Linux/apt's `conf/appliances` does not list `web` yet; the test build added `web core` in its own tree. Until keel renders the sites of decision 0042, the default site is the one site Keel Web serves, which is why the Anubis front is this package's and not keel's. ## Test plan - [x] `tests/package.bats` (20), `tests/anubis-front.bats` (22), `tests/image-conf.bats` (10), written first; the three shell files at 100 percent under kcov; lintian clean - [x] isolated build on the build host, core then web from this branch (060d14f) and keel#63, staged with keel-release; booted in LXC (results below) ## On the built image - Simple: Nginx serves the default site (200, the page this recipe ships); Coraza's module not linked, `nginx -T` has no `coraza` directive, a Core Rule Set payload gets 200; `anubis@keel` disabled and inactive. Monit's file: units and probes of sshd, webmin, postfix and nginx only; `monit -t` passes. A second apply: 0 changes. - `keel manifest validate` passes; `keel manifest show web --resolved` prints the Web table of 0041 (overlays and ports as the format has them). - Cloud simple, set in `/etc/keel/instance.yaml` and applied with `keel spec apply --system` (17 changes: CrowdSec's identity and units, Coraza's hook, `anubis@keel`, then this package's hook): CRS payload 403; Firefox user agent gets Anubis's challenge; Googlebot's user agent from 2001:4860:4801:10::1 gets the page (625 bytes), Googlebot's user agent from the test host is challenged. The Google address was simulated: a test-only `conf.d` file trusted the build host (`set_real_ip_from`, `real_ip_header X-Forwarded-For`, the `header` case of 0042's `web.real_ip`), and Anubis logged `x-real-ip: 2001:4860:4801:10::1`. Monit adds crowdsec, firewall-bouncer, anubis and `waf-blocks`. A second apply: 0 changes. - Back to simple through the spec: the hooks put Debian's default site back and unload Coraza, 13 changes. Two fixes came from that run: the recipe ships the default page (common's removelist deletes `/var/www/html`, so the first image answered 404), and the socket Anubis reads is served without gzip, since under Coraza a gzip static answer is empty (Keel-Linux/libnginx-mod-http-coraza#2). Image: pre-release `testing-19.0-1-step7-20261001` of this repository. ## After review - The front only ever replaces Debian's unedited default link; with no Debian link it changes nothing and says so. The record is written before the link goes. - `gzip off` on the socket is gone: Anubis asks the socket for gzip and passes it on to a client that accepts it (measured), so it cost browsers compression. The empty-gzip bug is handled for every site by Keel-Linux/common#25 (keel-overlay-coraza 0.1.1, now a Depends) and fixed in the module by Keel-Linux/libnginx-mod-http-coraza#3. - Merge order: keel#63, common#25, then this. The testing image predates these commits (built from 060d14f).
Sign in to join this conversation.
No description provided.