fix: HTTPS behind Anubis, and the site on the usage screen #3

Merged
marcos-mendez merged 3 commits from fix/web-https-waf-usage into master 2026-10-02 03:27:36 -03:00
marcos-mendez commented 2026-10-02 00:35:38 -03:00 (Migrated from github.com)

Three Keel Web bugs from the maintainer's test screenshots (114, 024 and #2), and the dependencies for the WAF fixes of Keel-Linux/common#27.

114: no browser passed Anubis over HTTP

Root cause: Anubis sets its cookies Secure; SameSite=None; Partitioned. default-anubis served plain HTTP on port 80 only, so a browser never sent the cookies back and the challenge failed with "cookies disabled".

Default chosen: in the cloud modes, where Anubis is on, the front is HTTPS only. This is what decision 0042 sets for sites (redirect_http: true, the default certificate):

  • port 443 is the default server, with TLS 1.2/1.3, HTTP/2 and the machine's certificate (/usr/local/share/ca-certificates/cert.crt, /etc/ssl/private/cert.key);
  • that certificate is self-signed by keel-host-keys at the first boot, until the confconsole Certificate screen issues one through ACME at the same paths;
  • port 80 answers 301 to the same URL on HTTPS;
  • there is no HSTS while the certificate may be self-signed (0042, tls.hsts);
  • the site answers by name and by IP.

Anubis's cookie option is left at Secure: no mode with Anubis needs HTTP. A simple installation keeps Debian's site on port 80. It has no Anubis, so it has no cookie to carry.

The state hook refuses, and changes nothing, while the certificate or its key is missing. The package also activates nginx-reload, so an upgrade from 0.1.0 serves the new front at once.

024: the usage screen did not list the site

Root cause: Core's recipe ships overlay/etc/confconsole/services.txt with Webmin and SSH only (keel-core), and the web layer kept it. confconsole itself is not involved: its default template lists Web, but Core's overlay replaces it. So there is no confconsole change, and nothing overlaps confconsole#16.

The web recipe's overlay now ships its own services.txt, with Web: http://<address> first, IPv6 then IPv4. Port 80 serves the site in simple mode and redirects to HTTPS behind Anubis, so the one URL is right in every mode. conf.d/main fails the build when the usage screen does not list the site.

#2: Anubis's challenge returned 500 without gzip

Root cause: upstream Anubis refuses one request in 64 at random from clients without gzip (Keel-Linux/anubis#2). keel-web 0.1.1 depends on anubis (>= 1.27.0-0+keel2) and on keel-overlay-coraza (>= 0.1.2). Closes #2.

Evidence (LXC container of the step7b Web image, moved to cloud_simple with keel spec apply, these packages installed)

Chromium (playwright-core, normal Chrome user agent), through a relay of the test VM:

start challenge pass-challenge final cookies
http://web.keel.test/ 301 → https://web.keel.test/, "Making sure you're not a bot!" 302 https://web.keel.test/, "Keel Web" auth + verification, both Secure
http://[fd42:…:fe06]/ 301 → https, challenge 302 page same
http://10.0.3.158/ 301 → https, challenge 302 page same
  • An XSS URL and a SQLi URL get 403, and the audit log names the rules.
  • 200 browser loads with Accept-Encoding: identity got 200 × 200.
  • The console usage screen lists Web: http://[…] and Web: http://10.0.3.158.

Unit tests: bats gives 73 + 25 passing tests. COVERAGE_THRESHOLD=100 tests/coverage.sh gives anubis-front 84/84, conf.d/main 20/20 and boot-test-lib 109/109. The package build is lintian-clean.

Test plan

Three Keel Web bugs from the maintainer's test screenshots (114, 024 and #2), and the dependencies for the WAF fixes of Keel-Linux/common#27. ## 114: no browser passed Anubis over HTTP **Root cause:** Anubis sets its cookies `Secure; SameSite=None; Partitioned`. `default-anubis` served plain HTTP on port 80 only, so a browser never sent the cookies back and the challenge failed with "cookies disabled". **Default chosen:** in the cloud modes, where Anubis is on, the front is HTTPS only. This is what decision 0042 sets for sites (`redirect_http: true`, the `default` certificate): - port 443 is the default server, with TLS 1.2/1.3, HTTP/2 and the machine's certificate (`/usr/local/share/ca-certificates/cert.crt`, `/etc/ssl/private/cert.key`); - that certificate is self-signed by keel-host-keys at the first boot, until the confconsole Certificate screen issues one through ACME at the same paths; - port 80 answers 301 to the same URL on HTTPS; - there is no HSTS while the certificate may be self-signed (0042, `tls.hsts`); - the site answers by name and by IP. Anubis's cookie option is left at Secure: no mode with Anubis needs HTTP. A simple installation keeps Debian's site on port 80. It has no Anubis, so it has no cookie to carry. The state hook refuses, and changes nothing, while the certificate or its key is missing. The package also activates `nginx-reload`, so an upgrade from 0.1.0 serves the new front at once. ## 024: the usage screen did not list the site **Root cause:** Core's recipe ships `overlay/etc/confconsole/services.txt` with Webmin and SSH only (keel-core), and the web layer kept it. confconsole itself is not involved: its default template lists Web, but Core's overlay replaces it. So there is no confconsole change, and nothing overlaps confconsole#16. The web recipe's overlay now ships its own `services.txt`, with `Web: http://<address>` first, IPv6 then IPv4. Port 80 serves the site in simple mode and redirects to HTTPS behind Anubis, so the one URL is right in every mode. `conf.d/main` fails the build when the usage screen does not list the site. ## #2: Anubis's challenge returned 500 without gzip **Root cause:** upstream Anubis refuses one request in 64 at random from clients without gzip (Keel-Linux/anubis#2). keel-web 0.1.1 depends on `anubis (>= 1.27.0-0+keel2)` and on `keel-overlay-coraza (>= 0.1.2)`. Closes #2. ## Evidence (LXC container of the step7b Web image, moved to cloud_simple with `keel spec apply`, these packages installed) Chromium (playwright-core, normal Chrome user agent), through a relay of the test VM: | start | challenge | pass-challenge | final | cookies | | --- | --- | --- | --- | --- | | `http://web.keel.test/` | 301 → `https://web.keel.test/`, "Making sure you're not a bot!" | 302 | `https://web.keel.test/`, "Keel Web" | auth + verification, both Secure | | `http://[fd42:…:fe06]/` | 301 → https, challenge | 302 | page | same | | `http://10.0.3.158/` | 301 → https, challenge | 302 | page | same | - An XSS URL and a SQLi URL get 403, and the audit log names the rules. - 200 browser loads with `Accept-Encoding: identity` got 200 × 200. - The console usage screen lists `Web: http://[…]` and `Web: http://10.0.3.158`. Unit tests: `bats` gives 73 + 25 passing tests. `COVERAGE_THRESHOLD=100 tests/coverage.sh` gives anubis-front 84/84, conf.d/main 20/20 and boot-test-lib 109/109. The package build is lintian-clean. ## Test plan - [ ] `tests / coverage` and `packages / build` green - [ ] Merge after Keel-Linux/common#27 and Keel-Linux/anubis#2; rebuild the Web image and check the usage screen and the browser by name and IP on it
Sign in to join this conversation.
No description provided.