review follow-up: close the gaps left by the phase1-6 pass
test / test (push) Has been cancelled

Verified the tree against docs/plans/code-review-2026-08.md and finished the
tasks that were only partly done, plus two defects the pass introduced.

- bcrypt: the setup account was still hashed at DefaultCost (10). The work
  factor now has one definition, auth.BcryptCost = 12, used everywhere.
- rate limiter: protecting blocked buckets from eviction was unbounded — an
  attacker with many source addresses could grow the map by making each one
  fail its way to blocked. Blocked buckets are now evicted past
  maxBuckets * 4, nearest expiry first, logged once per window. Tests cover
  both halves.
- postqueue: the 5s timeout left the output size unbounded; reads are now
  capped at 4 MiB and report truncation.
- spec references: the ~76 `spec N` citations CHANGELOG [0.5.0] claimed were
  gone are removed from build/, deploy/, the first two migrations and the
  release workflow, with the affected comment paragraphs re-wrapped. Comments
  only; shell/YAML/SQL syntax re-checked.
- schema-migrations.md: schema section was headed v9 with the chain at v10,
  and three links pointed at deleted plan files.
- internal/configsafe: the shared empty/forbidden-character check behind the
  OpenDKIM and Postfix config writers; each writer keeps its own forbidden set.
- dropped the parseDomainRateLimitForm/parseAppRateLimitForm pass-throughs
  left behind by the parser merge (only their own tests still called them).
- plan doc now carries a status table: what shipped, what was already in
  place, what was declined (//go:build linux for the /proc reader) and the
  open CSRF-token question.

Not done, each its own phase: typed template data structs, log/slog, DMARC
service and handler tests, error-page/corrupted-backup tests, backup re-auth.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
mix
2026-08-19 20:03:05 +03:00
co-authored by Claude Opus 5
parent 4204ee279c
commit ab2cd885c4
34 changed files with 586 additions and 318 deletions
+13 -14
View File
@@ -1,18 +1,17 @@
# Example host Apache vhost for the SelfPost panel (spec 10.3, default
# scenario). Install on the host running Apache — NOT inside the SelfPost
# container. Requires mod_ssl and mod_proxy/mod_proxy_http enabled
# (`a2enmod ssl proxy proxy_http`).
# Example host Apache vhost for the SelfPost panel (default scenario). Install
# on the host running Apache — NOT inside the SelfPost container. Requires
# mod_ssl and mod_proxy/mod_proxy_http enabled (`a2enmod ssl proxy proxy_http`).
#
# Certificates: obtain with the Apache certbot plugin against THIS vhost
# (`certbot --apache -d mail.example.com`). Certbot edits this file in place
# to add the SSLCertificateFile/SSLCertificateKeyFile directives and a
# :80 -> :443 redirect vhost, and renews in the background via its own timer.
# The resulting PEM files land at
# /etc/letsencrypt/live/mail.example.com/{fullchain,privkey}.pem on the host
# — bind-mount that directory read-only into the SelfPost container (see
# (`certbot --apache -d mail.example.com`). Certbot edits this file in place to
# add the SSLCertificateFile/SSLCertificateKeyFile directives and a :80 -> :443
# redirect vhost, and renews in the background via its own timer. The resulting
# PEM files land at
# /etc/letsencrypt/live/mail.example.com/{fullchain,privkey}.pem on the host —
# bind-mount that directory read-only into the SelfPost container (see
# ../docker-compose.yml, the `./certs:/etc/postfix/tls:ro` volume) so Postfix
# can present the very same certificate on 465/587. One certificate, two
# consumers (spec 10 p.4) — no separate cert just for the panel.
# consumers — no separate cert just for the panel.
<VirtualHost *:443>
ServerName mail.example.com
@@ -26,9 +25,9 @@
ProxyPass "/" "http://127.0.0.1:8080/"
ProxyPassReverse "/" "http://127.0.0.1:8080/"
# The panel is plain HTTP behind the proxy; it never terminates TLS
# itself (spec 10 p.2). Cookies are still marked Secure by the panel
# (spec 7.6.6) because the browser only ever sees this HTTPS vhost.
# The panel is plain HTTP behind the proxy; it never terminates TLS itself.
# Cookies are still marked Secure by the panel because the browser only ever
# sees this HTTPS vhost.
</VirtualHost>
<VirtualHost *:80>