policyd-client is a rudimentary tool to query a policy server from the command line. It will generate the instance and request fields all other fields must be specified on stdin and the request is completed by a blank line.
policyd-client [-?hhksv] [long options...] -h -? --usage --help Prints this usage information. -h --host host:port of a policyd -s --socket_path path to a socket of a policyd -k --keepalive use connection keepalive? -v --verbose be verbose, print input/output to STDERR
$ policyd-client -v -h localhost:12347 client_address=212.178.212.218 >> request=smtpd_access_policy >> instance=0.133885340838791 >> client_address=212.178.212.218 >> << action=reject IP is blacklisted << reject IP is blddacklisted
mtpolicyd - a modular policy daemon for postfix
mtpolicyd is a policy daemon for postfix access delegation.
It can be configured to accept connections on several ports from a postfix MTA. For each port a VirtualHost can be configured and for each VirtualHost several Plugins can be configured.
In postfix main.cf:
smtpd_recipient_restrictions = check_policy_service inet:127.0.0.1:12345
In mtpolicyd.conf:
# listen on port 12345 (multiple ports can be separated by ',') port="127.0.0.1:12345" # defined host for this port <VirtualHost 12345> name=example_vhost <Plugin spamhaus_bl> module="RBL" domain="sbl.spamhaus.org" mode=reject </Plugin> </VirtualHost>
This check will execute a simple RBL lookup against dbl.spamhaus.org.
mtpolicyd [-h|--help] [-c|--config=<file>] [-f|--foreground] [-l|--loglevel=<level>] [-d|--dump_vhosts]
Show available command line options.
Specify the path to the configuration file.
Do not fork to background and log to stdout.
Overwrite the log level specified in the configuration with the specified level.
Parse VirtualHosts configuration, print it to stdout and exit.
The configuration file is implementend with Config::General which allows apache style configuration files.
mtpolicyd accepts global configuration parameters in the style:
key=value
Comments begin with '#'.
VirtualHosts must be configured with VirtualHost sections:
<VirtualHost <portnumber>> name=<name of the vhost> </VirtualHost>
Each VirtualHost should contain at least on Plugin.
<VirtualHost <portnumber>> name=<name of the vhost> <Plugin <name of check> > module = "<name of plugin>" # plugin options key=value </Plugin> </VirtualHost>
For individual plugin configuration options see the man page of the plugin:
Mail::MtPolicyd::Plugin::<name of plugin>
user id to run as
group id to run as
location of the pid file
Verbosity of logging: 0=>'err', 1=>'warning', 2=>'notice', 3=>'info', 4=>'debug'
ip address to bind to.
comma separated list of ports to listen on.
The minimum number of client processes to start.
The minimum number of client processes that should hanging around idle and wait for new connections.
If the number of free processes is below this threshold mtpolicyd will start to create new child processes.
The maximum number of idle processes.
If the number of idle processes is over this threshold mtpolicyd will start to shutdown child processes.
The absolute maximum number of child processes to start.
Number of requests after that mtpolicyd closes the connection or no limit if set to zero.
Should be the same value as smtpd_policy_service_reuse_count_limit (postfix >2.12) in postfix/smtpd configuration.
Select VirtualHost by 'policy_context' request field.
The policy_context will be matched against the 'name' field of the VirtualHost.
For example in postfix main.cf use advanced syntax:
check_policy_service { inet:localhost:12345, policy_context=reputation } ... check_policy_service { inet:localhost:12345, policy_context=accounting }
In mtpolicyd.conf:
port="127.0.0.1:12345" # only 1 port vhost_by_policy_context=1 <VirtualHost 12345> name=reputation ... plugins ... </VirtualHost> <VirtualHost 12345> name=accounting ... plugins ... </VirtualHost>
The policy_context feature will be available in postfix 3.1 and later.
If you just need small differentiations consider using the Mail::MtPolicyd::Plugin::Condition plugin to match against plugin_context field.
Maximum total time for one request.
mtpolicyd has a global per process connection pool.
Connections could be registered within the connection pool using a <Connection> block within the configuration. You must at least specify the name of the connection and the module for the connection type.
<Connection [name of connection]> module = "[connection type]" # ... addditional parameters </Connection>
Connection modules may require additional parameters.
Currently supported connection modules:
Perl DBI based connections for SQL databases.
Mail::MtPolicyd::Connection::Sql
Connection to a memcached server/cluster.
Mail::MtPolicyd::Connection::Memcached
Connection to an LDAP directory server.
Mail::MtPolicyd::Connection::Ldap
mtpolicyd implements session managemend to cache data across different checks for requests with the same instance id.
mtpolicy is able to generate a session for each mail passed to it and store it within the session cache. The attached session information will be available to all following plugins across child processes, virtual hosts and ports.
Plugins will use this session information to cache lookup etc. across multiple requests for the same mail. Postfix will send a query for each recipient and for each configured check_policy_service call.
To enable the SessionCache specify a <SessionCache> block within your configuration:
<SessionCache> module = "Memcached" expire = "300" lock_wait=50 lock_max_retry=50 lock_timeout=10 </SessionCache>
The example requires that a connection of type "Memcached" and the name "memcached" is configured within the connection pool. For details read Mail::MtPolicyd::SessionCache::Memcached.
As of version 2.00 it is possible to implement different session caches.
Currently there are 2 session cache modules:
The policy daemon will process all plugins in the order they appear in the configuration file. It will stop as soon as a plugin returns an action and will return this action to the MTA.
Most plugins can be configured to not return an action if the performed check matched.
For example the RBL module could be set to passive mode and instead a score could be applied to the request:
<Plugin spamhaus> module = "RBL" mode = "passive" domain="zen.spamhaus.org" score=5 </Plugin>
Check the documentation of the plugin for certain score/mode parameters. Plugin may provide more than one mode/score parameters if the do several checks.
Now if you configure more than one RBL check the score will add up. Later an action can be taken based on the score. The ScoreAction plugin will return an action based on the score and the AddScoreHeader plugin will prepend the score as a header to the mail:
<Plugin ScoreReject> module = "ScoreAction" threshold = 15 action = "reject sender ip %IP% is blocked (score=%SCORE%%SCORE_DETAIL%)" </Plugin> <Plugin ScoreTag> module = "AddScoreHeader" spam_score=5 </Plugin>
With mtpolicyd 2.x configuration of connections and session cache has been changed.
In mtpolicyd 2.00 the connections defined globaly in the configuration file have been replaced by a dynamic connection pool.
The global options db_* ldap_* and memcached_* have been removed.
Instead connections are registered within a connection pool.
You can define them using <Connection> blocks:
<Connection myconn> module = "<adapter>" # parameter = "value" # ... </Connection>
In mtpolicyd 1.x:
db_dsn=DBI:mysql:mtpolicyd db_user=mtpolicyd db_password=secret
In mtpolicyd 2.x:
<Connection db> dsn = "DBI:mysql:mtpolicyd" user = "mtpolicyd" password = "secret" </Connection>
All SQL modules will by default use the connection registered as "db".
See modules in Mail::MtPolicyd::Connection::* for available connection adapters.
Starting with mtpolicyd 2.x it is possible to use other session caches then memcached.
The global session_* parameters have been removed.
Instead the session cache is defined by a <SessionCache> block:
<SessionCache> module = "<module>" # parameter = "value" # ... </SessionCache>
A memcached session cache in mtpolicyd v1.x:
memcached_servers="127.0.0.1:11211" session_lock_wait=50 session_lock_max_retry=50 session_lock_timeout=10
In mtpolicyd 2.x:
<Connection memcached> servers = "127.0.0.1:11211" </Connection> <SessionCache> module = "Memcached" # defaults to connection "memcached" # memcached = "memcached" lock_wait = "50" lock_max_retry = "50" lock_timeout = "10" </SessionCache>
If no <SessionCache> is defined it will default to the dummy session cache module "None".
See modules in Mail::MtPolicyd::SessionCache::* for available session cache modules.
This module forwards the request to another policy daemon.
The <host>:<port> of the target policy daemon.
The path to the socket of the target policy daemon.
Keep connection open across requests.
<Plugin ask-postgrey> module = "Proxy" host="localhost:10023" </Plugin>
This plugin executes a list of configured plugins but will not return the action back to mtpolicyd. Instead it writes the output of the plugins to a variable within the session.
The name of the key in the session to store the result of the eval'ed checks.
A list of checks to execute.
<Plugin eval-spf> module = "Eval" # store result in spf_action store_in="spf_action" <Plugin proxy-spf> module = "Proxy" host = "localhost:10023" </Plugin> </Plugin>
This plugin could be used to reset some session variables.
A comma separated list of session variables to unset.
A comma separated list of prefixes. All session variables with this prefixes will be unset.
<Plugin cleanup> module = "ClearFields" fields = "spamhaus-rbl,spamhaus-dbl" </Plugin>
Will remove both fields from the session.
<Plugin cleanup> module = "ClearFields" fields_prefix = "spamhaus-" </Plugin>
Will also remove both fields and everything else starting with "spamhaus-" from the session.
Will check the sender, helo and reverse_client_name against an domain black list.
The domain of the blacklist to query.
Set to 'off' to disable plugin.
Possible values: on,off
If specified the give variable within the session will overwrite the value of 'enabled' if set.
Should the plugin return an reject if the check matches (reject) or just add an score (passive).
Possible values: reject, passive
Add the given score if check matched.
Name of the session variable the score is stored in. Could be used if multiple scores are needed.
Only the sender and the reverse_client_name check will cause an action to be executed (mode). The helo check will only add an score.
<Plugin sh_dbl> module = "RBL" #enabled = "on" uc_enabled = "spamhaus" domain="dbl.spamhaus.org" # do not reject based on helo #helo_name_mode=passive #helo_name_score=1 #sender_mode=reject #sender_score=5 #reverse_client_name_mode=reject #reverse_client_name_score=2.5 </Plugin>
Returns a action based on the score.
If the score is higher than this value the action will be executed.
If it should match if the score if >= or <= the threshold.
Possible values: gt, lt
If set the value for threshold will be fetched from this user-config value if defined.
Specifies the name of the field the score is stored in. Could be set if you need multiple scores.
The action to be executed.
The following patterns in the string will be replaced:
%IP%, %SCORE%, %SCORE_DETAIL%
Execute this plugins when the condition matched.
Reject everything with a score >= 15. and do greylisting for the remaining request with a score >=5.
<Plugin ScoreReject> module = "ScoreAction" threshold = 15 action = "reject sender ip %IP% is blocked (score=%SCORE%%SCORE_DETAIL%)" </Plugin> <Plugin ScoreGreylist> module = "ScoreAction" threshold = 5 <Plugin greylist> module = "Greylist" score = -5 mode = "passive" </Plugin> </Plugin>
This plugin just returns the specified string as action.
<Plugin reject-all> module = "action" # any postfix action will do action=reject no reason </Plugin>
This plugin will execute an action or score based on a previous lookup done with SaAwlLookup plugin.
Take the AWL information from the result of this plugin.
The plugin in must be executed before this plugin.
Enable/disable this plugin.
If set to 'passive' no action will be returned.
Could be used to specify an custom reject message.
A score to apply to the message.
A factor to apply the SA score to the message.
Do not configure a score if you want to use the factor.
The minimum count of mails/scores spamassassin must have done on this sender/ip before the AWL entry is used.
If the count in AWLs auto-whitelist table is below this count the test will be skipped.
At this threshold the action or score will be applied.
The default is to match values greater("gt") than the threshold.
When configured with 'lt' AWL scores less than the threshold will be matched.
Check that AWL is active in your SA/amavis configuration:
loadplugin Mail::SpamAssassin::Plugin::AWL use_auto_whitelist 1
Make sure that mtpolicyd has permissions to read the auto-whitelist db:
$ usermod -G amavis mtpolicyd $ chmod g+rx /var/lib/amavis/.spamassassin $ chmod g+r /var/lib/amavis/.spamassassin/auto-whitelist
Make sure it stays like this when its recreated in your SA local.cf:
auto_whitelist_file_mode 0770
Net::Server does not automatically set supplementary groups. You have to do that in mtpolicyd.conf:
group="mtpolicyd amavis"
Permissions may be different on your system.
To check that mtpolicyd can access the file try:
$ sudo -u mtpolicyd -- head -n0 /var/lib/amavis/.spamassassin/auto-whitelist
Now use it in mtpolicyd.conf:
<Plugin amavis-reputation> module = "SaAwlLookup" db_file = "/var/lib/amavis/.spamassassin/auto-whitelist" </Plugin>
For whitelisting you may configure it like:
<Plugin awl-whitelist> module = "SaAwlAction" result_from = "amavis-reputation" mode = "accept" match = "lt" threshold = "0" </Plugin>
Or apply a score based for bad AWL reputation (score > 5):
<Plugin awl-score-bad> module = "SaAwlAction" result_from = "amavis-reputation" mode = "passive" match = "gt" threshold = 6 score = 5 </Plugin>
Or apply the score value from AWL with an factor:
<Plugin awl-score-bad> module = "SaAwlAction" result_from = "amavis-reputation" mode = "passive" match = "gt" threshold = 5 score_factor = 0.5 </Plugin>
If the score in AWL is >5 it will apply the score with an factor of 0.5. When the score in AWL is 8 it will apply a score of 4.
Or just reject all mail with a bad reputation:
<Plugin awl-reject> module = "SaAwlAction" result_from = "amavis-reputation" mode = "reject" match = "gt" threshold = 5 reject_message = "bye bye..." </Plugin>
To check the content of the auto-whitelist database use the sa-awl command:
$ sa-awl /var/lib/amavis/.spamassassin/auto-whitelist | grep <user>
http://spamassassin.apache.org/full/3.1.x/doc/Mail_SpamAssassin_Plugin_AWL.html
This plugin queries a GeoIP for the country code of the client_address. The plugin is divided in this plugin which does the Lookup and the GeoIPAction plugin which can be used to take actions based on country code.
On a debian system you can install the country database with the geoip-database package.
You also download it directly from Maxmind:
http://dev.maxmind.com/geoip/geoip2/geolite2/
(choose "GeoLite2 Country/DB")
<Plugin whitelist> module="PostfixMap" db_file="/etc/postfix/whitelist.db" match_action=dunno </Plugin> <Plugin blacklist> moduel="PostfixMap" db_file="/etc/postfix/blacklist.db" match_action="reject you are blacklisted!" </Plugin>
Plugin checks the client_address against a postfix hash table.
It will only check if the IP address matches the list. 'OK' or a numerical value will be interpreted as a 'true' value. All other actions or values will be treaded as 'false'.
/etc/postfix/whitelist:
123.123.123.123 OK 123.123.122 OK 123.12 OK fe80::250:56ff:fe85:56f5 OK fe80::250:56ff:fe83 OK
generate whitelist.db:
$ postmap whitelist
The module takes the following parameters:
Could be set to 'off' to deactivate check. Could be used to activate/deactivate check per user.
By default the plugin will do nothing. One of the following actions should be specified:
The Honeypot plugin creates an honeypot to trap IPs sending to unused recipient addresses.
The plugin requires that you define unused recipient addresses as honeypots. These addresses can be specified by the recipients and recipients_re parameters.
Each time an IP tries to send an mail to one of these honeypots the message will be reject if mode is 'reject' and an scoring is applied. The IP is also added to a temporary IP blacklist till an timeout is reached (parameter expire). All IPs on this blacklist will also be rejected if mode is 'reject' and scoring is applied.
<Plugin honeypot> module = "Honeypot" recipients = "bob@company.com,joe@company.com" recipients_re = "^(tic|tric|trac)@(gmail|googlemail)\.de$" </Plugin>
Enable/disable this check.
Apply an score to this message if it is send to an honeypot address or it has been added to the honeypot before by sending an mail to an honeypot.
The default is to return an reject.
Change to 'passive' if you just want scoring.
A comma separated list of recipients to use as honeypots.
A comma separated list of regular expression to match against the recipient to use them as honeypots.
A string to return with the reject action.
Time in seconds till the client_ip is removed from the honeypot.
Execute this plugins when the condition matched.
Will return an action, score or execute further plugins if the specified condition matched.
The name of the variable to check.
Syntax is
(<scope>:)?<variable-name>
If no scope is give it defaults to request.
Possible scopes are:
Examples:
session:user_policy s:user_policy request:queue_id r:queue_id queue_id
At least one of the following parameters should be given or your condition will never match:
Simple string equal match.
Match content of the session variable against an regex.
Match if numerical less than.
Match if numerical greater than.
If set to 1 the logic will be inverted.
Finally an action must be specified.
First the score will be applied then the action will be executed or if specified additional plugins will be executed.
The action to return when the condition matched.
The score to add if the condition matched.
Execute this plugins when the condition matched.
The policy_context of postfix could be used to trigger checks in mtpolicyd.
To activate additional checks in mtpolicyd from within postfix use may use a configuration in postfix main.cf like:
# check, no additional checks check_policy_service inet:localhost:12345 ... # check with additional checks! check_policy_service { inet:localhost:12345, policy_context=strict_checks }
In mtpolicyd.conf:
<Plugin if-strict-checks> module = "Condition" key = "policy_context" match = "strict_checks" <Plugin strict-check> # ... </Plugin> # more checks ... </Plugin>
The policy_context feature will be available in postfix 3.1 and later.
If you need completely different checks consider using the vhost_by_policy_context (mtpolicyd) option with different virtual hosts.
If the session variable "greylisting" is "on" return the postfix action "postgrey":
<Plugin trigger-greylisting> module = "Condition" key = "greylisting" match = "on" action = "postgrey" </Plugin>
The variable may be set by a UserConfig module like SqlUserConfig.
The postgrey action in postfix may look like:
smtpd_restriction_classes = postgrey postgrey = check_policy_service inet:127.0.0.1:11023
This plugin applies Sender Policy Framework(SPF) checks.
Checks are implemented using the Mail::SPF perl module.
Actions based on the SPF result can be applied for:
For status 'neutral' no action or score is applied.
Enable/disable the plugin.
How to behave if the SPF checks passed successfully:
Score to apply when the sender has been successfully checked against SPF.
How to behave if the SPF checks returned a softfail status.
Score to apply when the SPF check returns an softfail status.
Action to apply on a temperror SPF result.
Possible values: passive, dunno, defer, reject
Score to apply on a temperror SPF result.
By default no score is applied.
Action to apply on a permerror SPF result.
Possible values: passive, dunno, defer, reject
Score to apply on a permerror SPF result.
By default no score is applied.
If fail_mode is set to 'reject' this message is used in the reject.
The following pattern will be replaced in the string:
Score to apply if the sender failed the SPF checks.
String to return as an URL pointing to an explanation of the SPF check result.
See Mail::SPF::Server for details.
An hostname to show in the default_authority_explanation as generating server.
A comma separated list of IP addresses to skip.
Set to 'off' to disable SPF check on helo.
Maximum number of terms using DNS lookup in a SPF record to evaluate.
Exceeding this limit will cause a permanent error as specified by RFC7208.
The default of 10 is also specified in by RFC7208.
Maximum number of DNS lookups per SPF term.
Maximum number of void DNS lookups.
<Plugin spf> module = "SPF" pass_mode = passive pass_score = -10 fail_mode = reject #fail_score = 10 </Plugin>
Mail::SPF, OpenSPF www.openspf.org/, RFC 7208 https://tools.ietf.org/html/rfc7208
This plugin can be used to set key/values within the session.
<Plugin set-scanned> module = "SetField" key=mail-is-scanned value=1 </Plugin>
This plugin can be used to block an ip with iptable thru the fail2ban daemon.
For more information abount fail2ban read:
This plugin will directly talk to the daemon thru the unix domain socket and execute an banip command:
set <JAIL> banip <IP>
Path to the fail2ban unix socket.
Make sure mtpolicyd is allowed to write to this socket!
The jail in which the ip should be banned.
Execute a ban on all client-ips which send a mail with a score of >=15:
<Plugin ScoreBan> module = "ScoreAction" threshold = 15 <Plugin ban-ip> module = "Fail2Ban" socket = "/var/run/fail2ban/fail2ban.sock" jail = "postfix" </Plugin> </Plugin>
To allow mtpolicyd to access fail2ban you must make sure fail2ban can write to the fail2ban unix socket.
chgrp mtpolicyd /var/run/fail2ban/fail2ban.sock chmod g+rwx /var/run/fail2ban/fail2ban.sock
You may want to add this to the fail2ban startup script.
You may want to use the predefined postfix jail. To activate it create /etc/fail2ban/jail.local and enable the postfix fail by setting enabled=true.
[postfix] enabled = true
This plugin can be used to do remote SMTP verification of addresses.
To check if the recipient exists on a internal relay and mailbox is able to receive a message of this size:
<Plugin smtp-rcpt-check> module = "SMTPVerify" host = "mail.company.internal" sender_field = "sender" recipient_field = "recipient" # send SIZE to check quota size_field = "size" temp_fail_action = "defer %MSG%" perm_fail_action = "reject %MSG%" </Plugin>
Do some very strict checks on sender address:
<Plugin sender-sender-check> module = "SMTPVerify" # use a verifiable address in MAIL FROM: sender = "horst@mydomain.tld" recipient_field = "sender" no_starttls_action = "reject sender address does not support STARTTLS" temp_fail_action = "defer sender address failed verification: %MSG%" perm_fail_action = "reject sender address does not accept mail: %MSG%" </Plugin>
Or do advanced checking of sender address and apply a score:
<Plugin sender-sender-check> module = "SMTPVerify" # use a verifiable address in MAIL FROM: sender = "horst@mydomain.tld" recipient_field = "sender" check_tlsa = "on" check_openpgp = "on" temp_fail_score = "1" perm_fail_score = "3" has_starttls_score = "-1" no_starttls_score = "5" has_tlsa_score = "-3" has_openpgp_score = "-3" </Plugin>
Based on the score you can later apply greylisting or other actions.
The module takes the following parameters:
Enable/disable this check.
If defined this host will be used for checks instead of a MX.
Port to use for connection.
Set to 'on' to enable check if an TLSA record for the MX exists.
This requires that your DNS resolver returns the AD flag for DNSSEC secured records.
Set to 'on' to enable check if an OPENPGPKEY records for the recipients exists.
Field to take the MAIL FROM address from.
If set use this fixed sender in MAIL FROM instead of sender_field.
Field to take the RCPT TO address from.
Field to take the message SIZE from.
Action to return if the remote server returned an permanent error for this recipient.
The string "%MSG%" will be replaced by the smtp message:
perm_fail_action = "reject %MSG%"
Like perm_fail_action but this message is returned when an temporary error is returned by the remote smtp server.
temp_fail_action = "defer %MSG%"
Score to apply when a permanent error is returned for this recipient.
Score to apply when a temporary error is returned for this recipient.
Score to apply when the smtp server of the recipient announces support for STARTTLS extension.
Score to apply when there is a TLSA or no TLSA record for the remote SMTP server.
Score to apply when a OPENPGPKEY record for the recipient exists or not exists.
This plugin queries a DNS black/white list.
The domain of the blacklist to query.
Enable/disable this check.
A pattern for the reject message if mode is set to 'reject'.
Apply this score if the check matched.
<Plugin sorbs.net> module = "RBL" mode = "passive" domain="dnsbl.sorbs.net" score = 5 </Plugin>
<Plugin dnswl.org> module = "RBL" mode = "accept" # will stop here domain="list.dnswl.org" </Plugin>
This plugin can be used to do accounting based on request fields.
<Plugin quota-clients> module = "Quota" table_prefix = "acct_" # per month time_pattern = "%Y-%m" # per ip field = "client_address" # allow 1000 mails metric = "count" threshold = 1000 action = "defer you exceeded your monthly limit, please insert coin" </Plugin>
The module takes the following parameters:
Enable/disable this check.
The field used for accounting/quota.
The metric on which the quota should be based.
The Accounting module stores the following metrics:
A format string for building the time key used to store counters.
Default is to build counters on a monthly base.
For example use:
* "%Y-%W" for weekly * "%Y-%m-%d" for daily
See "man date" for format string sequences.
You must use the same time_pattern as used in for the Accounting module.
The quota limit.
The action to return when the quota limit has been reached.
A prefix to add to every table.
The table name will be the prefix + field_name.
<Plugin regex-whitelist> module = "RegexList" key = "request:client_name" regex = "^mail-[a-z][a-z]0-f[0-9]*\.google\.com$" regex = "\.bofh-noc\.de$" # file = "/etc/mtpolicyd/regex-whitelist.txt" action = "accept" </Plugin>
This plugin matches a value against a list of regular expressions and executes an action if it matched.
The module takes the following parameters:
Could be set to 'off' to deactivate check. Could be used to activate/deactivate check per user.
Field to query.
If set to 1 the logic will be inverted.
One or more regular expressions
A file to load regular expressions from.
One regex per line. Empty lines and lines starting with # will be ignored.
By default the plugin will do nothing. One of the following actions should be specified:
This plugin could be used to retrieve session variables/user configuration from a LDAP server.
ldap_host="localhost" ldap_binddn="cn=readonly,dc=domain,dc=com" ldap_password="secret" <Plugin user_config> module="LdapUserConfig" basedn="ou=users,dc=domain,dc=com" filter="(mail=%s)" filter_field="sasl_username" config_fields="mailMessageLimit,mailSendExternal" </Plugin>
The LDAP connection must be configured in the global configuration section of mtpolicyd. See mtpolicyd.
The basedn to use for the search.
The filter to use for the search.
The pattern %s will be replaced with the content of filter_field.
The content of this request field will be used to replace %s in the filter string.
A comma separated list of LDAP attributes to retrieve and copy into the current mtpolicyd session.
This plugin implements a greylisting mechanism with an auto whitelist.
If a client connects it will return an defer and create a greylisting "ticket" for the combination of the address of the sender, the senders address and the recipient address. The ticket will be stored in memcached and will contain the time when the client was seen for the first time. The ticket will expire after the max_retry_wait timeout.
The client will be deferred until the min_retry_wait timeout has been reached. Only in the time between the min_retry_wait and max_retry_wait the request will pass the greylisting test.
When the auto-whitelist is enabled (default) a record for every client which passes the greylisting test will be stored in the autowl_table. The table is based on the combination of the sender domain and client_address. If a client passed the test at least autowl_threshold (default 3) times the greylisting test will be skipped. Additional an last_seen time stamp is stored in the record and records which are older then the autowl_expire_days will expire.
Please note the greylisting is done on a triplet based on the
client_address + sender + recipient
The auto-white list is based on the
client_address + sender_domain
Enable/disable this check.
Apply an score to this message if it _passed_ the greylisting test. In most cases you want to assign a negative score. (eg. -10)
The default is to return no action if the client passed the greylisting test and continue.
You can set this 'accept' or 'dunno' if you want skip further checks.
This action is returned to the MTA if a message is deferred.
If a client retries too fast the time left till min_retry_wait is reach will be appended to the string.
A client will have to wait at least for this timeout. (in seconds)
A client must retry to deliver the message before this timeout. (in seconds)
Could be used to disable the use of the auto-whitelist.
How often a client/sender_domain pair must pass the check before it is whitelisted.
After how many days an auto-whitelist entry will expire if no client with this client/sender pair is seen.
The name of the table to use.
The database handle specified in the global configuration will be used. (see man mtpolicyd)
This options could be used to disable the creation of a new ticket or to query the autowl.
This can be used to catch early retries at the begin of your configuration before more expensive checks are processed.
Example:
<Plugin greylist> module = "Greylist" score = -5 mode = "passive" create_ticket = 0 query_autowl = 0 </Plugin> # ... a lot of RBL checks, etc... <Plugin ScoreGreylist> module = "ScoreAction" threshold = 5 <Plugin greylist> module = "Greylist" score = -5 mode = "passive" </Plugin> </Plugin>
This will prevent early retries from running thru all checks.
Adds an header with the current score and score details to the mail.
If the score is higher than this value it'll be tagged as 'YES'. Otherwise 'NO'.
Specifies the name of the field the score is stored in. Could be set if you need multiple scores.
The name of the header to set.
<Plugin add-score-header> module = "AddScoreHeader" # score_field = "score" # header_name = "X-MtScore" spam_score = 5 </Plugin>
Will return an action like:
X-MtScore: YES score=7.5 [CTIPREP_TEMP=2.5, spamhaus-rbl=5]
This plugin can be used to do accounting based on request fields.
<Plugin acct-clients> module = "Accounting" # per ip and user fields = "client_address,sasl_username" # statistics per month time_pattern = "%Y-%m" table_prefix = "acct_" </Plugin>
This will create a table acct_client_address and a table acct_sasl_username.
If a request is received containing the field the plugin will update the row in the fields table. The key is the fields value(ip or username) and the time string build from the time_pattern.
For each key the following counters are stored:
* count * count_rcpt (count per recipient) * size * size_rcpt (size * recipients)
The resulting tables will look like:
mysql> select * from acct_client_address; +----+--------------+---------+-------+------------+--------+-----------+ | id | key | time | count | count_rcpt | size | size_rcpt | +----+--------------+---------+-------+------------+--------+-----------+ | 1 | 192.168.0.1 | 2014-12 | 11 | 11 | 147081 | 147081 | | 2 | 192.168.1.1 | 2014-12 | 1 | 1 | 13371 | 13371 | | 12 | 192.168.2.1 | 2014-12 | 10 | 100 | 133710 | 1337100 | ...
The module takes the following parameters:
Enable/disable this check.
A comma separated list of fields used for accounting.
For each field a table will be created.
For a list of available fields see postfix documentation:
A format string for building the time key used to store counters.
Default is to build counters on a monthly base.
For example use:
* "%Y-%W" for weekly * "%Y-%m-%d" for daily
See "man date" for format string sequences.
A prefix to add to every table.
The table name will be the prefix + field_name.
This plugin will retrieve a JSON string from an SQL database and will merge the data structure into the current session.
This could be used to retrieve configuration values for users from a database.
The SQL query to retrieve the JSON configuration string.
The content of the first row/column is used.
The request field used in the sql query to retrieve the user configuration.
Create the following table in the SQL database:
CREATE TABLE `user_config` ( `id` int(11) NOT NULL AUTO_INCREMENT, `address` varchar(255) DEFAULT NULL, `config` TEXT NOT NULL, PRIMARY KEY (`id`), UNIQUE KEY `address` (`address`) ) ENGINE=MyISAM DEFAULT CHARSET=latin1 INSERT INTO TABLE `user_config` VALUES( NULL, 'karlson@vomdach.de', '{"greylisting":"on"}' );
In mtpolicyd.conf:
db_dsn="dbi:mysql:mail" db_user=mail db_password=password <Plugin user-config> module = "SqlUserConfig" sql_query = "SELECT config FROM user_config WHERE address=?" </Plugin> <Plugin greylist> enabled = "off" # off by default uc_enabled = "greylisting" # override with value of key 'greylisting' is set in session module = "Greylist" score = -5 mode = "passive" </Plugin>
This plugin queries the auto_whitelist database used by spamassassins AWL plugin for the reputation of sender ip/address combination.
Based on the AWL score a score or action in mtpolicyd can be applied in combination with the SaAwlAction plugin.
The path to the auto-whitelist database file.
To read reputation from amavis/spamassassin AWL use:
<Plugin amavis-awl> module = "SaAwlLookup" db_file = "/var/lib/amamvis/.spamassassin/auto-whitelist" </Plugin>
The location of auto-whitelist may be different on your system. Make sure mtpolicyd is allowed to read the db_file.
This plugin will execute an action or score based on a previous lookup done with GeoIPLookup plugin.
Take the GeoIP information from the result of this plugin.
The plugin in must be executed before this plugin.
Enable/disable this plugin.
A comma separated list of 2 letter country codes to match.
If set to 'passive' no action will be returned.
Could be used to specify an custom reject message.
A score to apply to the message.
<Plugin whitelist> module="SqlList" sql_query="SELECT client_ip FROM whitelist WHERE client_ip=?" match_action=dunno </Plugin> <Plugin blacklist> module="SqlList" sql_query="SELECT client_ip FROM blacklist WHERE client_ip=?" match_action="reject you are blacklisted!" </Plugin>
Plugin checks a field against a SQL table/query.
Depending on whether a supplied SQL query matched actions can be taken.
The module takes the following parameters:
Could be set to 'off' to deactivate check. Could be used to activate/deactivate check per user.
Prepared SQL statement to use for checking an IP address.
? will be replaced by the IP address.
The module will match if the statement returns one or more rows.
By default the plugin will do nothing. One of the following actions should be specified:
If given this action will be returned to the MTA if the SQL query matched.
If given this action will be returned to the MTA if the SQL query DID NOT matched.
If given this score will be applied to the session.
The field the query parameter will be taken from.
You may use the following table for storing IPv4 addresses in MySQL:
CREATE TABLE `whitelist` ( `id` int(11) NOT NULL AUTO_INCREMENT, `client_ip` INT UNSIGNED NOT NULL, PRIMARY KEY (`id`), UNIQUE KEY `client_ip` (`client_ip`) ) ENGINE=MyISAM DEFAULT CHARSET=latin1 INSERT INTO whitelist VALUES(NULL, INET_ATON('127.0.0.1'));
And use it as a whitelist in mtpolicyd:
<VirtualHost 12345> name="reputation" <Plugin whitelist> module="SqlList" sql_query="SELECT client_ip FROM whitelist WHERE client_ip=INET_ATON(?)" match_action="dunno" </Plugin> <Plugin trigger-greylisting> ... </VirtualHost>
This plugin can be used when a more complex evaluation of an RBL result is needed that just match/not-match.
With this plugin you can take the same actions as with the RBL plugin, but it can match the result with a regular expression. This allows one to take action based on the category in combined blacklists.
Use the query result of this RBL check.
Enable/disable this check.
An regular expression to check the RBL result.
A pattern for the reject message if mode is set to 'reject'.
Apply this score if the check matched.
<Plugin spamhaus-rbl> module = "RBL" mode = "passive" domain="zen.spamhaus.org" </Plugin> <Plugin spamhaus-rbl-sbl> module = "RBLAction" result_from = "spamhaus-rbl" mode = "passive" re_match = "^127\.0\.0\.[23]$" score = 5 </Plugin> <Plugin spamhaus-rbl-xbl> module = "RBLAction" result_from = "spamhaus-rbl" mode = "passive" re_match = "^127\.0\.0\.[4-7]$" score = 5 </Plugin> <Plugin spamhaus-rbl-pbl> module = "RBLAction" result_from = "spamhaus-rbl" mode = "passive" re_match = "^127\.0\.0\.1[01]$" score = 3 </Plugin>
This plugin will query the Commtouch IP Reputation service (ctipd).
The used protocol is HTTP.
The services will return a status permfail or tempfail.
Enable/disable the plugin.
The URL to access the ctipd daemon.
If an authentication key is required by the ctipd.
This parameter could be used to specify a custom reject message if message is rejected.
This parameter could be used to specify a custom message is a message is to be deferred.
Action to take when the service return permfail/tempfail status:
Apply the specified score.
Will return an action or execute further plugins if postfix signals stress.
See postfix STRESS_README.
An action must be specified:
The action to return when under stress.
Execute this plugins when under stress.
To defer clients under stress:
<Plugin stress> module = "Stress" action = "defer please try again later" </Plugin>
This will return an defer action and execute no further tests.
You may want to do some white listing for preferred clients before this action.