release: 2.14.4: the follow-ups of the security audit of 2026-10-17
test / test (push) Canceled after 0s
test / test (push) Canceled after 0s
Stages 0-6 of docs/security-audit-2026-10-17.md in one cut: the high A2
(the user form asks for the account password), the seven mediums (M1, M2,
M3, W1, I1, I2, A1) and the lows and nits the plan names, with three
read-only security reviews of the fixes and their findings fixed. Stage H
(the test server's host) is the owner's.
No migration; schema 13. Upgrading: give the TLS key to group 10997;
copy antispam/ again where the sidecar runs (rspamd 4.2.2, a third file);
set TRUSTED_PROXY_CIDR behind Apache on the host if unset.
make e2e (64 passed) and go vet + go test (26 packages) on the test server
for 32f6ed6, the tree this release commit adds only pins and notes to. The
pins (compose, README, guide), the guide's backup example, the planned
cuts, the roadmap row and the plan's stages marked shipped. No tag.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
+2
-1
@@ -107,7 +107,7 @@ than the default «meaningful step» rule in [§ Commits and release build](#com
|
||||
2. Git tag `vX.Y.Z` and publish the GitHub Release only on explicit request (see
|
||||
[§ Release image](#release-image)).
|
||||
|
||||
**Planned version cuts** (from pin `2.14.3`; adjust if semver changes mid-track):
|
||||
**Planned version cuts** (from pin `2.14.4`; adjust if semver changes mid-track):
|
||||
|
||||
| Stage | ID | Cut |
|
||||
|---|---|---|
|
||||
@@ -155,6 +155,7 @@ than the default «meaningful step» rule in [§ Commits and release build](#com
|
||||
| 42 | overview-head | `2.14.1` |
|
||||
| 43 | dmarc-day, health-sockets | `2.14.2` |
|
||||
| 44 | label-tag | `2.14.3` |
|
||||
| 45 | security-audit-2026-10-17, stages 0-6 | `2.14.4` |
|
||||
|
||||
Docs-only prep (checklists in plans, no product code) uses the same per-step
|
||||
commit rule but **no** version cut until the next product stage ships.
|
||||
|
||||
+4
-4
@@ -218,14 +218,14 @@ cat ./data/setup-token
|
||||
#### Fixed image tag
|
||||
|
||||
`deploy/docker-compose.yml` pins an explicit version (`ghcr.io/mixeme/selfpost:X.Y.Z`),
|
||||
deliberately never `:latest`. The current pin is `2.14.3`. **No 2.x image is
|
||||
deliberately never `:latest`. The current pin is `2.14.4`. **No 2.x image is
|
||||
published on ghcr.io yet** (the newest there is `1.3.0`); until one is, build
|
||||
it from the checkout under the pinned name, and Compose uses the local image
|
||||
instead of pulling:
|
||||
|
||||
```sh
|
||||
docker build -f build/Dockerfile --build-arg VERSION=2.14.3 \
|
||||
-t ghcr.io/mixeme/selfpost:2.14.3 .
|
||||
docker build -f build/Dockerfile --build-arg VERSION=2.14.4 \
|
||||
-t ghcr.io/mixeme/selfpost:2.14.4 .
|
||||
```
|
||||
|
||||
`VERSION` must equal the tag: it is the version the backup check compares
|
||||
@@ -1067,7 +1067,7 @@ A version mismatch at step 5 refuses to start and leaves `/data` untouched —
|
||||
the panel exits with a message naming the tag to use, e.g.:
|
||||
|
||||
```
|
||||
backup: this backup was created by SelfPost 2.14.2 but this image is 2.14.3 — restore into the matching image (selfpost:2.14.2)
|
||||
backup: this backup was created by SelfPost 2.14.3 but this image is 2.14.4 — restore into the matching image (selfpost:2.14.3)
|
||||
```
|
||||
|
||||
Fix the tag in `docker-compose.yml` (build that tag as under [Fixed image
|
||||
|
||||
+2
-2
@@ -28,7 +28,7 @@ in `git log` and [CHANGELOG.md](../CHANGELOG.md).
|
||||
|
||||
| ID | Topic | Status | Progress | Plan |
|
||||
|---|---|---|---|---|
|
||||
| security-audit-2026-10-17 | Follow-ups of the 2026-10-17 security audit: A2 (high), seven mediums, the lows | stages 0-6 built 2026-10-17 for `2.14.4`; stage H (the host, S1-S3, S5) the owner's | 27/29 | [security-audit-2026-10-17.md](security-audit-2026-10-17.md) |
|
||||
| security-audit-2026-10-17 | Follow-ups of the 2026-10-17 security audit: A2 (high), seven mediums, the lows | stages 0-6 shipped `2.14.4` (2026-10-17); stage H (the host, S1-S3, S5) the owner's | 27/29 | [security-audit-2026-10-17.md](security-audit-2026-10-17.md) |
|
||||
| upstream-tls-verify | Inbound: offer "Verified" TLS to the upstream (Postfix `secure`, the upstream's name checked), beside Required, which checks no certificate (audit M7) | proposed | — | — |
|
||||
| server-dmarc-hint | Server › Settings lists a DMARC record for the server's own name beside its DKIM and SPF (audit S3, product side) | proposed | — | — |
|
||||
| inbound-upstream-result | Inbound › Log shows what the upstream answered: sent, deferred, bounced, with its last reply | shipped `2.10.0` | 7/7 | [plans/inbound-upstream-result.md](plans/inbound-upstream-result.md) |
|
||||
@@ -68,7 +68,7 @@ stages 1 and 2 as `2.5.0` the same day, stage 2b as `2.5.1`, stage 2c as
|
||||
`2.6.0` the same day; stage 6 (documents and tests, no cut) closed the
|
||||
audit. Of the three rows from [own-mta-builds](#own-mta-builds),
|
||||
**port25-bare-newline** shipped as `2.6.1` the same day and
|
||||
**base-trixie** as `2.7.0`, and **panel-dkim-signing** as `2.8.0` (2026-10-16). **dns-record-collapse**, **settings-save-row** and **notification-mail-recheck** shipped together as `2.9.0` the same day, with `/data/opendkim` removed as panel-dkim-signing planned, then `2.9.1` (log panes on a phone) and **inbound-upstream-result** as `2.10.0`. What is agreed after it is marked so in the index; every other
|
||||
**base-trixie** as `2.7.0`, and **panel-dkim-signing** as `2.8.0` (2026-10-16). **dns-record-collapse**, **settings-save-row** and **notification-mail-recheck** shipped together as `2.9.0` the same day, with `/data/opendkim` removed as panel-dkim-signing planned, then `2.9.1` (log panes on a phone) and **inbound-upstream-result** as `2.10.0`. The follow-ups of the [security audit of 2026-10-17](security-audit-2026-10-17.md) shipped together as `2.14.4`, stages 0-6 in one cut; its stage H is the owner's host. What is agreed after it is marked so in the index; every other
|
||||
remaining item is a candidate. panel-docs shipped in
|
||||
[CHANGELOG.md](../CHANGELOG.md) `[1.8.0]`; dmarc-reports in `[1.7.0]`
|
||||
(its ingest path first ran in `2.0.0` and was reviewed on 2026-10-11, see
|
||||
|
||||
@@ -683,7 +683,7 @@ the argument.
|
||||
"letsencrypt.org"`. Done when `dig +short TXT _dmarc.selfpost.mixfed.ru`
|
||||
answers.
|
||||
|
||||
### Stage 0 — the high and the cheap guards (~5 h) → patch release
|
||||
### Stage 0 — the high and the cheap guards (~5 h) → patch release (shipped `2.14.4`, 2026-10-17)
|
||||
|
||||
- [x] **A2.** `reauth` on user create, on a user update that carries
|
||||
`password` or changes `role`, and on user delete; the user form gets the
|
||||
@@ -717,7 +717,7 @@ the argument.
|
||||
- [x] **X1.** SECURITY.md's table: `latest 2.x` supported, `1.x` not. —
|
||||
**Sonnet**, 0.25 h. *Done 2026-10-17.*
|
||||
|
||||
### Stage 1 — the tenant boundary in the mail path (~7 h) → patch release
|
||||
### Stage 1 — the tenant boundary in the mail path (~7 h) → patch release (shipped `2.14.4`, 2026-10-17)
|
||||
|
||||
- [x] **M1.** `overLimit` and `recordRejected` take the domain from the login
|
||||
(`ApplicationByLogin`), return early on an empty login; the reader's two
|
||||
@@ -753,7 +753,7 @@ the argument.
|
||||
- [x] **W3.** A mutex around `Resync`'s read + write + reload. — **Sonnet**,
|
||||
0.5 h. *Done 2026-10-17:* TestResyncRunsOneAtATime.
|
||||
|
||||
### Stage 2 — the key group (~2.5 h) → patch release, then the test server's `certs/`
|
||||
### Stage 2 — the key group (~2.5 h) → patch release, then the test server's `certs/` (shipped `2.14.4`, 2026-10-17)
|
||||
|
||||
- [x] **I1.** `groupadd --system --gid 10997 backupkey; usermod -aG backupkey
|
||||
panel` in the Dockerfile; the guide's two `chgrp 10998` become `10997`
|
||||
@@ -767,7 +767,7 @@ the argument.
|
||||
is root and `testFullBackupRestore` checks both uids; the test server's
|
||||
key at the rollout.
|
||||
|
||||
### Stage 3 — limits and defaults (~7 h)
|
||||
### Stage 3 — limits and defaults (~7 h) (shipped `2.14.4`, 2026-10-17)
|
||||
|
||||
- [x] **A1.** (a) Compose and guide set `TRUSTED_PROXY_CIDR` for the
|
||||
Apache-on-host scenario (the Docker gateway, with the command that prints
|
||||
@@ -797,7 +797,7 @@ the argument.
|
||||
private address - a trusted proxy's peer would have let the internet in
|
||||
again through that proxy; TestHealthzAnswersOnlyLocalProbes.
|
||||
|
||||
### Stage 4 — resources and imports (~5 h)
|
||||
### Stage 4 — resources and imports (~5 h) (shipped `2.14.4`, 2026-10-17)
|
||||
|
||||
- [x] **I3.** `pids_limit: 512` in every compose fragment; the comment
|
||||
corrected; one e2e run. — **Sonnet**, 0.5 h. *Done 2026-10-17:* 1024 for
|
||||
@@ -832,7 +832,7 @@ the argument.
|
||||
openssl's HMAC, the deny list's 554 message, healthy. The live sidecar at
|
||||
the rollout.
|
||||
|
||||
### Stage 5 — supply chain and currency (~2.5 h)
|
||||
### Stage 5 — supply chain and currency (~2.5 h) (shipped `2.14.4`, 2026-10-17)
|
||||
|
||||
- [x] **I4.** Actions pinned by SHA with the version in a comment;
|
||||
`govulncheck ./...` in `test.yml` and in `release.yml` before the push (a
|
||||
@@ -855,7 +855,7 @@ the argument.
|
||||
test server both ways.
|
||||
1.5 h.
|
||||
|
||||
### Stage 6 — the rest, and what to accept (~3 h)
|
||||
### Stage 6 — the rest, and what to accept (~3 h) (shipped `2.14.4`, 2026-10-17)
|
||||
|
||||
- [x] **M7.** guide: upstream `encrypt` checks no certificate. — **Sonnet**,
|
||||
0.25 h. *Done 2026-10-17:* guide and Help. (Offering `secure` is hours and a `domain`-user-facing choice;
|
||||
|
||||
Reference in New Issue
Block a user