Filtering
By default, the server will deny any SMTP transaction. We have to define filtering rules to accept connections and filter messages.
In this chapter, we will get a glimpse of vSMTPβs filtering system. To create filtering rules, we recommend checking out the vSL reference, focussing on the following chapters:
For this example, we will configure the following rules:
- Messages from blacklisted domain will be rejected.
- As Jenny is 11 years old, Jane wants her address to be added as a blind carbon copy of messages destined to her daughter.
- Messages sent to the family must be delivered in Mailbox format.
Configuration
Letβs first add our filters in the /etc/vsmtp/conf.d/config.vsl
script.
fn on_config(config) {
// Name of the server.
config.server.name = "doe-family.com";
// addresses that the server will listen to.
// (change `192.168.1.254` for the desired address)
config.server.interfaces = #{
addr: ["192.168.1.254:25"],
addr_submission: ["192.168.1.254:587"],
addr_submissions: ["192.168.1.254:465"],
};
+ // Root filter.
+ config.app.vsl.filter_path = "/etc/vsmtp/filter.vsl";
+ // Domain specific filters.
+ config.app.vsl.domain_dir = "/etc/vsmtp/domain-enabled";
config
}
Root Filter
Letβs define the root filter for incoming emails.
/etc/vsmtp/
β£ vsmtp.vsl
+β£ filter.vsl
β£ conf.d/
β β£ config.vsl
β β *.vsl
β objects/
β family.vsl
Adding the root filtering script
The filter.vsl
script is responsible for handling clients that just connected to vSMTP.
Add anti-relaying
Letβs setup anti-relaying by adding the following rule. (See the Root Filter section in the Transaction Context chapter for more details)
#{
rcpt: [
rule "anti relaying" || state::deny(),
]
}
/etc/vsmtp/filter.vsl
Use the blacklist
We can add the blacklist we defined in the Blacklist section to filter out sender domains that we do not trust.
// Importing objects that we defined in the last chapter.
+import "objects/family" as family;
#{
+ mail: [
+ rule "do not deliver untrusted domains" || {
+ if ctx::mail_from().domain in family::blacklist {
+ state::quarantine(family::untrusted_queue)
+ } else {
+ state::next()
+ }
+ },
+ ],
rcpt: [
rule "anti relaying" || state::deny(),
]
}
/etc/vsmtp/filter.vsl
The do not deliver untrusted domains
rule will save any email from senders found in the blacklist in a quarantine folder named βuntrustedβ and will not deliver the email.
Filtering for doe-family.com
Letβs create filtering rules for the doe-family.com
domain.
/etc/vsmtp
β£ vsmtp.vsl
β£ filter.vsl
β£ conf.d/
β β£ config.vsl
β β *.vsl
+ β£ domain-available/
+ β β doe-family.com/
+ β β£ incoming.vsl
+ β β£ outgoing.vsl
+ β β internal.vsl
+ β£ domain-enabled/
β objects/
β family.vsl
adding filtering scripts for the `doe-family.com` domain
Since we specified in the configuration that the domain-enabled
directory was our domain filtering directory, we need to create a symbolic link to domain-available/doe-family.com
to enable filtering for doe-family.com
.
/etc/vsmtp
β£ vsmtp.vsl
β£ filter.vsl
β£ conf.d/
β β£ config.vsl
β β *.vsl
β£ domain-available/
β β doe-family.com/
β β£ incoming.vsl
β β£ outgoing.vsl
β β internal.vsl
β£ domain-enabled/
+ β β example.com -> /etc/vsmtp/domain-available/doe-family.com
β objects/
β family.vsl
Enabling the `example.com` domain filtering
vSMTP will pickup incoming.vsl
, outgoing.vsl
and internal.vsl
scripts under a folder with a fully qualified domain name. Those rules will be run following vSMTPβs transaction logic. Letβs define rules for each cases.