The MTA's Sovite.SMTP.Server.Handler: relay control, restrictions,
authentication, recipient checks and expansion, and durable spooling.
Recipients are checked at RCPT time:
<Postmaster>, andpostmaster@andabuse@any hosted domain, are always accepted (RFC 5321 §4.5.1, RFC 2142). A bare<Postmaster>is queued aspostmaster@<server.hostname>.- Domains this server handles (local, aliased, hosted, and relay; see
Sovite.Core.Routing): the recipient is expanded (Sovite.Core.Recipients.expand/2); one that no alias matched must be a known user (Sovite.Core.Recipients.check/2), otherwise550 5.1.1. - Any other destination, including address literals: accepted only from
smtp.trusted_networksor afterAUTH, otherwise554 5.7.1 Relay access denied. The default config trusts no one, so it is never an open relay.
Domains are compared case-insensitively. Address tricks such as
user%remote@local or source routes do not relay: only the domain of
the parsed mailbox counts.
The anti-abuse checks (Sovite.Core.Screen: the postscreen-like
client score, rate limits, greylisting, and suspended users) run
first at each stage.
The restriction chains (Sovite.Core.Restrictions) run at connect,
EHLO, MAIL, RCPT, DATA, and at the end of the data, after the
built-in checks of each stage; they can reject, but never permit what
relay control or recipient validation refuses. Policy servers in them
(Sovite.Core.PolicyService) may also add header fields, redirect or
copy the message, or send it to a content filter.
The listener's milters (Sovite.Core.Milters) see each stage last,
and change the message at the end of the data.
Rewriting
The sender is rewritten at MAIL (Sovite.Core.Rewrite.sender/2) and
each recipient at RCPT, before expansion. routing.always_bcc and
the BCC maps add recipients at DATA. Mail from trusted networks and
authenticated clients also gets its header addresses rewritten.
Authentication
AUTH runs against the configured backend (auth.backend), see
Sovite.SASL.Server and Sovite.SASL.Dovecot. Failed logins are
counted per client address (per /64 for IPv6) in a
Sovite.Abuse.Penalty; a banned address gets 454 4.7.0 to AUTH, and
is turned away at connect on listeners that require authentication.
Each failure is answered after auth.failure_delay, to slow down
guessing.
An authenticated client may only use the sender addresses its login
maps to, see Sovite.Core.SenderCheck.
Submission fixes
Messages from authenticated clients are fixed up as RFC 6409 §8 allows:
a missing Date: or Message-ID: is added, and the header fields in
submission.strip_headers are removed.
Email authentication
Mail from outside is checked with SPF, DKIM, ARC, and DMARC, mail from
users is DKIM signed, and forwarded mail is ARC sealed, see
Sovite.Core.MailAuth.
With srs.enabled, mail from outside that an alias forwards to another
domain gets an SRS sender address (Sovite.SRS) for that delivery, so
SPF passes at the destination. Bounces to those addresses are accepted
for the original sender at RCPT, and invalid or expired ones are
refused with 550 5.1.1.
REQUIRETLS
With smtp.requiretls (the default), REQUIRETLS (RFC 8689) is
offered over TLS. A message sent with it is queued with
requiretls, so Sovite.Core.Delivery relays it only over verified
TLS.
DSN
The DSN parameters (RFC 3461) are kept in the queued message, for
each recipient after expansion: a recipient that an alias forwards to
one address keeps them, and gets the address the client gave as its
ORCPT when it had none. An alias that expands to several addresses
passes them on without SUCCESS in NOTIFY, and when the client
asked for SUCCESS, the alias itself gets an "expanded" notification
(RFC 3461 §5.2.7.3, option c).
Priorities, deadlines, and RRVS
The MT-PRIORITY (RFC 6710) of a message is kept, except that clients
neither trusted nor authenticated cannot raise it above 0. Only
authenticated clients may hold messages for later (FUTURERELEASE,
RFC 4865), and a DELIVERBY time (RFC 2852) becomes a deadline from
the time the message arrived.
A recipient with RRVS (RFC 7293) that is a mailbox here (in the
database) is refused with 550 5.7.17 if the mailbox was added after
the given time. Other local recipients pass, as do role accounts
(RFC 2142); one that is relayed keeps its RRVS for the next hop,
unless an alias changed it.
ETRN
ETRN (RFC 1985) starts the delivery of deferred mail for a relay
domain (Sovite.Core.Routing), or with @, for it and its subdomains, as
Postfix's fast_flush_domains does by default. Other domains and
named queues get 459.
Loops
A message with more than smtp.max_hops Received: fields is refused
at the end of the data with 554 5.4.6 (RFC 5321 §6.3): it is most
likely going round in circles.
Proxies and content filters
A client that used XCLIENT (from smtp.xclient_networks) is
treated as the client it named: its LOGIN counts as authenticated,
and its NAME as its verified reverse DNS name.
On a listener with a content filter, messages are queued for the
filter (Sovite.Core.QueueManager). A reinjection listener is
where filters send them back: email authentication is skipped there,
as it ran when the message first arrived. XFORWARD attributes from
the filter (smtp.xforward_networks) are kept as the message's
original client.
Queueing
The message is accepted with 250 only after Sovite.Queue.Spool
has made it durable. A Received: header is added at the top. The
queue manager given as :queue_manager is then told about it. A
message a restriction put on hold goes to the hold queue instead; one
it discarded is accepted and dropped.
Telemetry
[:sovite, :smtp, :message, :discarded]and[:sovite, :smtp, :message, :held]-%{},%{session_id, queue_id, reason}[:sovite, :routing, :expansion_error]-%{},%{session_id, recipient, reason}
Summary
Functions
Handler options from the running configuration.
Functions
@spec opts(Sovite.Core.Config.t(), GenServer.server() | nil, keyword()) :: map()
Handler options from the running configuration.
queue_manager- theSovite.Core.QueueManagerto notify about new messages, if any.runtime-:repo(aSovite.Core.Reporeference),:milters(the names of the listener's milters),:penalty(the name of theSovite.Abuse.Penaltyfor failed logins),:require_auth(the listener requires authentication),:resolver(for restrictions that look up domains), and theSovite.Core.Screenoptions:screen,:screen_cache,:rate_limit, and:outbound, and the listener's:content_filterand:reinjection.