Mail Routing and Traffic Shaping
- Table of Contents
-
Traffic Shaping and Delivery Settings
- Does the MTA support rate limiting delivery speed?
- Does the MTA support limiting concurrent connections?
- What configuration options are available for connection settings?
- Can settings be applied globally, per outbound IP, per receiving domain, per MX rollup?
- Can settings be applied across a group of domains, regardless of whether they’re related?
- How are MX rollups configured?
- Is it possible to specify HELO/EHLO FQDN on a per IP basis?
- Is there the ability to rename queues without the queue being deleted?
-
Traffic shaping automations and delivery overrides
- Can the MTA temporarily override IP-based throttles due to the percentage of temp failures or permanent failures?
- Can the MTA temporarily override IP-based throttles due to a regex match of a SMTP response message?
- Can the MTA dynamically throttle back delivery of specific RFC5321.MailFrom or RFC5322.From domains?
- Can the MTA override a delivery result in response to messages from mailbox providers?
- Mail Routing
- Blackhole routing
Traffic Shaping and Delivery Settings
Does the MTA support rate limiting delivery speed?
Yes. The max_delivery_rate directive is used to limit the rate of delivery attempts to a group of domains and/or MX rollups from a single IP address.
When configured in the configuration file, this looks like:
ip_address * {
domain * {
max_delivery_rate 500/hr
}
}
ip_address smtp1 {
domain yahoo.com,mx:*.yahoodns.net {
max_delivery_rate 5000/hr
}
domain * {
max_delivery_rate 2000/hr
}
}
When using the API, the max delivery rate is accessed using the IP Addresses API
and the Throttling Templates API as the max_messages_per_hour field.
You can configure the speed in whatever unit you want. For example, these are all identical configurations:
max_delivery_rate 2/smax_delivery_rate 120/minmax_delivery_rate 7200/hr
The reason that these are all identical configurations is because rates are always “smoothly” applied; GreenArrow Engine strives for a constant speed of message delivery across a given time slice. So, for example, 7200/hr will never mean “7200 sent in the first five minutes, then no sending for fifty-five minutes”. Instead, it will mean that Engine will attempt to send two messages every second for the entire hour.
That said, there is a small sliding window so that if the delivery rate was slower than the configured speed for a short period of time, then the delivery rate will be allowed to exceed the configured speed briefly so that the average speed works out to the configured speed.
For more information, see the documentation on Throttling.
Does the MTA support limiting concurrent connections?
Yes. The max_concurrent_connections directive is used to limit the maximum concurrent connections that may be opened to a group of domains and/or MX rollups from a single IP address.
When configured in the configuration file, this looks like:
ip_address * {
domain * {
max_concurrent_connections 1
}
}
ip_address smtp1 {
domain yahoo.com,mx:*.yahoodns.net {
max_concurrent_connections 10
}
domain * {
max_concurrent_connections 5
}
}
When using the API, the max concurrent connections is accessed using the IP Addresses API
and the Throttling Templates API as the max_concurrent_connections field.
For more information, see the documentation on Throttling.
What configuration options are available for connection settings?
In addition to the max delivery speed and max concurrent connections already described, GreenArrow offers a number of different options for configuring connection settings, including:
- Outbound TLS, offering both opportunistic TLS and required TLS
- Several options for Connection Reuse
- Maximum delivery speed, configured with the max_delivery_rate directive.
Can settings be applied globally, per outbound IP, per receiving domain, per MX rollup?
Yes, to all of these.
These directives exist inside of a domain context in the configuration
file. The domain context can accept MX wildcards, specific domains, wildcard domains, or an “*”.
The domain context exists inside of the ip_address context and
the ip_address context can accept a list of specific IP addresses or an “*” for all IP addresses.
Different settings are layered together as described here.
MX rollup, domain wildcarding, and the special **super** virtual IP address are described here.
Can settings be applied across a group of domains, regardless of whether they’re related?
Yes, just provide a comma-separated list of the domains and MX wildcards in a domain stanza within an ip_address block.
For example:
ip_address * {
domain yahoo.com, gmail.com, mx:*.outlook.com {
starttls_use use
}
domain yahoo.com {
max_concurrent_connections 2
}
domain gmail.com {
max_concurrent_connections 4
}
}
How are MX rollups configured?
Configurable, using a MX matching rule in a domain configuration stanza.
For example:
ip_address * {
domain mx:*.outlook.com {
max_concurrent_connections 10
max_delivery_rate 2000/hr
}
}
The matching rules are described in the documentation of the domain context.
Is it possible to specify HELO/EHLO FQDN on a per IP basis?
The answer is “yes” for both outgoing and incoming email.
For outgoing SMTP, this is part of the configuration of the IP Address record, and can be done:
- In the hostname portion of the smtp_source configuration directive
- In the smtp_source_hostname configuration directive
- Or in the IP Address API, in the
hostnamefield:
For incoming SMTP, instructions for configuring the SMTP greeting are here
Is there the ability to rename queues without the queue being deleted?
Yes. New throttling groupings are dynamically applied when the configuration is reloaded, without queues being deleted or needing to do an explicit rename.
Traffic shaping automations and delivery overrides
Can the MTA temporarily override IP-based throttles due to the percentage of temp failures or permanent failures?
This is defined in the Dynamic Delivery documentation.
It can be configured in the UI/API with the Throttle Programs API and the throttle_program
field in the IP Addresses API and the Throttling Templates API.
It can be configured in the configuration file with the following directives:
- throttle_program
- backoff_max_concurrent_connections
- backoff_max_messages_per_hour
- return_after
- trigger_failure_rate
- trigger_deferral_rate
- trigger_required_attempts
For example:
throttle_program yahoo_basic {
trigger_failure_rate 20%
trigger_deferral_rate 90%
trigger_required_attempts 10
backoff_max_concurrent_connections 1
backoff_max_messages_per_hour 200
return_after 1h
}
ip_address * {
domain yahoo.com,mx:*.yahoodns.net {
throttle_program yahoo_basic
}
}
Can the MTA temporarily override IP-based throttles due to a regex match of a SMTP response message?
This can be done using the smtp_match_begin_backoff_mode directive.
This can also be done using the backoff=on parameter in the smtp_pattern and smtp_pattern_list directives.
For example:
ip_address * {
domain yahoo.com,mx:*.yahoodns.net {
smtp_match_begin_backoff_mode /TSS02/ case_insensitive=yes duration=30min maxconn=1 msgperhour=20
smtp_match_begin_backoff_mode /TSS03/ case_insensitive=yes duration=90min maxconn=1 msgperhour=1
}
}
And also:
smtp_pattern_list yahoo_patterns {
smtp_pattern /TSS02/ backoff=on backoff_duration=30min backoff_maxconn=1 backoff_msgperhour=20
smtp_pattern /TSS03/ backoff=on backoff_duration=90min backoff_maxconn=1 backoff_msgperhour=1
smtp_pattern /TSS09/ backoff=on backoff_duration=4h backoff_maxconn=1 backoff_msgperhour=1
}
ip_address * {
domain yahoo.com, mx:*.yahoodns.net {
smtp_pattern yahoo_patterns
}
}
Can the MTA dynamically throttle back delivery of specific RFC5321.MailFrom or RFC5322.From domains?
Yes, you can temporarily pause or reduce sending to a specific mailbox provider for a RFC5321.MailFrom or RFC5322.From domain across all IP addresses based on a regex match of a SMTP response.
This can serve to prioritize delivery for RFC5321.MailFrom or RFC5322.From domains that are not being throttled at mailbox providers.
Often a short pause time is used such as a few seconds, and this will automatically find the rate that the mailbox providers are willing to accept email from the RFC5321.MailFrom or RFC5322.From domain, based on how frequently a domain pause triggers after a previous pause ends.
This is documented in the Pausing Domains section of the documentation.
This is configured with the smtp_match_pause_domain directive or with the pause parameter of the smtp_pattern directive.
For example:
ip_address * {
domain yahoo.com,mx:*.yahoodns.net {
smtp_match_pause_domain /domain sending too fast/ type=rfc5322_from_domain duration=15s
}
}
And also:
smtp_pattern_list yahoo_patterns {
smtp_pattern /domain sending too fast/ pause=rfc5322_from_domain pause_duration=15s
}
ip_address * {
domain yahoo.com, mx:*.yahoodns.net {
smtp_pattern yahoo_patterns
}
}
Can the MTA override a delivery result in response to messages from mailbox providers?
Yes, you can override the result of the delivery and cause it to be considered a “success”, “perm_failure”, or “temp_failure” regardless of the SMTP status code. This is helpful if you don’t want to retry a particular temporary error condition. You can override the result to a “success” to silently remove the messages from the queue or override to a “perm_failure” to cause the email to bounce.
This is configured with the override_smtp_result directive or with the result parameter of the smtp_pattern directive.
For example:
ip_address * {
domain yahoo.com,mx:*.yahoodns.net {
override_smtp_result /TSS04/ perm_failure
}
}
And also:
smtp_pattern_list yahoo_patterns {
smtp_pattern /TSS04/ result=perm_failure
}
ip_address * {
domain yahoo.com, mx:*.yahoodns.net {
smtp_pattern yahoo_patterns
}
}
Mail Routing
Can we specify which IP (or pool of IPs) outbound traffic will use?
Yes. GreenArrow is very flexible here.
In GreenArrow, any method that can be used to deliver an email is called a VirtualMTA. IP Addresses are VirtualMTAs, and IP Pools defined with Routing Rules are also VirtualMTAs. Each email is assigned a VirtualMTA value at time of injection. This becomes part of the internal metadata of the email. By setting the VirtualMTA of an email or of a delivery attempt, you assign it to an IP or an IP pool at that time.
The VirtualMTA is set for an email message by any one of the following methods:
- The default VirtualMTA value for a source IP address.
- Regex matching based on email headers, RFC5321.MailFrom, RFC5322.From, ClickTrackingID, or SendID (as configured by the source IP address)
- The VirtualMTA value for the Mail Class that this email belongs to.
- The
X-GreenArrow-MtaIDheader - The
X-Virtual-MTAheader (if the process_x_virtual_mta_header configuration directive is enabled)
Can we pool IP addresses together in groups?
GreenArrow’s email routing is very flexible. You can define Routing Rules in the Engine UI or in the configuration file to manage outbound traffic flow to meet your needs. IP Pools are defined by creating a Routing Rule that splits the email between multiple IP addresses. Let’s look at some examples of Routing Rules defined in a configuration file.
In the first example, email for the VirtualMTA “customer_a” for Yahoo domains will be sent through “ip_address_a” and all other domains will be sent through “ip_address_b”:
routing_rule customer_a {
routing_rule_domain yahoo.com, mx:*.yahoodns.net {
routing_rule_destination ip_address_a
}
routing_rule_domain * {
routing_rule_destination ip_address_b
}
}
Meanwhile, in this example, email for the VirtualMTA “pool_a” will be split between “ip_address_a”, “ip_address_b”, and “ip_address_c” with the given ratios (subject to the delivery throttling settings for each IP and traffic shaping rules that take effect):
routing_rule pool_a {
routing_rule_domain * {
routing_rule_destination ip_address_a 50%
routing_rule_destination ip_address_b 25%
routing_rule_destination ip_address_c 25%
}
}
Last, randomization and domain routing can also be combined in a single Routing Rule. Here is an example Routing Rule where email for “customer_a” destined to Yahoo domains will be evenly split between “ip_address_a” and “ip_address_b” (subject to delivery throttling and traffic shaping rules), and email to all other domains will be sent through “ip_address_c”:
routing_rule customer_a {
routing_rule_domain yahoo.com, mx:*.yahoodns.net {
routing_rule_destination ip_address_a
routing_rule_destination ip_address_b
}
routing_rule_domain * {
routing_rule_destination ip_address_c
}
}
A Routing Rule can also direct email into another Routing Rule as a destination, providing a lot of power and flexibility. Some GreenArrow installations define a Routing Rule for every one of their customers (which directs into the IP pool or IP addresses that the customer is using) and a Routing Rule for every IP address pool.
The above just scratches the surface of the capabilities of GreenArrow with regard to IP Pools and Routing Rules. Other options available for configuring Routing Rules include, but are not limited to:
- Domain matching in Routing Rules with the domain directive
- Multiple smtp_source directives in one
ip_addressblock, which implicitly creates configuration for multiple IP addresses and a Routing Rule to split traffic between them. - The redirect_to_virtual_mta directive, which can be used to redirect email from a particular domain of a particular IP to another VirtualMTA.
All of this configuration can be updated without restarting the MTA or pausing delivery of email messages.
Every time a delivery of an email message is attempted, these rules are dynamically re-evaluated, so there is no need to re-queue email messages to another IP address.
Blackhole routing
Is it possible to not deliver traffic sent to configured domains and/or MXs?
Yes.
You can prevent delivery to a recipient domain or an MX wildcard using the delivery_override directive
inside of the **super** special IP address that has higher matching precedence, which is documented in the matching precedence order in the
domain directive’s documentation.
For example:
ip_address **super** {
domain mx:badmx.example.com {
delivery_override discard "Message discarded (1)"
}
domain example.com {
delivery_override discard "Message discarded (2)"
}
}
If there’s no MX record in DNS for receiving domain, is it possible to configure the mail to bounce?
This is configurable for outgoing SMTP, using the bounce_recipients_with_no_mx directive.
This configuration is not available for incoming email.
