Transaction context
As described in the Configuring vSMTP
chapter, domains handled by the configuration of vSMTP have three filtering entry-points: incoming
, outgoing
and internal
.
/etc/vsmtp
β£ vsmtp.vsl
β£ filter.vsl
β£ conf.d/
β β config.vsl
β£ domain-available/
+ β β example.com
+ β β£ incoming.vsl
+ β β£ outgoing.vsl
+ β β internal.vsl
+ β domain-enabled/
+ β example.com -> ...
Adding filtering scripts for the `example.com` domain
Here is a diagram of which entry-points are executed following the transaction pipeline.
Rules execution order following the transaction context
Root Filter β¬
The root filter.vsl
script is used to filter incoming transaction at the connect
, helo
and authenticate
stages. The rules contained in those stages are applied to ALL incoming transactions.
This script also run rules under the mail
stage when an incoming sender domain is not handled by the configuration.
Finally, if the senderβs domain is not handled by the configuration, and that the domain of recipients is not as well, rules defined in the rcpt
stage contained in the root filter.vsl
are also called. By default, the transaction should be denied at this stage since it probably is a relay tentative.
#{
rcpt: [
rule "deny relay" || state::deny(),
]
}
anti-relaying using rules in `filter.vsl`
If this file is not present in the rule directory, it will deny all transactions by default.
Incoming π¨
The incoming.vsl
script is run if the sender domain is not handled by the configuration, but domains from recipients are.
MAIL FROM: <john.doe@unknown.com> # We don't have a `unknown.com` folder, this is an incoming message.
RCPT TO: <foo@example.com> # `example.com` is handled, we run `example.com/incoming.vsl`.
RCPT TO: <bar@example.com> # Same as above.
Transaction example
If any recipient domain in this context is not handled by the configuration, then the root filter.vsl
script is called.
MAIL FROM: <john.doe@unknown.com> # We don't have a `unknown.com` folder, this is an incoming message.
RCPT TO: <foo@example.com> # `example.com` is handled, we run `example.com/incoming.vsl`.
RCPT TO: <bar@anonymous.com> # We don't have a `unknown.com` folder, the root `filter.vsl` is used.
Transaction example
A client should not mix up multiple recipient domains when sending a message to the server. This is why the root filter.vsl
script is called when this happens. Once again, if incoming.vsl
is not defined, the transaction will be denied by default.
Outgoing πͺ
The outgoing.vsl
script is run if the sender domain is handled by the configuration, but recipients are not.
MAIL FROM: <john.doe@example.com> # `example.com` exists, this is an outgoing message.
RCPT TO: <foo@anonymous.com> # We don't have a `anonymous.com` folder, `outgoing.vsl` is used.
RCPT TO: <bar@anonymous.com> # Same as above.
Transaction example
Internal π©
The internal.vsl
script is run if the sender and recipients domains are handled by the configuration and the exact same.
MAIL FROM: <john.doe@example.com> # `example.com` exists, we don't know yet about the recipient, so this is an outgoing message for now.
RCPT TO: <foo@example.com> # The domain is the same as the sender, `internal.vsl` is used, it becomes an internal message now.
RCPT TO: <bar@example.com> # Same as above.
Transaction example
Sub domains
Root domain rules are used when a sub domain does not have any rules configured.
For example, if the configuration has rules setup for the example.com
domain, but does not for the dev.example.com
, if any transaction has the dev.example.com
sub-domain, rules for example.com
will be used.