# This file allows you to declare traffic shaping parameters by domain. # Each domain has a section as shown below. The domain name must be enclosed # in square-brackets and quotes to be correctly recognized. # # The default for a domain is to use MX rollup; when this file is loaded, # the MX is resolved for the domain and all domains that rollup to that # same set of MX records will share those settings. # It is an error to list multiple different domains that rollup to the same # MX, as that would result in an ambiguous configuration. The error will be # noted when the configuration is loaded. # # If you do not wish to use mx rollup for a domain, you can set # `mx_rollup = false` as one of the values in the domain section, as shown # in the `example.com` example in this file. # # If a domain is a NULL MX (such as `example.com`), it cannot be used with # mx_rollup, because there are no MX's to roll up into. # # You may compose multiple shaping files over each other; in that case you # have the option of specifying `replace_base = true` in a domain in a # later file. That will have the effect of ignoring all previous values # for that domain. # # The acceptable set of values in a domain section are valid parameters to # kumo.make_egress_path. # # # Community members are invited to submit their rules for general use by adding them # to the community/shaping.toml file and submitting a pull request. # DO NOT EDIT THIS FILE, IT WILL BE OVERWRITTEN WHEN YOU UPDATE YOUR INSTALLATION # INSTEAD CREATE YOUR OWN FILE AND ADD IT TO THE LIST OF FILES LOADED IN YOUR # INIT POLICY. IN THIS EXAMPLE YOUR OWN FILE IS AT /opt/kumomta/etc/policy/custom-shaping.toml # local shaping = require 'policy-extras.shaping' # local shaper = shaping:setup_with_automation { # publish = { 'http://127.0.0.1:8008', }, # subscribe = { 'http://127.0.0.1:8008', }, # extra_files = { # '/opt/kumomta/share/policy-extras/shaping.toml', # '/opt/kumomta/share/community/shaping.toml', # '/opt/kumomta/etc/policy/shaping_custom.toml', # }, # } # kumo.on('init', function() # -- Configure publishing of TSA logs to automation daemon # shaper.setup_publish() # end) -- END OF THE INIT EVENT # kumo.on('get_egress_path_config', shaper.get_egress_path_config) ["default"] connection_limit = 10 max_connection_rate = "100/min" max_deliveries_per_connection = 100 max_message_rate = "100/s" idle_timeout = "60s" data_timeout = "30s" data_dot_timeout = "60s" enable_tls = "Opportunistic" consecutive_connection_failures_before_delay = 100 remember_broken_tls = "3 days" ["generator.kumomta.internal"] mx_rollup = false ["deferred_smtp_inject.kumomta.internal"] mx_rollup = false [["default".automation]] # We use ''' for strings in the regex section because it forces a string literal that requires no extra # delimiters while also allowing for literal ' characters in the regex strings. regex=[ '''Messages from \d+\.\d+\.\d+\.\d+ temporarily deferred''', '''All messages from \d+\.\d+\.\d+\.\d+ will be permanently deferred''', '''has been temporarily rate limited due to IP reputation''', '''Unfortunately, messages from \d+\.\d+\.\d+\.\d+ weren.t sent''', '''Server busy\. Please try again later from''', ] action = [ {SetConfig={name="max_message_rate", value="1/minute"}}, {SetConfig={name="connection_limit", value=1}}, ] duration = "90m" # https://support.google.com/mail/answer/81126 # NOTE: While it's commonly understood that Gmail and Google Workspace use different filtering # Criteria, at time of writing (2024-09-03) their MX hostnames all resolve to common IPs, # so Google Workspace and Gmail are being combined for the purposes of traffic shaping and queueing. [provider."google"] match=[ {MXSuffix=".google.com"}, {MXSuffix=".googlemail.com"}, ] # NOTE: Google will tempfail and rate limit senders who attempt to inject messages without TLS, so for # Google domains enable_tls should be set to required. enable_tls = 'Required' max_deliveries_per_connection = 50 provider_connection_limit = 5 consecutive_connection_failures_before_delay = 5 ### THIS AUTOMATION IS COMMENTED OUT BECAUSE IT CAN SUPEND ENTIRE TENANTS AND IS ### PROVIDED AS AN EXAMPLE TO USE IN YOUR OWN CUSTOM SHAPING FILE. # [["gmail.com".automation]] # regex = "This message does not have authentication information" # action = "SuspendTenant" # duration = "3 hours" # PROVIDED BY YAHOO! DIRECTLY # https://senders.yahooinc.com/best-practices [provider."yahoo"] match=[{MXSuffix=".yahoodns.net"}] max_deliveries_per_connection = 20 [[provider."yahoo".automation]] regex = "\\[TS?S04\\]" action = "Suspend" duration = "2 hours" # Microsoft has different MX sets for Consumer and O365, and a new set for DANE. # This requires separate provider definitions as they are separate edge server groups. # https://techcommunity.microsoft.com/t5/exchange-team-blog/implementing-inbound-smtp-dane-with-dnssec-for-exchange-online/ba-p/3939694 # https://sendersupport.olc.protection.outlook.com/pm/Policies [provider."outlook"] match=[{MXSuffix=".olc.protection.outlook.com"}] max_deliveries_per_connection = 50 provider_connection_limit = 5 [provider."office365"] match=[{MXSuffix=".mail.protection.outlook.com"}] max_deliveries_per_connection = 50 provider_connection_limit = 5 [provider."office365-dane"] match=[{MXSuffix=".mx.microsoft"}] # Ideally we'd enable dane here, but most sites are not # configured to work correctly with DNSSEC or DANE out # of the box, so we leave it disabled. # enable_dane = true max_deliveries_per_connection = 50 provider_connection_limit = 5 # https://support.apple.com/en-us/102322 [provider."apple"] match=[{MXSuffix=".icloud.com"}] provider_connection_limit = 10 max_deliveries_per_connection = 5 # PROVIDED DIRECTLY BY COMCAST # https://spa.xfinity.com/help/postmaster # https://spa.xfinity.com/help/postmaster?faq=comcast-mail-errors ["comcast.net"] connection_limit = 25 max_deliveries_per_connection = 1000 enable_tls = "Required" idle_timeout = "30s" consecutive_connection_failures_before_delay = 24 [["comcast.net".automation]] regex = "RL0000" # sets max_connection_rate="100/s" action = {SetConfig={name="max_connection_rate", value="10000/h"}} # if we see 2 or more matches in an hour. Unlike throttles, this # doesn't divide down to per-second rates. trigger = {Threshold="2/hr"} # The config override will last for 2 hours duration = "2 hours" # Domain Throttled - https://postmaster.comcast.net/smtp-error-codes.php#RL000010 [["comcast.net".automation]] regex = "^(?!.*KumoMTA internal).*RL000010" trigger = "Immediate" action = "SuspendTenant" duration = "5 minutes" # PROVIDED DIRECTLY BY MIMECAST # NOTE: Each sitename is a separate region with separate MTAs, so we do not use provider_connection_limit # For Mimecast because the connection limit should be enforced for each sitename separately. # https://community.mimecast.com/s/article/email-security-cloud-gateway-mimecast-gateway # https://community.mimecast.com/s/article/email-security-cloud-gateway-mimecast-smtp-error-codes [provider."mimecast"] match=[{MXSuffix=".mimecast.com"},{MXSuffix=".mimecast.co.za"},{MXSuffix=".mimecast-offshore.com"}] max_deliveries_per_connection = 100 connection_limit = 10 # PROVIDED DIRECTLY BY MAIL.COM ["mail.com"] max_deliveries_per_connection = 100 # https://www.postmastery.com/orange-postmaster-smtp-error-codes-ofr/ # https://messagerie.orange.fr/postmaster.html [provider."orange"] match=[{MXSuffix=".orange.fr"}] provider_connection_limit = 2 max_deliveries_per_connection = 100 enable_tls = "Required" # PROVIDED DIRECTLY FROM MAILGUN FOR SENDERS WHO SMARTHOST VIA MAILGUN ["smtp.mailgun.com"] connection_limit = 7000 max_deliveries_per_connection = 3 ############################################################# # example.com is used by our integration tests, while also demonstrating # a couple of example options. No one should be sending mail to example.com: # it has a NULL MX record and doesn't accept mail. ["example.com"] mx_rollup = false max_deliveries_per_connection = 100 connection_limit = 3 # If you want to declare local overrides with settings for your locally defined # egress sources, you can syntax like the following; the section is named: # [DOMAIN.sources.SOURCE] where both the DOMAIN and the SOURCE need to be quoted # with double quotes. # If you do want to do this, don't edit this file at /opt/kumomta/share/policy-extras/shaping.toml, # but instead create your own copy at `/opt/kumomta/etc/shaping.toml` and provide # your overrides there. ["example.com".sources."my source name"] connection_limit = 5 # Increase constraints when sending events to the TSA daemon. # If you deploy TSA daemon to other hosts, you need to define an entry # like this for each of them! ['http://127.0.0.1:8008.tsa.kumomta'] # This is not a regular email domain, so do not try to resolve it # as an MX record mx_rollup = false max_deliveries_per_connection = 8192 # No need to coordinate with other MTAs on a shared limit connection_limit = "local:5" # Allow a healthy amount in the ready queue in case things get # busy max_ready = 10000 system_shutdown_timeout = "30s"