The dp_config.lua and custom_policy.lua Files
Last updated March 2020
This appendix reproduces the files referenced in the title.
Default policy is configured using the dp_config.lua
file. A sample configuration file is found in the /opt/msys/ecelerity/etc/sample-configs
directory and is reproduced below.
module("msys.dp_config", package.seeall); require("custom_policy"); --[[ Whitelist support. If enabled, each default policy may optionally honor one or more whitelists, such that an IP address that is whitelisted will not be subjected to the policy in question. Two types are supported, either from a datasource (such as a database or LDAP) or an RBLDNSD file. The following common parameters are required: type: either "datasource" or "rbldnsd" name: name of the whitelist refresh: an integer greater than or equal to 0 default_value: Must always be "" Syntax for "datasource": cachename: The name of a Datasource defined in ecelerity.conf query: A query understood by the Datasource, which returns all CIDR blocks to whitelist, one row at a time. Two columns must be returned, a value (which can be anything, even a static value) and the CIDR block. cidr_column: The name of the column containing the CIDR block value_column: The name of the column containing the value (the value is ignored for the purposes of the whitelist but something must be there) Syntax for "rbldnsd" source: Path to the rbldnsd source file on disk record_type: Either "A" or "TXT" ]] --[[ Custom Whitelist: Note that you can define custom policies to create your own whitelists (for example based on something other than connecting IP, like envelope parameters). You may then use the Default Policy whitelist honor mechanism by setting the whitelist as follows: msys.pbp.set_whitelist(vctx, "my_whitelist_name", true); Then you may put "my_whitelist_name" as one of the "honor_whitelist" table entries if you wish a specific policy honor that whitelist. ]] --[[ msys.dp_config.whitelist = { { name = "global", type = "rbldnsd", refresh = 1800, source = "/opt/msys/ecelerity/etc/whitelist.txt", record_type = "TXT", default_value = "", }, { name = "global_datasource", type = "datasource", refresh = 1800, cachename = "sqlite", query = "SELECT 1 as val, cidr FROM whitelist", cidr_column = "cidr", value_column = "val", default_value = "", } }; ]] --[[ Supports both DNS and RBLDNSD RBLs. name: The name of the RBL, must be unique type: either 'dns' or 'rbldnsd' code: Numeric SMTP response code to use for an RBL hit reason: SMTP string to use for an RBL hit, %s is the RBL message Syntax for 'dns' base: Base domain to lookup server: Optional, the IP address of the DNS server to use, by default we will use the servers defined in resolv.conf Syntax for 'rbldnsd': source: Path to the rbldnsd source file on disk refresh: How often to reload the rbldnsd file ]] --[[ For all of the RBLs, you may define a 'process_result' function to override all processing of the result. The function is defined like so: msys.dp_config.rbls = { { ... ... process_result = function (ac, vctx, info) return vctx:pbp_disconnect(554, "RBL hit: " .. info); end, }, }; The function is passed three parameters: ac: The accept construct vctx: The validation context info: The result returned by the RBL. Will be the first A or TXT record returned based on how the RBL was configured. Returns either msys.core.VALIDATE_CONT to continue or msys.core.VALIDATE_DONE to terminate processing of this phase. ]] msys.dp_config.rbls = { --[[ { check = true, name = "myrbl", type = "dns", base = "rbl.myrbl.org", record_type = "TXT", code = 554, reason = "RBL hit on myrbl: %s", honor_whitelist = { "global" }, }, { check = true, name = "myrbl2", type = "rbldnsd", source = "/opt/msys/ecelerity/etc/myrbldnsd.txt", refresh = 1800, record_type = "A", code = 451, reason = "RBL hit on myrbl2: %s", honor_whitelist = { "global" }, } ]] }; -- Early talker detection, requires the 'conntrol' module to be loaded -- in the ecelerity.conf file msys.dp_config.early_talker = { check = true, honor_whitelist = { "global" }, }; -- FCDNS checking msys.dp_config.fcdns = { check = true, rdns_failure_code = 554, fdns_failure_code = 554, honor_whitelist = { "global" }, }; -- Concurrent connection limiting msys.dp_config.concurrent_connection_limits = { { check = true, mask = "/32", limit = 10, service = "SMTP", honor_whitelist = { "global" }, }, { check = true, mask = "/24", limit = 100, service = "SMTP", honor_whitelist = { "global" }, }, -- System-wide connection limit, don't honor the whitelists here { check = true, mask = "/0", limit = 20000, service = "SMTP", } }; msys.dp_config.audit_series = {}; --[[ Failed SMTP AUTH limiting. This essentially the same as DHA prevention for invalid recipient handling, except it is applied to failed AUTH LOGIN requests type: cidr interval: Bucket size in seconds buckets: Number of intervals key: /mask length for the threshold (leading slash required) startv: Starting bucket (0 is the current bucket) endv: Ending bucket threshold: Count over which we do not allow any more SMTP AUTH commands NOTE: Disabled for the moment ]] --[[ msys.dp_config.audit_series.invalid_smtp_auth = { type = "cidr", interval = 900, buckets = 4, thresholds = { { check = true, key = "/32", startv = 0, endv = 3, threshold = 100, honor_whitelist = { "global" } }, { check = true, key = "/24", startv = 0, endv = 3, threshold = 1000, honor_whitelist = { "global" } } }, options = { persist = true } }; ]] --[[ Connection rate limiting type: cidr interval: Bucket size in seconds buckets: Number of intervals key: /mask length for the threshold (leading slash required) startv: Starting bucket (0 is the current bucket) endv: Ending bucket threshold: Count over which rejection happens honor_whitelist: List of whitelists to honor ]] msys.dp_config.audit_series.connections = { type = "cidr", interval = 900, buckets = 4, thresholds = { { check = true, key = "/32", startv = 0, endv = 3, threshold = 100, honor_whitelist = { "global" } }, { check = true, key = "/24", startv = 0, endv = 3, threshold = 1000, honor_whitelist = { "global" } } }, options = { persist = true } }; --[[ MAIL FROM rate limiting Note this is disabled by default as there is a potential for a sender to DoS the system with garbage sender addresses. type: string interval: Bucket size in seconds buckets: Number of intervals startv: Starting bucket (0 is the current bucket) endv: Ending bucket threshold: Count over which rejection happens honor_whitelist: List of whitelists to honor ]] --[[ msys.dp_config.audit_series.mailfrom = { type = "string", interval = 900, buckets = 4, thresholds = { { check = true, startv = 0, endv = 3, threshold = 100, honor_whitelist = { "global" } } }, options = { persist = true } }; ]] --[[ SMTP AUTH user rate limiting this check is never evaluated if the sender is not authenticated with SMTP authentication type: string interval: Bucket size in seconds buckets: Number of intervals startv: Starting bucket (0 is the current bucket) endv: Ending bucket threshold: Count over which rejection happens honor_whitelist: List of whitelists to honor ]] msys.dp_config.audit_series.auth_user = { type = "string", interval = 900, buckets = 4, thresholds = { { check = true, startv = 0, endv = 3, threshold = 100, honor_whitelist = { "global" } } }, options = { persist = true } }; -- MAIL FROM domain validation msys.dp_config.mail_from_domain_validate = { check = true, failure_code = 554, honor_whitelist = { "global" } }; --[[ Recipient Validation Assumes a datasource has been setup in the ecelerity.conf file whose name is provided below. Use this policy if you wish to perform per-recipient or per-domain recipient validation. If this policy is enabled, any Relay_Domains defined in ecelerity.conf will mean that any recipient in such domains will be allowed without any query against the defined datasource. If you wish to perform per- recipient validation then do _not_ define the domains in question in the ecelerity.conf Relay_Domains configuration setting. This policy is designed to be used on 'inbound' systems, and may be disabled if the system is an 'outbound' system (in this case relay checking should be enabled) ]] msys.dp_config.recipient_validation = { -- Whether or not to perform recipient validation -- Disabled by default, enable if you want to define a recipient validation -- policy check = true, -- Name of the datasource. If you only want to honor Relay_Domains from -- ecelerity.conf then you should not define either ds_name or query. -- ds_name = "ldap", -- Query, $rcpt is the placeholder for the recipient's email address, -- depending on the datasource it may also be ':rcpt'. If you only -- want to check the domain, use $domain or :domain -- query = "ldap:///DC=domain,DC=com?mail,status?sub?mail=$rcpt", -- Attribute to compare for mailbox status (suspended, active, etc). -- Must be queried in the provided URI. To not perform a status attribute -- check comment out the following line. -- status_attribute = "status", -- Acceptable status values, all other status values will be rejected. -- May include Lua-compatible patterns as well as static strings. -- status_values = { "active", "online", "other" }, -- Enable DHA prevention dha_prevention = true, }; --[[ Relay Authorization For 'outbound' systems, relay checking is generally done based on either the source IP address (on-net IP addresses) or based on the SMTP authentication result. ]] msys.dp_config.relay_authorization = { check = false, --[[ Onnet IP addresses. If this option is defined, the source IP address will be checked against the configured datasource, and if it matches will be allowed to relay messages. Two types are supported, either from a datasource (such as a database or LDAP) or an RBLDNSD file. The following common parameters are required: type: either "datasource" or "rbldnsd" refresh: an integer greater than or equal to 0 default_value: Must always be "" Syntax for "datasource": cachename: The name of a Datasource defined in ecelerity.conf query: A query understood by the Datasource, which returns all CIDR blocks to whitelist, one row at a time. Two columns must be returned, a value (which can be anything, even a static value) and the CIDR block. cidr_column: The name of the column containing the CIDR block value_column: The name of the column containing the value (the value is ignored for the purposes of the whitelist but something must be there) Syntax for "rbldnsd" source: Path to the rbldnsd source file on disk record_type: Either "A" or "TXT" ]] --[[ onnet = { type = "rbldnsd", refresh = 1800, source = "/opt/msys/ecelerity/etc/onnet.txt", record_type = "TXT", default_value = "", }; ]] --[[ onnet = { type = "datasource", refresh = 1800, cachename = "sqlite", query = "SELECT 1 as val, cidr FROM onnet", cidr_column = "cidr", value_column = "val", default_value = "", }; ]] -- Allow SMTP-authenticated users to relay -- Note that you still must configure SMTP authentication in ecelerity.conf -- using the auth_ds module and the appropriate ESMTP_Listener options. allow_smtp_auth = true }; --[[ DHA parameters, to disable comment out invalid recipients audit_series type: cidr interval: Bucket size in seconds buckets: Number of intervals key: /mask length for the threshold (leading slash required) startv: Starting bucket (0 is the current bucket) endv: Ending bucket threshold: Count over which rejection happens honor_whitelist: List of whitelists to honor ]] msys.dp_config.audit_series.invalid_recipients = { type = "cidr", interval = 900, buckets = 4, thresholds = { { check = true, key = "/32", startv = 0, endv = 3, threshold = 50 }, { check = true, key = "/24", startv = 0, endv = 3, threshold = 500 } }, options = { persist = true } }; --[[ Message rate limiting, to disable comment out the definition of messages audit_series type: cidr interval: Bucket size in seconds buckets: Number of intervals key: /mask length for the threshold (leading slash required) startv: Starting bucket (0 is the current bucket) endv: Ending bucket threshold: Count over which rejection happens honor_whitelist: List of whitelists to honor ]] msys.dp_config.audit_series.messages = { type = "cidr", interval = 900, buckets = 4, thresholds = { { check = true, key = "/32", startv = 0, endv = 3, threshold = 200, honor_whitelist = { "global" } }, { check = true, key = "/24", startv = 0, endv = 3, threshold = 2000, honor_whitelist = { "global" } } }, options = { persist = true } }; --[[ SPAM MAIL FROM rate limiting Note this is disabled by default as there is a potential for a sender to DoS the system with garbage sender addresses. type: string interval: Bucket size in seconds buckets: Number of intervals startv: Starting bucket (0 is the current bucket) endv: Ending bucket threshold: Count over which rejection happens honor_whitelist: List of whitelists to honor ]] --[[ msys.dp_config.audit_series.spam_mailfrom = { type = "string", interval = 900, buckets = 4, thresholds = { { check = false, startv = 0, endv = 3, threshold = 100, honor_whitelist = { "global" } } }, options = { persist = true } }; ]] --[[ Spam rate limiting, to disable comment out the definition of spam audit_series type: cidr interval: Bucket size in seconds buckets: Number of intervals key: /mask length for the threshold (leading slash required) startv: Starting bucket (0 is the current bucket) endv: Ending bucket threshold: Count over which rejection happens honor_whitelist: List of whitelists to honor ]] msys.dp_config.audit_series.spam = { type = "cidr", interval = 900, buckets = 4, thresholds = { { check = true, key = "/32", startv = 0, endv = 3, threshold = 50, honor_whitelist = { "global" } }, { check = true, key = "/24", startv = 0, endv = 3, threshold = 200, honor_whitelist = { "global" } } }, options = { persist = true } }; --[[ Virus rate limiting, to disable comment out the definition of virus audit_series type: cidr interval: Bucket size in seconds buckets: Number of intervals key: /mask length for the threshold (leading slash required) startv: Starting bucket (0 is the current bucket) endv: Ending bucket threshold: Count over which rejection happens honor_whitelist: List of whitelists to honor ]] msys.dp_config.audit_series.virus = { type = "cidr", interval = 900, buckets = 4, thresholds = { { check = true, key = "/32", startv = 0, endv = 3, threshold = 50, honor_whitelist = { "global" } }, { check = true, key = "/24", startv = 0, endv = 3, threshold = 200, honor_whitelist = { "global" } } }, options = { persist = true } }; --[[ VIRUS MAIL FROM rate limiting Note this is disabled by default as there is a potential for a sender to DoS the system with garbage sender addresses. type: string interval: Bucket size in seconds buckets: Number of intervals startv: Starting bucket (0 is the current bucket) endv: Ending bucket threshold: Count over which rejection happens honor_whitelist: List of whitelists to honor ]] --[[ msys.dp_config.audit_series.virus_mailfrom = { type = "string", interval = 900, buckets = 4, thresholds = { { check = false, startv = 0, endv = 3, threshold = 100, honor_whitelist = { "global" } } }, options = { persist = true } }; ]] --[[ Message size limits. Multiple can be defined, with different whitelist honoring settings. Size: In bytes (1024b), kilobytes (50k), megabytes (5m) The policy below applies a general limit of 20M, but allows members of the global whitelist to send messages up to 50M ]] msys.dp_config.message_size_limits = { { check = true, size = "20m", honor_whitelist = { "global" } }, { check = true, size = "50m", honor_whitelist = { } } }; --[[ For all of the content scanners, you may define a 'process_result' function to override all processing of the result. The function is defined like so: msys.dp_config.my_scanner = { ... ... process_result = function (msg, vctx, info) if info.result == "spam" then return vctx:pbp_action(555, "No soup for you"), true; end end, }; The function is passed three parameters: msg: The ec_message vctx: The validation context info: The information returned by the spam classifier. This will differ for each classifier, and is documented below. Return values. Must return two values. The first is whether to continue the validate_data phase, which is either msys.core.VALIDATE_CONT to continue or msys.core.VALIDATE_DONE to stop. This does not affect whether the default processing logic will be processed for the spam scanner in question, if you define a process_result function the default logic is never evaluated. The second is a boolean stating whether or not the system-wide 'spam' audit_series should be incremented. The disposition for each content scanner may either be 'discard' or 'reject'. ]] -- Un-comment to enable BEIK scanning -- process_result info is a table: -- { rc = rc, verdict = verdict } -- -- More information on these parameters can be found here: -- https://support.messagesystems.com/docs/web-ref/lua.ref.msys.symantec_beik.scan.php --[[ require("msys.symantec_beik"); msys.dp_config.beik = { scan = true, isspam_disposition = "reject", honor_whitelist = { "global" }, }; ]] -- Un-comment to enable Commtouch scanning -- process_result info is the return value from msys.commtouch.diagnose, -- documented here: https://support.messagesystems.com/docs/web-ref/lua.ref.msys.commtouch.diagnose.php --[[ require("msys.commtouch"); msys.dp_config.commtouch = { scan = true, spam_dispositions = { confirmed = "reject", bulk = "reject", -- suspect = "reject" }, virus_dispositions = { virus = "reject", high = "reject", -- medium = "reject" }, honor_whitelist = { "global" } }; ]] -- Un-comment to enable Cloudmark scanning -- process_result info is the return value from msys.cloudmark.score, -- documented here: https://support.messagesystems.com/docs/web-ref/lua.ref.msys.cloudmark.score.php --[[ require("msys.cloudmark"); msys.dp_config.cloudmark = { scan = true, score_threshold = 95, isspam_disposition = "reject", honor_whitelist = { "global" } }; ]] -- Uncomment to enable AV scanning. In order for AV scanning to work -- you must separately load the antivirus module in ecelerity.conf, and -- configure each engine you reference in the configuration stanza below. -- Valid engines are platform dependent and can be found in the -- Momentum documentation. -- -- Valid values for 'virus_disposition' are disinfect, reject or discard. -- disinfect will replace any infected MIME parts with a text string. -- -- These may also define a process_result function instead of virus_disposition: -- result == String from the engine giving details of the virus, if any -- Return msys.core.VALIDATE_CONT or msys.core.VALIDATE_DONE --[[ process_result = function (msg, vctx, result) return vctx:pbp_action(555, "Virus found"); end, ]] --[[ require("msys.av"); msys.dp_config.antivirus = { { scan = true, engine = "csapi", virus_disposition = "disinfect", honor_whitelist = { "global" } }, { scan = true, engine = "clamav", virus_disposition = "reject", honor_whitelist = { "global" } } }; ]] -- Keyword filter -- -- scan: true or false -- name: Name of the keyword filter, must be unique among keyword filters -- path: Absolute path of the file on disk -- charset: Character set of the file, currently we support: -- UTF-8 -- GBK -- ISO-8859-1 -- ISO-2022-JP -- Big5 -- disposition: reject or discard -- process_result: Takes msg, vctx and number of matches found in the -- subject and message together. Note that each MIME part -- is scanned individually, and the num_found value represents -- how many were found in the subject plus the MIME part -- being scanned. The subject header is scanned along with -- each MIME part. -- -- The file format is one keyword per line. You may search for multiple -- words in a pattern by separating the words with the '|' character --[[ process_result = function (msg, vctx, num_found) if num_found >= 2 then return vctx:pbp_action(554, "Keyword matches"); end end, ]] msys.dp_config.keyword_filter = { { scan = false, name = "keywords", path = "/opt/msys/ecelerity/etc/conf/default/keyword_filter.txt", charset = "UTF-8", disposition = "reject", honor_whitelist = { "global" }, } }; -- vim:ts=2:sw=2:et: -- $Revision: 2938 $
Was this page helpful?