diff --git a/CHANGELOG.md b/CHANGELOG.md index 03b7a38..47dbd1f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,15 @@ Format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/); version ## [Unreleased] +## [2.8.0] - 2026-10-16 + +The panel signs outgoing mail with DKIM itself, and OpenDKIM - a 2018 beta +with open 2026 CVEs - has left the image. Keys, selectors and DNS records do +not change; the first start copies the keys to `/data/dkim`. The sender +check holds a `Sender:` line too. Nothing for an operator to do; a rollback +to 2.7.x needs one command first (guide, § Upgrading). No migration; +schema 11. + ### Added - **The panel signs outgoing mail with DKIM itself** (panel-dkim-signing, diff --git a/README.md b/README.md index 133cab6..b4fd2d7 100644 --- a/README.md +++ b/README.md @@ -112,8 +112,8 @@ outbound mail will not reach the real internet without DNS, PTR, and port 25. > local image and pulls nothing: > > ```sh -> docker build -f build/Dockerfile --build-arg VERSION=2.7.0 \ -> -t ghcr.io/mixeme/selfpost:2.7.0 . +> docker build -f build/Dockerfile --build-arg VERSION=2.8.0 \ +> -t ghcr.io/mixeme/selfpost:2.8.0 . > ``` ```sh @@ -122,7 +122,7 @@ docker run --rm -d --name selfpost-try \ -e SELFPOST_HOSTNAME=mail.local.test \ -e PANEL_COOKIE_SECURE=false \ -v selfpost-try-data:/data \ - ghcr.io/mixeme/selfpost:2.7.0 + ghcr.io/mixeme/selfpost:2.8.0 ``` **Get the setup URL** (pick one): diff --git a/deploy/docker-compose.yml b/deploy/docker-compose.yml index d57dbd9..d7caefd 100644 --- a/deploy/docker-compose.yml +++ b/deploy/docker-compose.yml @@ -23,7 +23,7 @@ services: selfpost: - image: ghcr.io/mixeme/selfpost:2.7.0 + image: ghcr.io/mixeme/selfpost:2.8.0 restart: unless-stopped environment: SELFPOST_HOSTNAME: "${SELFPOST_HOSTNAME:?set the mail/panel hostname, e.g. mail.example.com}" diff --git a/docs/development.md b/docs/development.md index b426eea..901ba9f 100644 --- a/docs/development.md +++ b/docs/development.md @@ -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.7.0`; adjust if semver changes mid-track): +**Planned version cuts** (from pin `2.8.0`; adjust if semver changes mid-track): | Stage | ID | Cut | |---|---|---| diff --git a/docs/guide.md b/docs/guide.md index 891b476..02ca053 100644 --- a/docs/guide.md +++ b/docs/guide.md @@ -204,14 +204,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.7.0`. **No 2.x image is +deliberately never `:latest`. The current pin is `2.8.0`. **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.7.0 \ - -t ghcr.io/mixeme/selfpost:2.7.0 . +docker build -f build/Dockerfile --build-arg VERSION=2.8.0 \ + -t ghcr.io/mixeme/selfpost:2.8.0 . ``` `VERSION` must equal the tag: it is the version the backup check compares @@ -934,7 +934,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.6.1 but this image is 2.7.0 — restore into the matching image (selfpost:2.6.1) +backup: this backup was created by SelfPost 2.7.0 but this image is 2.8.0 — restore into the matching image (selfpost:2.7.0) ``` Fix the tag in `docker-compose.yml` (build that tag as under [Fixed image diff --git a/docs/plans/panel-dkim-signing.md b/docs/plans/panel-dkim-signing.md index e09c3ca..8e8af34 100644 --- a/docs/plans/panel-dkim-signing.md +++ b/docs/plans/panel-dkim-signing.md @@ -1,6 +1,6 @@ # Plan: panel-dkim-signing -**Status:** agreed, 2026-10-15 - the row is agreed (owner, 2026-10-15, the +**Status:** shipped `2.8.0` (2026-10-16); agreed 2026-10-15 - the row is agreed (owner, 2026-10-15, the order port25-bare-newline -> base-trixie -> panel-dkim-signing); three questions below were settled one at a time the same day. **Date:** 2026-10-15 @@ -214,10 +214,23 @@ documents in the commit after it. `Sender:` is held to the login like v0.4.1 kept every header in a map of its own per session, on 465/587 and on port 25 alike: the panel builds it patched not to (`third_party/go-milter/PATCHES.md`; the owner's decision, 2026-10-16). -- [ ] On the test server: a day of the owner's mail; one message from an +- [x] On the test server: a day of the owner's mail; one message from an application through 465 and one notification to a real mailbox, the headers read (dkim=pass with the panel's `d=`). -- [ ] Cut `2.8.0`. +- [x] Cut `2.8.0`. + +*Done (2026-10-16):* the owner's message through 465 (`dev/send-check.ps1`) +arrived at Gmail with `dkim=pass header.i=@carrel.mixfed.ru +header.s=selfpost`, `spf=pass`, `dmarc=pass`, and at Yandex with +`dkim=pass` and `X-Yandex-Spam: 1`; its `h=` over-signs the shown headers. +His `dev/from-check.ps1` sent thirteen `From:`/`Sender:` cases: four +accepted and delivered, nine refused as expected, each a send-log row of +reason `from` or `sender`. The notification to a real mailbox was not +sent - nothing raised one; its signature is verified by dkimpy on every e2e +run, and the server name's key, unchanged by the move (digests compared), +matched its published record on 2026-10-15. The day of mail was cut short +at the owner's word ("Выпускай", 2026-10-16), the test server having run +the stage's code since 2026-10-15 22:48 UTC. Cut as `2.8.0`, no tag. ## Risks diff --git a/docs/roadmap.md b/docs/roadmap.md index bb021a5..6be676d 100644 --- a/docs/roadmap.md +++ b/docs/roadmap.md @@ -45,7 +45,7 @@ in `git log` and [CHANGELOG.md](../CHANGELOG.md). | own-mta-builds | Analysis: build Postfix and OpenDKIM ourselves, patched, instead of Debian's packages | analysed 2026-10-15: no own builds; three rows proposed instead | — | [own-mta-builds-2026-10-15.md](own-mta-builds-2026-10-15.md) | | port25-bare-newline | The inbound relay's port 25 refuses bare newlines in DATA (`smtpd_forbid_bare_newline=normalize`) | shipped `2.6.1` | — | — | | base-trixie | The image's base from Debian bookworm (LTS since 2026-07-12) to trixie: Postfix 3.10 with the 2026 security batches | shipped `2.7.0` | — | — | -| panel-dkim-signing | DKIM signing in the panel's own milter; OpenDKIM, the syslog relay and the parser port removed | agreed (2026-10-15; stages 1-2 done, documents and reviews) | 12/14 | [plans/panel-dkim-signing.md](plans/panel-dkim-signing.md) | +| panel-dkim-signing | DKIM signing in the panel's own milter; OpenDKIM, the syslog relay and the parser port removed | shipped `2.8.0` | 14/14 | [plans/panel-dkim-signing.md](plans/panel-dkim-signing.md) | | phone-desktop-mode | A phone browser in "desktop site" mode gets the phone navigation | agreed (2026-10-13: after stages 1 and 2 of audit-2026-10-12) | — | — | | from-header-binding | Hold a message's `From:` header against the application that sends it | shipped `2.4.0` | 9/9 | [plans/from-header-binding.md](plans/from-header-binding.md) | | panel-redesign | Panel redesign (accepted mockups, design contract) | shipped `2.0.0` | 27/27 | [plans/panel-redesign.md](plans/panel-redesign.md) | @@ -64,7 +64,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`; panel-dkim-signing follows. 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). 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