release: 1.4.0: Optional inbound relay (backup-MX) on port 25
Optional inbound relay (backup-MX / forwarder) on port 25, off by default. Mail is accepted only for domains configured in the panel and forwarded to an upstream; there are still no mailboxes. A dedicated security review of the inbound path is still open on the plan (Fable). Added: - `INBOUND_RELAY_ENABLE` (default `false`): when true, Postfix listens on - Panel **Inbound** pages (global administrator): domains, upstream host/port - Optional `INBOUND_ANTISPAM_MILTER` on the inbound listener only, plus - Inbound rate limit (`INBOUND_RATE_LIMIT_MESSAGES_PER_IP`, default 20) and Changed: - Compose publishes host port 25 even when the flag is off (nothing listens - Full-backup restore Resync also rebuilds inbound maps when the flag is on. Full detail: CHANGELOG.md (1.4.0).
This commit is contained in:
@@ -11,6 +11,21 @@ SELFPOST_HOSTNAME=mail.example.com
|
||||
# primary 465/smtps listener.
|
||||
SUBMISSION_ENABLE=false
|
||||
|
||||
# Optional inbound relay (backup-MX / forwarder). When true, Postfix accepts
|
||||
# mail on port 25 only for domains configured in the panel and forwards them
|
||||
# to the upstream you set. Off by default — the outbound path is unchanged.
|
||||
INBOUND_RELAY_ENABLE=false
|
||||
|
||||
# Optional milter on the inbound listener only (not 465/587). Empty = off.
|
||||
# Example with deploy/antispam/docker-compose.antispam.yml:
|
||||
# INBOUND_ANTISPAM_MILTER=inet:antispam:11332
|
||||
# INBOUND_ANTISPAM_MILTER_ACTION=accept
|
||||
|
||||
# Coarse per-client-IP limit and message size on inbound smtpd (port 25).
|
||||
# INBOUND_RATE_LIMIT_MESSAGES_PER_IP=20
|
||||
# INBOUND_MESSAGE_SIZE_LIMIT=26214400
|
||||
|
||||
|
||||
# Level-1 backstop rate limit (anvil) — see docs/guide.md "Rate limiting".
|
||||
RATE_LIMIT_MESSAGES_PER_IP=100
|
||||
RATE_LIMIT_WINDOW_SECONDS=3600
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
# Optional anti-spam sidecar for inbound relay (docs/plans/inbound-relay.md).
|
||||
#
|
||||
# SelfPost does not ship or start an anti-spam engine. This fragment brings up
|
||||
# rspamd next to SelfPost and points the inbound smtpd milter at it. Merge it
|
||||
# only when you want filtering on port 25:
|
||||
#
|
||||
# docker compose -f docker-compose.yml -f antispam/docker-compose.antispam.yml up -d
|
||||
#
|
||||
# Requires INBOUND_RELAY_ENABLE=true in .env. The milter sees the real client
|
||||
# IP, HELO and PTR — unlike the upstream, which only sees SelfPost's address.
|
||||
#
|
||||
# Pin the rspamd tag the same way the SelfPost image is pinned; bump it
|
||||
# deliberately. Default milter action is fail-open (accept) so a down sidecar
|
||||
# does not block backup-MX. Set INBOUND_ANTISPAM_MILTER_ACTION=tempfail to
|
||||
# defer instead.
|
||||
|
||||
services:
|
||||
selfpost:
|
||||
environment:
|
||||
INBOUND_RELAY_ENABLE: "${INBOUND_RELAY_ENABLE:-true}"
|
||||
INBOUND_ANTISPAM_MILTER: "${INBOUND_ANTISPAM_MILTER:-inet:antispam:11332}"
|
||||
INBOUND_ANTISPAM_MILTER_ACTION: "${INBOUND_ANTISPAM_MILTER_ACTION:-accept}"
|
||||
depends_on:
|
||||
- antispam
|
||||
|
||||
antispam:
|
||||
image: rspamd/rspamd:3.11
|
||||
restart: unless-stopped
|
||||
# No host ports: only SelfPost talks to the milter on the compose network.
|
||||
@@ -23,6 +23,7 @@ services:
|
||||
ports: !override
|
||||
- "465:465"
|
||||
- "587:587"
|
||||
- "25:25"
|
||||
environment:
|
||||
# Caddy names certificate files after the hostname, not
|
||||
# fullchain.pem/privkey.pem like certbot — override the base file's
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
|
||||
services:
|
||||
selfpost:
|
||||
image: ghcr.io/mixeme/selfpost:1.3.1
|
||||
image: ghcr.io/mixeme/selfpost:1.4.0
|
||||
restart: unless-stopped
|
||||
environment:
|
||||
SELFPOST_HOSTNAME: "${SELFPOST_HOSTNAME:?set the mail/panel hostname, e.g. mail.example.com}"
|
||||
@@ -33,6 +33,11 @@ services:
|
||||
# Set to true to also publish RFC 6409 submission (587/STARTTLS)
|
||||
# alongside the primary 465/smtps listener (spec 5).
|
||||
SUBMISSION_ENABLE: "${SUBMISSION_ENABLE:-false}"
|
||||
INBOUND_RELAY_ENABLE: "${INBOUND_RELAY_ENABLE:-false}"
|
||||
INBOUND_ANTISPAM_MILTER: "${INBOUND_ANTISPAM_MILTER:-}"
|
||||
INBOUND_ANTISPAM_MILTER_ACTION: "${INBOUND_ANTISPAM_MILTER_ACTION:-accept}"
|
||||
INBOUND_RATE_LIMIT_MESSAGES_PER_IP: "${INBOUND_RATE_LIMIT_MESSAGES_PER_IP:-20}"
|
||||
INBOUND_MESSAGE_SIZE_LIMIT: "${INBOUND_MESSAGE_SIZE_LIMIT:-26214400}"
|
||||
# Level-1 backstop rate limit (anvil, spec 5.5, 7.4); per-domain/app
|
||||
# limits (level 2) are configured later from the panel itself.
|
||||
RATE_LIMIT_MESSAGES_PER_IP: "${RATE_LIMIT_MESSAGES_PER_IP:-100}"
|
||||
@@ -76,6 +81,9 @@ services:
|
||||
# 587 is mapped even when SUBMISSION_ENABLE=false; Postfix listens only
|
||||
# when the variable is true — see docs/guide.md "Published ports".
|
||||
- "587:587"
|
||||
# 25 is mapped even when INBOUND_RELAY_ENABLE=false; Postfix listens only
|
||||
# when the variable is true.
|
||||
- "25:25"
|
||||
- "127.0.0.1:8080:8080"
|
||||
# Hardening (spec 10 p.6). SelfPost's entrypoint still needs to run as
|
||||
# root very briefly to fix /data ownership and normalise permissions
|
||||
@@ -85,7 +93,7 @@ services:
|
||||
# self-healing. What IS applied: no privilege escalation past what the
|
||||
# image already grants, and every Linux capability dropped except the
|
||||
# small set the root startup phase and Postfix/OpenDKIM genuinely need:
|
||||
# - NET_BIND_SERVICE — bind 465/587 (and 25 outbound) below 1024;
|
||||
# - NET_BIND_SERVICE — bind 465/587 and inbound 25 below 1024;
|
||||
# - CHOWN — entrypoint re-owns /data (bind mount) to `panel`;
|
||||
# - FOWNER — entrypoint then chmods those now panel-owned /data
|
||||
# dirs/files while still root (owner-check bypass);
|
||||
|
||||
@@ -23,6 +23,7 @@ services:
|
||||
ports: !override
|
||||
- "465:465"
|
||||
- "587:587"
|
||||
- "25:25"
|
||||
# No host publish for 8080 here: nginx reaches it over the compose
|
||||
# network at selfpost:8080 instead (see nginx.conf.example).
|
||||
volumes: !override
|
||||
|
||||
@@ -15,6 +15,7 @@ services:
|
||||
ports: !override
|
||||
- "465:465"
|
||||
- "587:587"
|
||||
- "25:25"
|
||||
volumes: !override
|
||||
- ./data:/data
|
||||
- .:/selfpost-deploy:ro
|
||||
|
||||
Reference in New Issue
Block a user