Filtering
It is possible to filter emails using .vsl
files for incoming emails and specific domains. vSL
is the vSMTP scripting language
, a superset of Rhai which is used to filter emails, modify their contents, send them to a specific target, etc.
The vSL chapter explains in detail what is possible to do with
.vsl
scripts.
Root Filter
The root filter.vsl
script is used to filter incoming transaction at the connect
, helo
and authenticate
stages of an SMTP transaction. (Check out the Transaction Context chapter for more details)
/etc/vsmtp
β£ vsmtp.vsl
+β£ filter.vsl
β£ conf.d/
β β£ config.vsl
β β£ interfaces.vsl
β β app.vsl
β£ domain-available/
β£ domain-enabled/
β£ objects/
β£ services/
β plugins/
Adding the root filter script
#{
connect: [
rule "deny all" || state::deny(),
]
}
Content of the `filter.vsl` file. Denies every transaction by default.
fn on_config(config) {
config.app.vsl.filter_path = "/etc/vsmtp/filter.vsl";
return config;
}
Specifying the path to the filter in the configuration
If this script is not present, vSMTP will deny all incoming transactions by default.
Domains
It is also possible to filter emails per domain.
β£ vsmtp.vsl
β£ filter.vsl
β£ conf.d/
β β£ config.vsl
β β£ interfaces.vsl
β β app.vsl
β£ domain-available/
+β β example.com/
+β β£ incoming.vsl
+β β£ outgoing.vsl
+β β internal.vsl
β£ domain-enabled/
β£ objects/
β£ services/
β plugins/
Adding filtering scripts for the `example.com` domain under the `domain-available` directory
The configuration in conf.d/config.vsl
must be updated like so:
fn on_config(config) {
config.app.vsl.domain_dir = "/etc/vsmtp/domain-enabled";
return config;
}
Specifying filtering rules directory for domains in the configuration
In the above configuration, vSMTP has been setup to pickup filtering rules in the domain-enabled
directory, not domain-available
. Letβs use symbolic links to make our scripts available for vSMTP inside the domain-available/example.com
directory.
/etc/vsmtp
β£ vsmtp.vsl
β£ filter.vsl
β£ conf.d/
β β£ config.vsl
β β£ interfaces.vsl
β β app.vsl
β£ domain-available/
β β example.com/
β β£ incoming.vsl
β β£ outgoing.vsl
β β internal.vsl
β£ domain-enabled/
+β β example.com -> /etc/vsmtp/domain-available/example.com
β£ objects/
β£ services/
β plugins/
Using symlinks to enable filtering for the `example.com` domain
This directory structure is standard. The goal here is to disable / enable domain specific filtering by simply removing / adding symbolic links while keeping the configuration intact.
The server will pickup the scripts defined in the domain-enabled/example.com
directory and run them following the conditions defined in the Transaction Context chapter.
Domain specific configuration
It is possible to add a specific configuration for each domain.
/etc/vsmtp
β£ vsmtp.vsl
β£ filter.vsl
β£ conf.d/
β β£ config.vsl
β β£ interfaces.vsl
β β app.vsl
β£ domain-available/
β β example.com
+β β£ config.vsl
β β£ incoming.vsl
β β£ outgoing.vsl
β β internal.vsl
β£ domain-enabled/
β β example.com -> /etc/vsmtp/domain-available/example.com
β£ objects/
β£ services/
β plugins/
Adding specific configuration for a domain
Although it is not mandatory to add a config.vsl
script under a domain directory, if it is created, it must contain, at least, the following statement:
fn on_domain_config(config) {
config
}
An empty domain specific configuration
Like the root config.vsl
file, this script contains a function used to configure the domain, in this case called on_domain_config
. It is possible to configure TLS, DKIM and DNS for each domain.
fn on_domain_config(config) {
config.tls = #{
protocol_version: ["TLSv1.2", "TLSv1.3"],
certificate: "/etc/vsmtp/certs/fullchain.pem",
private_key: "/etc/vsmtp/certs/privkey.pem",
};
config.dkim = #{
private_key: "/etc/vsmtp/certs/example.dkim.key",
};
config.server.dns.type = "system";
config
}
Changing TLS, DKIM and DNS parameters for a specific domain
If this script is not present in a domain directory, configuration from the root
config.vsl
script is used instead.