Anti-abuse checks of SMTP clients, run by Sovite.Core.SMTPHandler
before its own checks of each stage. Clients in
smtp.trusted_networks skip all of them.
The screen
On listeners with screen (by default those in smtp mode), each
client gets a score, as with Postfix's postscreen:
- The client address is looked up in the
[[screen.dnsbl]]lists (Sovite.Abuse.DNSBL), in the background. Each list it is on adds its weight; allow lists such as DNSWL have negative weights. - With
screen.greet_delay, the greeting waits that long. A client that talks first addsscreen.early_talker_weight. - At
EHLOandMAIL, the[[screen.rhsbl]]lists are checked for theEHLOname and the sender's domain.
A client that reaches screen.threshold is refused: before the
greeting with 554 5.7.1, then the connection is closed; at EHLO or
MAIL, that command gets 554 5.7.1. A client at or below
screen.allow_threshold is allow-listed: the domain lists and
greylisting are skipped. A client that passed the greeting, without
talking first or a failed lookup, is remembered for screen.cache_time
and not delayed or looked up again meanwhile.
Rate limits
The [rate_limit] limits count, per client address (per /64 for
IPv6), new connections (421 4.7.0 and closed), messages (MAIL,
450 4.7.1), and recipients (450 4.7.1); and per authenticated user,
messages and recipients. Authenticated clients only count against the
user limits.
Greylisting
With greylist.enabled, a valid recipient from an unknown client
network and sender is deferred with 450 4.7.1 until the client tries
again after greylist.delay, see Sovite.Core.Greylist. Authenticated
and allow-listed clients, and listeners without screen, skip it.
Outbound
Authenticated users whose mail fails too often are suspended, see
Sovite.Core.Outbound; their MAIL gets 550 5.7.1.
Telemetry
[:sovite, :screen, :rejected]-%{score},%{session_id, remote_ip, stage, reasons}, when a client reaches the threshold.
Summary
Functions
Starts screening the client: looks it up in the DNS lists, and asks for the greeting delay.
Scores the client before the greeting, see the moduledoc.
Checks the EHLO name in the RHSBL lists.
Counts the connection against rate_limit.client_connections.
Checks a MAIL command: suspension and sending limits of the user,
message limits of the client, and the sender's domain in the RHSBL
lists.
The screen state of a new session.
The options for a listener. runtime has :screen (the listener
screens clients), :screen_cache (a Sovite.Abuse.Cache),
:rate_limit (a Sovite.Abuse.RateLimit), :repo, and :outbound
(Sovite.Core.Outbound options).
Checks an accepted recipient: greylisting, and the recipient limits of the user or the client.
Functions
@spec connect(map()) :: {:ok, map()} | {:pause, pos_integer(), map()}
Starts screening the client: looks it up in the DNS lists, and asks for the greeting delay.
@spec greet(binary(), map()) :: {:ok, map()} | {:close, Sovite.SMTP.Reply.t(), map()}
Scores the client before the greeting, see the moduledoc.
@spec helo(map()) :: {:ok, map()} | {:reply, Sovite.SMTP.Reply.t(), map()}
Checks the EHLO name in the RHSBL lists.
@spec limit_connection(map()) :: {:ok, map()} | {:close, Sovite.SMTP.Reply.t(), map()}
Counts the connection against rate_limit.client_connections.
@spec mail(String.t(), map()) :: {:ok, map()} | {:reply, Sovite.SMTP.Reply.t(), map()}
Checks a MAIL command: suspension and sending limits of the user,
message limits of the client, and the sender's domain in the RHSBL
lists.
@spec new() :: map()
The screen state of a new session.
@spec opts(Sovite.Core.Config.t(), keyword()) :: map()
The options for a listener. runtime has :screen (the listener
screens clients), :screen_cache (a Sovite.Abuse.Cache),
:rate_limit (a Sovite.Abuse.RateLimit), :repo, and :outbound
(Sovite.Core.Outbound options).
@spec rcpt(String.t(), map()) :: {:ok, map()} | {:reply, Sovite.SMTP.Reply.t(), map()}
Checks an accepted recipient: greylisting, and the recipient limits of the user or the client.