docs: the upstream's Required TLS checks no certificate (audit M7)

Security audit 2026-10-17, finding M7 (low), stage 6; Help's mockup is
c09368c. postfix/inbound.go writes "encrypt" for Required, and Postfix
verifies no certificate at that level: a domain user who chooses it gets
privacy against passive observers only. The guide § Inbound relay and Help
(word for word with the mockup) say so. Offering "secure" with the
upstream's name is a choice for domain users and hours of work: it goes on
the roadmap as a proposal, not into this plan.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
mix
2026-10-17 22:34:29 +03:00
co-authored by Claude Opus 5.5
parent c09368c544
commit 820b1bb968
4 changed files with 14 additions and 4 deletions
+7
View File
@@ -98,6 +98,13 @@ Format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/); version
three `dmarc_*` maps root creates at the start were missing from the list
of paths where a symbolic link is removed first.
### Documentation
- **The upstream's "Required" TLS checks no certificate**, and the guide and
Help now say so (audit M7): it guards against a listener, not against one
who answers in the upstream's place.
## [2.14.3] - 2026-10-17
A tag beside a label. No migration; schema 13.
+4 -1
View File
@@ -1225,7 +1225,10 @@ for such a sender.
**Panel** (`/inbound/domains`): the global role adds and deletes domains. On a
domain's page, set the upstream host/port and TLS to that hop (opportunistic /
required / off), and choose recipients. An upstream has one TLS mode: Postfix
required / off), and choose recipients. *Required* is Postfix's `encrypt`
level: the hop is encrypted, but the upstream's certificate is not checked,
so it guards against someone who listens on the way, not against one who
answers in the upstream's place. An upstream has one TLS mode: Postfix
keeps the TLS policy per next hop, not per domain, so the mode saved for one
domain is the mode of every domain forwarded to the same host and port, and
they are changed with it; a *domain* user who does not manage all of them is
+2 -2
View File
@@ -847,8 +847,8 @@ the argument.
### Stage 6 — the rest, and what to accept (~3 h)
- [ ] **M7.** guide: upstream `encrypt` checks no certificate. — **Sonnet**,
0.25 h. (Offering `secure` is hours and a `domain`-user-facing choice;
- [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;
propose it on the roadmap, not here.)
- [ ] **A6, A7, A10, W7, M6, M8** and the README note — half an hour each,
or the wording change named under each. — **Sonnet**, 2 h.
+1 -1
View File
@@ -231,7 +231,7 @@ var inboundTopics = []HelpTopic{
Rich("An optional backup-MX or forwarder, switched on in the server's ", Code(".env"), "; the Inbound menu exists only then. Postfix accepts mail on port 25 for the listed domains only and hands each message on to that domain's upstream; there are no mailboxes. For each domain publish the MX record its page shows, and keep a primary MX the domain already has if this is a backup. The MX tag is green when at least one MX of the domain points at this server, and a domain accepts no mail until an upstream is saved on its page. Adding and deleting domains is for the global role."),
}},
{ID: HelpUpstream, Title: "Upstream", Body: []Text{
Plain("The upstream is the server that actually holds the mailboxes. Give its host and port — used exactly as written, with no MX lookup — and choose the TLS for the hop to it: Opportunistic uses TLS when the upstream offers it and otherwise sends in the clear; Required sends only over TLS, and the mail waits in the queue while the upstream does not offer it or the TLS handshake fails - an upstream that answers STARTTLS with a permanent error bounces it; Off never uses TLS. While the upstream does not answer, Postfix keeps the mail and retries as for any other mail."),
Plain("The upstream is the server that actually holds the mailboxes. Give its host and port — used exactly as written, with no MX lookup — and choose the TLS for the hop to it: Opportunistic uses TLS when the upstream offers it and otherwise sends in the clear; Required sends only over TLS, and the mail waits in the queue while the upstream does not offer it or the TLS handshake fails - an upstream that answers STARTTLS with a permanent error bounces it. Neither checks the upstream's certificate: TLS here keeps the mail from whoever only listens on the way, not from one who answers in the upstream's place. Off never uses TLS. While the upstream does not answer, Postfix keeps the mail and retries as for any other mail."),
}},
{ID: HelpRecipients, Title: "Valid recipients", Body: []Text{
Plain("Choose whom this domain accepts. Listed addresses only: the relay accepts exactly the addresses you list, one per line or comma-separated, and refuses any other while the sender is still connected, so it never has to send a bounce for them. Any recipient: everything at the domain is accepted and passed on, and an address the upstream then rejects comes back as a bounce from this server to a sender who is often forged — backscatter. Prefer a list, and keep it in step with the mailboxes upstream."),