test / test (push) Has been cancelled
Review pass over the 1.4.0-1.9.1 work. Port 25 no longer inherits main.cf's submission milter chain: smtpd_milters is always overridden on smtp/inet, to the antispam milter or to nothing. Without that, OpenDKIM (strict, tempfail) gated relayed mail during a signing outage, and the journal-milter filed inbound mail into the outbound send log under the sender's domain -- so Deliveries showed other people's mail and a forged From: consumed that domain's level-2 budget. architecture.md already described the intended behaviour; the code now matches. DMARC reports are checked before they are stored: the policy domain must be a configured sending domain, and must match the +tag of a per-domain hosted address. The rua address form is predictable, so anyone able to reach it could file reports under any domain and evict genuine ones through the retention cap. Zip attachments are now decompressed as well as gzip. The auto level-2 ceiling is scaled to the level-1 window before the multiplier is applied; any window other than 3600s shifted the allowance by window/3600. Migration 0010 indexes send_log(app_login, created_at) -- both the per-MAIL FROM rate-limit count and the per-application statistics were scanning the created_at range. e2e now regenerates the Postfix config in-container for all four port-25 flag combinations and requires postfix check to pass; the 1.9.1 crash-loop shipped in 1.4.0 and survived three releases because only the flags-off path was exercised. Migration 0009 stays as shipped -- its conversion branch only fires for a database carrying application-scope allowed_ips from before 1.9.0. The schema reference notes that the old list was permissive and the new column is restrictive; the guide documents the allow-list as a sending control on a fail-open path, not an authentication boundary. Also: gofmt across cmd/ and internal/, unused duplicate validators dropped from internal/web/validate, export no longer swallows store errors. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
162 lines
7.3 KiB
HTML
162 lines
7.3 KiB
HTML
{{/* Hidden radios drive which help pane is visible — CSS :has(), no script. */}}
|
|
{{define "help_inputs"}}
|
|
<input class="ctrl" type="radio" name="help" id="help-off" checked>
|
|
<input class="ctrl" type="radio" name="help" id="help-index">
|
|
<input class="ctrl" type="radio" name="help" id="help-status">
|
|
<input class="ctrl" type="radio" name="help" id="help-password">
|
|
<input class="ctrl" type="radio" name="help" id="help-dns">
|
|
<input class="ctrl" type="radio" name="help" id="help-records">
|
|
<input class="ctrl" type="radio" name="help" id="help-dmarc">
|
|
<input class="ctrl" type="radio" name="help" id="help-connection">
|
|
<input class="ctrl" type="radio" name="help" id="help-apps">
|
|
<input class="ctrl" type="radio" name="help" id="help-domain-settings">
|
|
<input class="ctrl" type="radio" name="help" id="help-export">
|
|
{{end}}
|
|
|
|
{{define "help_more"}}<p class="more muted"><label for="help-index">All topics</label>{{if .}} · <a href="/help">Help page</a>{{end}}</p>{{end}}
|
|
|
|
{{/* card_help — «?» on a card head; .ID is the topic slug (dns, records, …). */}}
|
|
{{define "card_help"}}
|
|
<label class="help-link" for="help-{{.ID}}" title="{{.Title}}">?</label>
|
|
{{end}}
|
|
|
|
{{define "help_drawer"}}
|
|
<label class="help-scrim" for="help-off"></label>
|
|
<aside class="help-drawer">
|
|
<label class="help-close" for="help-off">Close</label>
|
|
|
|
<article class="help-pane help-pane-index">
|
|
<h2>Help</h2>
|
|
<p>Short notes for the card you opened — not a second copy of the
|
|
<a href="https://github.com/mixeme/selfpost/blob/main/docs/guide.md">operator guide</a>.</p>
|
|
{{if .IsGlobal}}
|
|
<p class="muted">Status</p>
|
|
<ul class="toc"><li><label for="help-status">Status checks</label></li></ul>
|
|
{{end}}
|
|
<p class="muted">Domain</p>
|
|
<ul class="toc">
|
|
<li><label for="help-password">New application password</label></li>
|
|
<li><label for="help-dns">DNS status</label></li>
|
|
<li><label for="help-records">DKIM and SPF records</label></li>
|
|
<li><label for="help-dmarc">DMARC record</label></li>
|
|
<li><label for="help-connection">Connection settings</label></li>
|
|
<li><label for="help-apps">Applications</label></li>
|
|
<li><label for="help-domain-settings">Domain settings</label></li>
|
|
<li><label for="help-export">Export domain</label></li>
|
|
</ul>
|
|
</article>
|
|
|
|
<article class="help-pane help-pane-status">
|
|
<h2>Status checks</h2>
|
|
<p>The cards keep the readings. This drawer is what used to sit under them
|
|
as paragraphs.</p>
|
|
<h2>Machine</h2>
|
|
<p>CPU and memory are the container's readings, not the host's spare
|
|
capacity. Network is a short rate window between refreshes, not a daily
|
|
total. High CPU with an empty queue usually means something else on the box
|
|
— not SelfPost being slow to send.</p>
|
|
<h2>TLS certificate</h2>
|
|
<p>Port 465 presents the certificate the reverse proxy (or the image)
|
|
mounted. The panel does not issue certificates. A warn here is expires
|
|
soon; an error is missing or unreadable, and clients will refuse
|
|
submission.</p>
|
|
<h2>Hostname / reverse DNS</h2>
|
|
<p>Forward-confirmed reverse DNS: the A/AAAA for
|
|
<code>SELFPOST_HOSTNAME</code> must reverse to that same name. PTR is set
|
|
at the hosting provider, not in this panel. Receiving networks use this
|
|
pair as a cheap reputation check.</p>
|
|
<h2>Mail queue</h2>
|
|
<p>Deferred mail is retried on a time schedule (first delay, doubling cap,
|
|
queue lifetime). There is no attempt budget — see the retry-policy card on
|
|
<em>Mail queue</em>.</p>
|
|
{{if .InboundEnabled}}
|
|
<h2>Inbound</h2>
|
|
<p>When <code>INBOUND_RELAY_ENABLE</code> is on, port 25 accepts mail for
|
|
configured domains and forwards it upstream — not to local mailboxes.
|
|
Recipients are a list or any address at the domain.</p>
|
|
{{end}}
|
|
{{template "help_more" true}}
|
|
</article>
|
|
|
|
<article class="help-pane help-pane-password">
|
|
<h2>New application password</h2>
|
|
<p>Shown <strong>once only</strong> and not stored. Copy it now — if it is
|
|
lost, regenerate a new one. The previous password stops working
|
|
immediately.</p>
|
|
{{template "help_more" true}}
|
|
</article>
|
|
|
|
<article class="help-pane help-pane-dns">
|
|
<h2>DNS status</h2>
|
|
<p>The badge is the worst of DKIM, SPF and DMARC. Results are cached a few
|
|
minutes — use <em>Re-check</em> after publishing.</p>
|
|
<p>SPF is a shallow check: the literal address only, no
|
|
<code>include:</code> or <code>redirect=</code>. Report authorization is
|
|
required only when <code>rua=</code> points at a domain this server does
|
|
not accept.</p>
|
|
{{template "help_more" true}}
|
|
</article>
|
|
|
|
<article class="help-pane help-pane-records">
|
|
<h2>DKIM and SPF records</h2>
|
|
<p>DKIM is not a secret. The selector on this page is the one this server
|
|
signs with. Merge the SPF example into an existing record if the domain
|
|
already has one — do not publish a second TXT.</p>
|
|
{{template "help_more" true}}
|
|
</article>
|
|
|
|
<article class="help-pane help-pane-dmarc">
|
|
<h2>DMARC record</h2>
|
|
<p><code>p=none</code> does not affect delivery. Tighten to
|
|
<code>p=quarantine</code> then <code>p=reject</code> once reports look
|
|
clean. The report address is set under Domain settings (or the Settings
|
|
default).</p>
|
|
{{template "help_more" true}}
|
|
</article>
|
|
|
|
<article class="help-pane help-pane-connection">
|
|
<h2>Connection settings</h2>
|
|
<p>Same host for every domain. Authenticate with an application login from
|
|
this page. Auth is required on every port. The password is shown once at
|
|
create or regenerate.</p>
|
|
<p>465 is implicit TLS; 587 is STARTTLS submission when that port is
|
|
enabled.</p>
|
|
{{template "help_more" true}}
|
|
</article>
|
|
|
|
<article class="help-pane help-pane-apps">
|
|
<h2>Applications</h2>
|
|
<p>SASL logins for this domain. Login is unique across domains; letters,
|
|
digits, <code>.</code>, <code>-</code> and <code>_</code>. The password is
|
|
shown once.</p>
|
|
<p>Address mode is which From addresses this application may use: any
|
|
address of the domain, or a fixed list. Client IP allow-list, when enabled,
|
|
restricts which client addresses may <em>submit</em> as this application;
|
|
when off, any client IP is allowed. It is checked in the journal-milter at
|
|
<code>MAIL FROM</code>, alongside the level-2 limit and fail-open like it,
|
|
so it narrows sending rather than blocking the SASL login itself. The
|
|
level-2 rate limit <em>overrides</em> the
|
|
domain limit for that application — you can set a ceiling above or below
|
|
the domain (still ≤ level 1). Independent of the client IP allow-list.</p>
|
|
{{template "help_more" true}}
|
|
</article>
|
|
|
|
<article class="help-pane help-pane-domain-settings">
|
|
<h2>Domain settings</h2>
|
|
<p>Aggregate reports (<code>rua=</code>) inherit the Settings default, or
|
|
you override them per domain. Level 2 is an optional ceiling for all
|
|
senders on this domain; it must be ≤ level 1. Each application may override
|
|
that domain limit (higher or lower, still ≤ level 1).</p>
|
|
{{template "help_more" true}}
|
|
</article>
|
|
|
|
<article class="help-pane help-pane-export">
|
|
<h2>Export domain</h2>
|
|
<p>The file is a secret: it carries the DKIM key and application
|
|
passwords, so published DNS does not have to change on the other instance.
|
|
Transfer it securely, or encrypt it as <code>.spde</code>.</p>
|
|
{{template "help_more" true}}
|
|
</article>
|
|
</aside>
|
|
{{end}}
|