Defending against denial of service attacks

From Messaging Server Technical Reference Wiki
Jump to: navigation, search

A denial of service attack is where an attacker tries (intentionally or inadvertently) to overwhelm your system by flooding you with e-mail.

The MTA is designed to continue operating even when impacted by an attempted denial of service attack. The design of the Dispatcher includes limits, which are configurable, on how many simultaneous inbound connections to accept, how many processes to generate to handle inbound connections, and how to aportion such inbound connections to those Worker Processes. Similarly, the Job Controller has various self-managing features; see the discussion of Job Controller operation under stress. However, sites subject to malicious attacks, or sites that communicate with particularly ill-behaved correspondents, may want to take further explicit steps for protection.

In some cases, adding a simple static mapping entry to unconditionally reject messages from the problem address or site is a sufficient defense, particularly if you know ahead of time (or can quickly detect) that the attack is occurring; see Access mapping tables and Client access to Message Store servers. In other cases, however, you may either wish to automate dynamic detection of message volume upswings sufficient to be considered an attack. Or you may not wish to reject all messages from the problem address or site and instead wish merely to "turn down the volume", i.e., slow down the flow to a level more easily managed by your users or system. For instance, you may be under a practical or legal mandate to accept certain messages, or good messages may be mixed in with the bad message flow; in such a case turning down the volume to a manageable level allows the good messages a chance to get into your system while preventing the bad messages from overloading your resources.

The PORT_ACCESS and SEND_ACCESS mapping tables ---as well as related mapping tables discussed in Access mapping tables---can be used in more sophisticated ways than simple unconditional entries to achieve such goals, and can indeed be hooked into dynamic, heuristic routines to decide "Yea" or "Nay" on accepting messages, such as MeterMaid, or dns_verify routines, or calling out to PureMessage IP Blocker via the pmxbl routine, or calling out to a third-party anti-spam/anti-virus package that supports so-called "early verdicts" via the mm_check_reputation routine, or callouts to site-provided routines.

First, on the most simple level, the PORT_ACCESS, SEND_ACCESS or related mapping tables can take a random argument, effectively having the MTA "flip a coin" each time it needs to decide whether to accept a connection or message, respectively, or in the case of SEND_ACCESS and related mapping tables whether to sideline a message; see the $? substitution (under Mapping tables) for details.

For more sophisticated needs, the PORT_ACCESS, SEND_ACCESS, or related mapping tables can call out to facilities such as MeterMaid, or the dns_verify routines, or call out to site-supplied shareable image routines; see Site-supplied routine substitutions (under Mapping tables) for details. Such routines can, if you wish, use PMDF API calls to access MTA counters information; this can allow for heuristic decisions based on recent message load, comparing MTA counters levels at one sampled time with MTA counters levels when checked a little later; e.g., "lots of messages came in to the tcp_local channel in the last few minutes, so let us reject additional connection attempts for the moment" or whatever decision basis you decide to implement.

As of Messaging Server 7.0u2, use of a LOG_ACTION mapping table calling out to MeterMaid may be an even better approach for making dynamic decisions.

If you have a site approach for monitoring syslog notices, note that the log_messages_syslog and log_connections_syslog MTA options can be enabled to cause message and connection entries, respectively, to also be sent to syslog.

As of the 8.0 release, the Sieve "memcache" operator and Sieve "metermaid" operator are available to query and update memcache or MeterMaid, respectively, from within a Sieve script. Sieve script powerful logic can thereby allow for especially flexible or "targetted" updates of memcache or MeterMaid tables, if desired, when such tables are to be queried for connection blocking or throttling type purposes.

The heuristics for making dynamic decisions about accepting or rejecting messages tend to be very site specific, and involve a variety of critical issues. Note also that sites may wish to keep the details of their own heuristic algorithms secure. Sites interested in implementing their own denial of service prevention techniques may wish to obtain specialized consulting assistance.

Particularly when implementing dynamic rejection mechanisms, the following TCP/IP-channel-specific options may be of interest:

  • ALLOW_TRANSACTIONS_PER_SESSION, ALLOW_RECIPIENTS_PER_TRANSACTION, and TRANSACTION_LIMIT_RCPT_TO. The ALLOW_TRANSACTIONS_PER_SESSION option can be used to limit the number of messages accepted during a particular connection. After refusing a number of connection attempts from a particular site, once you do let them connect, they are liable to have a backlog of messages for your site which they will try to deliver during that connection. If you are attempting to "slow down" how much mail you accept from that site, you likely will want to use this option to say, in effect, "enough for now" after some point in the connection. Similarly, the ALLOW_RECIPIENTS_PER_TRANSACTION option can be used to limit the number of recipients allowed for a particular message submission (additional recipients during that submission attempt being rejected with a temporary error, so that they may be tried again later); this can be useful in slowing down the number of recipients handed over during a single message transaction. Thus both these options may be useful protecting against a denial of service attack in the form of a rapid flood of messages blanketing large numbers of your users. The TRANSACTION_LIMIT_RCPT_TO option modifies the effect of ALLOW_RECIPIENTS_PER_TRANSACTION, in that it controls at which SMTP command (RCPT TO: or MAIL FROM:) the "extra" recipient addresses are rejected.
  • REJECT_RECIPIENTS_PER_TRANSACTION. The REJECT_RECIPIENTS_PER_TRANSACTION option can be considered a more aggressive version of ALLOW_RECIPIENTS_PER_TRANSACTION; whereas ALLOW_RECIPIENTS_PER_TRANSACTION allows up to the specified number of recipients to be accepted (while additional recipients get a temporary rejection) thereby merely "slowing down" the incoming messages, REJECT_RECIPIENTS_PER_TRANSACTION causes the MTA to issue a temporary rejection (after the DATA command) for all recipients of a message if too many recipients are attempted. That is, with REJECT_RECIPIENTS_PER_TRANSACTION, a message will not be allowed in at all until the sending side decreases the number of recipients it is trying to submit during a single transaction. So for a sufficiently flexible sender, REJECT_RECIPIENTS_PER_TRANSACTION is simply a somewhat more forceful way of slowing down the message flow. But for a sender that is not so flexible about retrying sending a message with fewer recipients per transaction, REJECT_RECIPENTS_PER_TRANSACTION may result in the message not getting through at all.
  • ALLOW_REJECTIONS_BEFORE_DEFERRAL. The ALLOW_REJECTIONS_BEFORE_DEFERRAL option causes the MTA, after the specified number of recipients have failed (been determined to be invalid addresses), to reject (with a temporary error) all further recipients in that transaction, good or bad. That is, this option penalizes message submissions that include a lot of bad recipient addresses (on the theory that such message submissions may be cases of dictionary-based or automatically-generated lists of recipients).
  • SIZE_DELAY_THRESHHOLDS, SIZE_DELAY_AMOUNTS, RECIPIENT_DELAY_THRESHHOLDS, RECIPIENT_DELAY_AMOUNTS, TRANSACTION_DELAY_THRESHHOLDS, TRANSACTION_DELAY_AMOUNTS. These options are specifically available to progressively "slow down" the acceptance of incoming messages once specified threshholds have been exceeded.

The above items focus on MTA features. However, many sites will also have a spam/virus filter package that may be capable of maintaining heuristic data concerning connections; if such a spam/virus filter package has useful such abilities and is configured to report or make available relevant such data to the MTA, as for instance via a mm_check_reputation routine call from the PORT_ACCESS mapping table, that can be yet another useful tool in the arsenal for defending against denial of service attacks.

See also: