Applies to: SimpleTwo 0.9.x, mail 0.43 · Checked: 27.09.2026
SimpleTwo mail is two roles. mail holds the mailboxes, the queue and the database; clients connect to it. mx is the edge: it takes mail from the internet, sends mail out, signs it with DKIM and checks what arrives. The mx nodes keep no database and no mailboxes, only a queue on their own disk. Between the two are LMTP (on mail) and port 2525 (on mx), closed to anyone but each other.
Until DNS has an MX record pointing at an mx node, no mail reaches you from the internet — and
that is right until somebody is named to answer abuse reports (the abuse@ and postmaster@
addresses). Make them aliases in identity for real people before you publish the MX record.
1. DNS records and DKIM keys
Console → Mail → Mail DNS shows each mail domain's records — MX, SPF, DMARC, DKIM, SRV, MTA-STS and TLS-RPT — and checks each one in DNS.
The coordinator makes the DKIM keys: an ed25519 and an RSA 2048 pair per domain. Changing a key takes three steps:
- New DKIM key makes a new pair; publish its two records.
- Activate the new key is available only once the new records answer in DNS.
- The old pair is retired; its records may go seven days later, on the date the card shows.
2. Devices without a password
Printers, an ERP or a monitoring system that cannot sign in are set up in Console → Mail → Mail devices: a name, the networks they connect to mx port 25 from, the addresses they may write as, and where to (inside the organisation only, or anywhere). Everything else signs in with an app password on ports 587/465.
3. Content filters
The filters are the MX_FILTERS variable on the mx node, a JSON list in the order they check:
[
{"name": "rspamd", "transport": "milter", "address": "inet:127.0.0.1:11332", "on_error": "open"},
{"name": "av", "transport": "icap", "address": "icap://av.corp.example:1344/respmod", "on_error": "closed"}
]
- milter — rspamd, clamav-milter, spamass-milter. A message the filter marks as spam
(
X-Spam: Yesand the like, thespam_signalfield) goes to Junk; the filter's fields are in the message's delivery headers, and the message's bytes are never changed. - icap — an anti-virus over RFC 3507. How the product says it found something is the
verdictfield (headers,header_patterns,on_modified_body,status_codes). on_error— what a filter that does not answer means:openlets the message through without it (the anti-spam default),closedtells the sender 451 to try again later (for an anti-virus).on_virus— an anti-virus's find:quarantine(ICAP's default) orreject.
A list that does not parse stops the service: a filter configured and quietly not run is mail
nobody checked. Greylisting is rspamd's greylist module with a Redis shared by every mx node;
mx keeps no greylist of its own.
4. DNS block lists
Every client of port 25 is checked against MX_DNSBL_ZONES (default zen.spamhaus.org). A
listed client is told 554 5.7.1 … blocked using <zone> at every MAIL. Addresses in
MX_DNSWL_ZONES are not checked.
Each zone tests itself at start and hourly. A zone that stops answering as it should is
disabled, and the mx node's /healthz says why. The usual cause is a query through a public
resolver, which Spamhaus refuses: the node's resolver must be its own. Commercial use of Spamhaus
needs a DQS key.
5. The quarantine
A message in which the anti-virus found a virus, and one a filter quarantined, is held on the server. The sender is told it was accepted. Each recipient gets a notice from the postmaster: who sent it, the subject, the date, the reason, and the number to give the administrator.
Console → Mail → Quarantine lists the held messages. Only an administrator releases one to
its recipients or deletes it, and each action goes into the audit log with the administrator's
name. What nobody decides on is deleted after 30 days (MAIL_QUARANTINE_DAYS).
6. Groups with members outside
When a group has outside addresses (partners), each gets a copy of its own. The copy's
reverse-path is the group's service address, sales+bounce.<token>@corp.example, so an outside
recipient's refusal comes back to the group, not to whoever wrote to it.
- A bounce is logged on the copy's path in the delivery log, and kept in the domain's
postmaster@mailbox when there is one. - Never passed outside: delivery notices, messages judged spam, held messages, and all of a group's mail when the installation has no mx node.
- After five bounces in a row (each within a week of the last) a member outside is disabled: its copies stop and the log says why. An administrator can enable it again.
- When a sender signs with SPF alone and its domain has
p=reject, a recipient outside may refuse the copy. That is a known limit of mailing lists.
7. MTA-STS
When a recipient's domain publishes an MTA-STS policy in enforce mode, mx sends it mail only to
the servers the policy lists, only over TLS, and only to a certificate valid for the server's
name. When that cannot be done, the message is not sent in the clear: it waits and is tried again.
The policies are kept on the mx node's disk; /healthz counts them.
Your own domain's policy is published by the coordinator. Mail DNS has three records for it:
_mta-sts.<domain>: a TXT record with the current policy's id. The id changes with the policy, and the record must then be updated.mta-sts.<domain>: a CNAME to the coordinator. The coordinator obtains the certificate for this name itself and serves the policy athttps://mta-sts.<domain>/.well-known/mta-sts.txt. The policy lists every mx node._smtp._tls.<domain>: a TXT record for TLS-RPT reports, sent totls-reports@<domain>. Make that address an alias for whoever reads the reports.
The policy's mode is chosen on the same card. Start with testing: senders report failures but
still deliver. Turn on enforce once a week of reports shows none. Under enforce a sender keeps
the policy for a week and sends only to the nodes it lists. It takes a new mx node once it sees
a new id in _mta-sts, so update that record as soon as you add a node.
8. The delivery log
Any message's path — from mx to a mailbox or to a remote server — is found by either side's queue number or by address. The mx events wait on the node's disk and reach the log even if the mail cluster was away.