Quarantine with full message history
Every inbound message is written to MariaDB and the
on-disk spool at /var/spool/spamgate/quarantine/.
Review-grade items are never auto-purged. HTML body
preview in the admin UI renders inside a sandboxed
iframe.
Three account roles
Superadmin manages all domains and
settings. Domain admin manages
quarantine and per-domain lists for one domain.
Mailbox user can release messages
addressed to their own mailbox.
Per-domain hold-all-mail
Superadmin-only switch to pause downstream delivery for
a single domain (useful during mailbox migrations).
Clean mail to that domain stays in quarantine; a
one-click "release all held" drains the queue when
the migration completes.
Global and per-domain lists
Blacklist and whitelist with four entry kinds:
email, domain, ip,
cidr. Domain admins manage their own
domain's lists independently of the global rules.
Layered network defences
Four kernel ipsets matched by iptables DROP rules on
ports 25/80/443:
spamgate-scanners - ShadowWhisperer list
spamgate-stretchoid - upstream feed + /var/log/mail.log harvest
spamgate-internet-census - internet-census.org ranges
spamgate-blocked-clients - mirror of the Postfix CIDR table (Censys, Shadowserver)
Plus seven fail2ban jails covering SMTP auth, EHLO
floods, DNSBL violators, no-PTR retriers, and web-UI
exploit probes.
Phishing intelligence
Daily download of the phishing.mailscanner.info
bad-sites list, merged with a local-override file that
is preserved across updates. Listed URLs in a message
body fire a hard score that cannot be cancelled by
other URLs in the same mail.
AbuseIPDB integration (optional)
Daily download of the AbuseIPDB worst-offender blacklist
into a static radix map - no per-message API calls, so
a free-tier token is sufficient. A listed sender IP
pushes the score above the review threshold so the
message is held rather than rejected.
Cluster-shared Bayes
Rspamd's Bayes classifier is shared across cluster
nodes via Redis replication from the main. Train once,
every node benefits. Bulk training and retraining via
the train_bayes.py helper.
Audit log and reports
Every state-changing action - account creation, list
edit, release, domain hold, password reset - lands in
audit_log. The reports page renders
quarantine stats with Chart.js.
Drift-safe updater
update.sh uses a three-way diff (baseline
vs deployed vs new template) on every config file and
only prompts when both the operator and the template
have diverged. Pending schema migrations are offered
one at a time.
Config backup / restore
backup_restore.py archives the
configuration surface - users, lists, settings,
domains, cluster nodes, Bayes dump.rdb,
system configs, iptables and ipset rules.
Operator-friendly tooling
A root-run reset_password.py rescues
lockouts without needing the web UI. A
test_dkim_dmarc.py diagnostic prints SPF,
DKIM and DMARC results for any domain in one shot.