base-trixie: findings of the reviews
test / test (push) Canceled after 0s

Security review (1c6e04b):
- The panel's database and its -wal/-shm were 0644 under a traversable
  /data, holding the panel users' password hashes and session token
  hashes. store.Open now makes them 0600 (SQLite gives the next -wal/-shm
  the database's mode: findCreateFileMode(), unixOpenSharedMemory());
  TestOpenKeepsTheDatabasePrivate.
- The entrypoint removes a symbolic link the panel user could leave where
  a /data directory, table, map, the queue or mail.log is expected, before
  its root steps chmod or create them (drop_links).
- The panel user is 10999:10999, outside the system range: in trixie
  useradd gave it group 998, the host's systemd-network on the test
  server; bookworm's 999 was the host's systemd-journal.
- security.md said the database was 0640; it was 0644.

Technical review (1c6e04b):
- mail_helpers.go: smtp-sink does add a Received: header, "(smtp-sink)"
  (smtp-sink.c:520-531); the "(Postfix)" filter leaves it out.
- CHANGELOG/roadmap: OpenDKIM's signing and From:-parsing code is
  unchanged, not all of it; the retry-policy bug predates 3.9 (any
  postconf warning); three entries moved from Fixed to Changed, as no
  released image had them.
- internal/app/sasl.go: db_dump's stdout alone is parsed.
- mynetworks comment: postinst:180, fset_all_changed.

Tests: on the server, make e2e exit 0 (712 s), go vet + go test 27
packages ok.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
mix
2026-10-15 20:05:01 +03:00
co-authored by Claude Opus 5.5
parent 1c6e04b7d3
commit a3050afb66
10 changed files with 164 additions and 31 deletions
+39 -16
View File
@@ -7,6 +7,20 @@ Format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/); version
### Security
- **The panel's database was readable by every user of the container.**
`selfpost.db` and its `-wal` and `-shm` files were 0644 under a
traversable `/data`; they hold the panel users' password hashes and the
session token hashes, and Postfix's smtpd - which faces the Internet -
and OpenDKIM run as other users there. The panel now makes them 0600 at
every start; SQLite gives the next `-wal` and `-shm` the database's mode.
Found by the security review of this release.
- **The entrypoint no longer follows a symbolic link the panel user could
leave under `/data`.** Several of its steps run as root and chmod,
create or regroup paths in a tree the panel writes; a link where a
directory or table is expected is now removed first. No escalation was
found - a compromised panel could only have turned it against the
container itself.
- **The image runs Debian trixie instead of bookworm** (base-trixie).
Bookworm left regular security support on 2026-07-12, and its Postfix
3.7.11 lacks upstream's 2026 security fixes, which carry no CVE ids and
@@ -14,7 +28,9 @@ Format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/); version
August batch (among them a BDAT memory exhaustion, a crash by DATA after
a BDAT error, and a policy and milter bypass after an end-of-data
reject), Debian's security support until 2028, OpenSSL 3.5 and libmilter
8.18.1. OpenDKIM's code is unchanged. The build stage is
8.18.1. OpenDKIM's signing and From:-parsing code is unchanged (Debian's
new patches touch the verifier's Authentication-Results and librbl).
The build stage is
`golang:1.26-trixie`.
### Changed
@@ -54,7 +70,9 @@ Format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/); version
the trixie image a package took it and the build failed, and on a host it
is often a system group of the host's own, which could then read the key
as well (on the test server's host it is `systemd-network`). 10998 is
outside that range. **On upgrade, give the private key in `certs/` to
outside that range. The panel user is 10999:10999 for the same reason
(it was 999:999, the host's `systemd-journal` group on the test server).
**On upgrade, give the private key in `certs/` to
the new group on the host** - `chgrp 10998` where the guide said
`chgrp 998`, in a certbot deploy hook too - or a full backup is refused
until then; Postfix reads its own copy and is not affected. The other
@@ -63,22 +81,27 @@ Format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/); version
- `opendkim-tools` is no longer installed: nothing in the image ran it.
`openssl` is installed by name, for the certificate reload.
- **Made ready for what trixie's programs do differently:** the log tailer
reads Postfix 3.10's refusal lines that carry `sasl_method=`,
`sasl_username=` and `sasl_sender=`, and cleanup's `removed (canceled)`
for a transaction that did not complete; the rotation loop refuses on
logrotate 3.22's "Ignoring" output, now with exit status 1 where 3.21
gave 0; Debian's chroot sync, which trixie's postfix runs at every
start, is turned off (`SYNC_CHROOT=` in `/etc/default/postfix`; nothing
runs chrooted), so `/etc/resolv.conf` and the like are not copied into
the queue under `/data`; a mail.log Postfix creates itself is `0640`, as
the entrypoint and logrotate create it.
### Fixed
- **The retry policy shown in the panel could fall back to Postfix's
compiled-in defaults:** the panel read `postconf`'s warnings together
with its values, and since Postfix 3.9 `postconf` warns about deprecated
parameters. It reads the values alone now and logs the warning.
- **logrotate 3.22 exits 1 when it skips a config it does not trust;**
3.21 exited 0. The rotation loop now refuses to run on that output
whatever the exit code, instead of retrying for ever.
- **The log tailer reads Postfix 3.10's new line shapes:** refusal lines
that carry `sasl_method=`, `sasl_username=` and `sasl_sender=`, and
cleanup's `removed (canceled)` for a transaction that did not complete.
- Debian's chroot sync no longer copies `/etc/resolv.conf` and the like
into the queue under `/data` at every start (`SYNC_CHROOT=` in
`/etc/default/postfix`; nothing runs chrooted). A Postfix-created
mail.log is `0640`, as the entrypoint and logrotate create it.
- **The retry policy shown in the panel fell back to Postfix's compiled-in
defaults whenever `postconf` warned:** the panel read `postconf`'s
standard error together with its values, and a warning there - an
unused parameter in main.cf, and since Postfix 3.9 a deprecated one -
was one value too many. The image's own main.cf sets none, so it took a
parameter an operator added. The panel reads the values alone now and
logs the warning. `db_dump`'s output, which the panel parses to list the
SASL accounts, is read the same way.
## [2.6.1] - 2026-10-15